Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.93k stars 551 forks source link

Can't handle a directory that has <0x5c> (backslash) at the end on the Windows system. #7589

Open p5pRT opened 19 years ago

p5pRT commented 19 years ago

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

Searchable as RT32394$

p5pRT commented 19 years ago

From ran@timedia.co.jp

If a directory include <0x5c> as a last byte of a directory name, ActivePerl can't judge whether this directory exists or not in a system by using "-d" (like a following sample code "test.pl").

#!perl
if (-d $ARGV[0]) {
print "$ARGV[0] is directory.\n";
} else {
print "$ARGV[0] is not directory.\n";
}

For example, when there is a directory consists of multi-byte characters.

C:\<0x94><0x5c>

In Japanese Windows environments, these two bytes (<0x94> and <0x5c>) compose a Japanese character.

When I ran a sample code "test.pl"(see above):

C:\> test.pl C:\<0x94><0x5c>
C:\<0x94><0x5c> is not directory

it returns "is not directory" even if C:\<0x94><0x5c> directory exists in a system.

However, when I added a backslash or backslashes as follows:

C:\> test.pl C:\<0x94><0x5c>\
C:\<0x94><0x5c>\ is directory
C:\> test.pl C:\<0x94><0x5c>\\
C:\<0x94><0x5c>\\ is directory
C:\> test.pl C:\<0x94><0x5c>\\\
C:\<0x94><0x5c>\\\ is directory

a sample program can find C:\<0x94><0x5c> directory and returns "is directory".

It seemed that one or more <0x5c> is trancated and it causes a fatal problem on a Japanese named directory that may include <0x5c> as a second byte of a particular character.

Once I submitted this problem in a bugtraq in ActiveState and received a following comment:

Comments from Jan Dubois 2004-05-18 07:27

Perl doesn't internally use the Unicode API on Windows, so the low level IO routines assume all filenames are using single byte characters only. The 0x5c character is a backslash '\' and Perl assumes that forward and backward slashes are semantically equivalent.

To work around a bug in the stat() function of the C runtime library Perl modifies a trailing backslash to a forward slash (in the win32_stat() function in win32.c).

I doubt this problem can be fixed until Perl internals move to Unicode even for the low level file access layer, and I don't see any activity in this area by the core Perl5 Porters.

Fortunately you have discovered a workaround: You can always append an additional backslash to the filename if you are using the -d test. You could use a forward slash as well because Perl will translate it internally anyways

Comments from Jan Dubois 2004-05-18 07:39

BTW, this problem affects all filetest operators, not just -d. So while you have a workaround for -d, I see that it will be impossible to apply other file operators like the file size -s to a filename ending with a 0x5c byte. :(

It seemed a reason why "an additional backslash" is needed that a trailing backslash is removed. It seemed to that "dir\subdir\" is converted to "dir\subdir" in library and it cause a problem. On the other hand, trancating two or more backslashes seemed to be work well -- "dir\subdir\" and "dir\subdir\\" is treated as "dir\subdir\".

I guess "dir\subdir\" should be remained as "dir\subdir\" instead of changing to "dir\subdir\".

Perl Info ``` --- Flags: category=core severity=high --- Site configuration information for perl v5.6.1: Configured by ActiveState at Tue Apr 13 19:24:10 2004. Summary of my perl5 (revision 5 version 6 subversion 1) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define useperlio=undef d_sfio=undef uselargefiles=undef usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef Compiler: cc='cl', ccflags ='-nologo -O1 -MD -Zi -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX', optimize='-O1 -MD -Zi -DNDEBUG', cppflags='-DWIN32' ccversion='', 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='off_t', lseeksize=4 alignbytes=8, usemymalloc=n, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -libpath:"D:\Perl\lib\CORE" -machine:x86' libpth="C:\Program Files\Microsoft Visual Studio\VC98\mfc\lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib" "D:\Perl\lib\CORE" 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 wsock32.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 wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl56.lib Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -libpath:"D:\Perl\lib\CORE" -machine:x86' Locally applied patches: ACTIVEPERL_LOCAL_PATCHES_ENTRY --- @INC for perl v5.6.1: D:/Perl/lib D:/Perl/site/lib . --- Environment for perl v5.6.1: HOME (unset) LANG=ja_JP.eucJP LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=D:\kabayaki\namazu\bin;D:\kabayaki\kakasi\bin;D:\kabayaki\kabayaki\bin;D:\kabayaki\kabayaki\libexec\common;D:\Perl\bin\;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT;C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual Studio\Common\Tools;C:\Program Files\Microsoft Visual Studio\VC98\bin PERL_BADLANG (unset) SHELL (unset) ```
p5pRT commented 7 years ago

From @jkeenan

Can anyone running ActivePerl\, Strawberry Perl\, etc.\, confirm that this is still a problem?

Would it be a problem on non-Windows Perls?

Thank you very much.

-- James E Keenan (jkeenan@​cpan.org)

p5pRT commented 7 years ago

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

p5pRT commented 7 years ago

From zefram@fysh.org

James E Keenan via RT wrote​:

Would it be a problem on non-Windows Perls?

It can't happen anywhere that the directory separator manifests as a distinctive code unit that can't otherwise appear in a pathname\, as is the case on Unix.

-zefram