Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win32 - file test operators don't work for //?/UNC/server/file filenames #9025

Closed
p5pRT opened this issue Sep 10, 2007 · 5 comments
Closed
Labels
distro-mswin32 type-core Win32 This is a meta-ticket to tag issues in the perl core which need attention on Win32. See #11925

Comments

@p5pRT
Copy link

p5pRT commented Sep 10, 2007

Migrated from rt.perl.org#45331 (status was 'open')

Searchable as RT45331$

@p5pRT
Copy link
Author

p5pRT commented Sep 10, 2007

From adavies@ptc.com

Created by adavies@ptc.com

On win32 you can use UNC pathanmes of the form​:

\\?\UNC\server\folder\filename

Perl can C<open> these files ok, but C<-f>, C<-e> etc.
incorrectly return false for these filenames.
However, they do work for directory names in this format.

The code in question is in win32/win32.c's win32_stat()​:

# %<

#if defined(WIN64) || defined(USE_LARGE_FILES)
  res = _stati64(path, sbuf);
#else
  res = stat(path, sbuf);
#endif
  sbuf->st_nlink = nlink;

if (res < 0) {
  /* CRT is buggy on sharenames, so make sure it really isn't.
  * XXX using GetFileAttributesEx() will enable us to set
  * sbuf->st_*time (but note that's not available on the
  * Windows of 1995) */
  DWORD r = GetFileAttributesA(path);
  if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
  /* sbuf may still contain old garbage since stat() failed */
  Zero(sbuf, 1, Stat_t);
  sbuf->st_mode = S_IFDIR | S_IREAD;
  errno = 0;
  if (!(r & FILE_ATTRIBUTE_READONLY))
  sbuf->st_mode |= S_IWRITE | S_IEXEC;
  return 0;
  }

# >%

Note that GetFileAttributesA() does succeed for "\\?\UNC\server\file"
format filesnames... but the result does not have the
"FILE_ATTRIBUTE_DIRECTORY" bit set.

Is there any reason why this isn't coded as (untested)​:

  DWORD r = GetFileAttributesA(path);
  if (r != 0xffffffff) {
  /* sbuf may still contain old garbage since stat() failed */
  Zero(sbuf, 1, Stat_t);
  sbuf->st_mode = S_IREAD;
  if (r & FILE_ATTRIBUTE_DIRECTORY)
  sbuf->st_mode |= S_IFDIR;
  errno = 0;
  if (!(r & FILE_ATTRIBUTE_READONLY))
  sbuf->st_mode |= S_IWRITE | S_IEXEC;
  return 0;
  }

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.7:

Configured by adavies at Thu Aug 11 14:02:10 2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
  Platform:
    osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cl', ccflags ='-nologo -Gf -W3 -MD -DNDEBUG -O1 -DWIN32
-D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT  -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX',
    optimize='-MD -DNDEBUG -O1',
    cppflags='-DWIN32'
    ccversion='12.00.8804', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -release
-libpath:"c:\perl3\lib\CORE"  -machine:x86'
    libpth=\lib
    libs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib
odbc32.lib odbccp32.lib msvcrt.lib
    perllibs=  oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib
    gnulibc_version='undef'
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release
-libpath:"c:\perl3\lib\CORE"  -machine:x86'

Locally applied patches:
    


@INC for perl v5.8.7:
    C:/perl3/lib
    C:/perl3/site/lib
    .


Environment for perl v5.8.7:
    HOME=C:\alex
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
 
PATH=C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\perl3\bin;D:\a
lex\bin;C:\cygwin\bin;C:\Program Files\Perforce;C:\Program
Files\Microsoft Visual Studio\VC98\Bin;C:\Program Files\Microsoft Visual
Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual
Studio\VC98\MFC\Lib;
    PERL_BADLANG (unset)
    SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Aug 13, 2012

From @jkeenan

On Mon Sep 10 09​:41​:21 2007, adavies@​ptc.com wrote​:

This is a bug report for perl from adavies@​ptc.com,
generated with the help of perlbug 1.35 running under perl v5.8.7.

-----------------------------------------------------------------
[Please enter your report here]

On win32 you can use UNC pathanmes of the form​:

\\?\UNC\server\folder\filename

Perl can C<open> these files ok, but C<-f>, C<-e> etc.
incorrectly return false for these filenames.
However, they do work for directory names in this format.

The code in question is in win32/win32.c's win32_stat()​:

# %<

#if defined(WIN64) || defined(USE_LARGE_FILES)
res = _stati64(path, sbuf);
#else
res = stat(path, sbuf);
#endif
sbuf->st_nlink = nlink;

if (res < 0) {
/* CRT is buggy on sharenames, so make sure it really isn't.
* XXX using GetFileAttributesEx() will enable us to set
* sbuf->st_*time (but note that's not available on the
* Windows of 1995) */
DWORD r = GetFileAttributesA(path);
if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
/* sbuf may still contain old garbage since stat() failed */
Zero(sbuf, 1, Stat_t);
sbuf->st_mode = S_IFDIR | S_IREAD;
errno = 0;
if (!(r & FILE_ATTRIBUTE_READONLY))
sbuf->st_mode |= S_IWRITE | S_IEXEC;
return 0;
}

# >%

Note that GetFileAttributesA() does succeed for "\\?\UNC\server\file"
format filesnames... but the result does not have the
"FILE_ATTRIBUTE_DIRECTORY" bit set.

Is there any reason why this isn't coded as (untested)​:

DWORD r = GetFileAttributesA\(path\);
if \(r \!= 0xffffffff\) \{
    /\* sbuf may still contain old garbage since stat\(\) failed \*/
    Zero\(sbuf\, 1\, Stat\_t\);
    sbuf\->st\_mode = S\_IREAD;
    if \(r & FILE\_ATTRIBUTE\_DIRECTORY\)
    sbuf\->st\_mode |= S\_IFDIR;
    errno = 0;
    if \(\!\(r & FILE\_ATTRIBUTE\_READONLY\)\)
    sbuf\->st\_mode |= S\_IWRITE | S\_IEXEC;
    return 0;
\}

Can anyone on Win32 confirm whether these problems persist in a
supported version of Perl (5.14 or 5.16)?

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Aug 13, 2012

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 14, 2012

From @tonycoz

On Mon, Aug 13, 2012 at 04​:10​:26PM -0700, James E Keenan via RT wrote​:

On Mon Sep 10 09​:41​:21 2007, adavies@​ptc.com wrote​:

This is a bug report for perl from adavies@​ptc.com,
generated with the help of perlbug 1.35 running under perl v5.8.7.

-----------------------------------------------------------------
[Please enter your report here]

On win32 you can use UNC pathanmes of the form​:

\\?\UNC\server\folder\filename

Perl can C<open> these files ok, but C<-f>, C<-e> etc.
incorrectly return false for these filenames.
However, they do work for directory names in this format.

Can anyone on Win32 confirm whether these problems persist in a
supported version of Perl (5.14 or 5.16)?

This is still a problem in blead.

C​:\Users\tony\dev\perl\git\perl>perl -le "print qq($_​: ), join ',', -d $_, -f $_
, -e $_ for @​ARGV" \\?\UNC\mars\tony\test.png \\?\UNC\mars\tony\library \\mars\t
ony\test.png \\mars\tony\library
\\?\UNC\mars\tony\test.png​: ,,
\\?\UNC\mars\tony\library​: 1,,1
\\mars\tony\test.png​: ,1,1
\\mars\tony\library​: 1,,1

Tony

@toddr toddr added the Win32 This is a meta-ticket to tag issues in the perl core which need attention on Win32. See #11925 label Feb 5, 2020
genio added a commit to genio/perl5 that referenced this issue Oct 15, 2020
As discussed on the mailing list here:
https://www.nntp.perl.org/group/perl.perl5.porters/2020/10/msg258453.html

This just removes the declaration that we support the very old versions
of Windows that have long since been EOLed.

For reference of problems related to maintaining the EOLed versions:
Perl#4145
Perl#6080
Perl#7410
Perl#8502
Perl#9025
Perl#12431
Perl#14687
@tonycoz
Copy link
Contributor

tonycoz commented Dec 3, 2020

Fixed in blead, by e935ef3:

C:\Users\Tony\dev\perl\git\perl\win32>..\perl -le "print qq($_: ), join ',', -d $_, -f $_, -e $_ for @ARGV" \\?\UNC\mars\tony\test.png \\?\UNC\mars\tony\library \\mars\tony\test.png \\mars\tony\library
\\?\UNC\mars\tony\test.png: ,1,1
\\?\UNC\mars\tony\library: 1,,1
\\mars\tony\test.png: ,1,1
\\mars\tony\library: 1,,1

I suspect a build with a recent MSVC would also fix it, since the UCRT uses CreateFile() to open file for stat() rather than FindFirstFile() as older MSVC and the msvcrt do.

@tonycoz tonycoz closed this as completed Dec 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
distro-mswin32 type-core Win32 This is a meta-ticket to tag issues in the perl core which need attention on Win32. See #11925
Projects
None yet
Development

No branches or pull requests

3 participants