Subject: | [PATCH] canon_path not canon at all on Win32 |
From: | Autrijus Tang <autrijus [...] autrijus.org> |
To: | bug-file-spec [...] rt.cpan.org |
Date: | Sun, 09 Nov 2003 00:29:29 +0800 |
The patch below has been sitting in my repository for 9 months, and I
finally got tired of merging it back against each new perl release. :-)
Basically, without this patch, HTML::Mason cannot run reliably on
Win32. It's because it tests the incoming URL and the on-disk component
path by passing them both to File::Spec->canon_path, and compare the
return values.
Unfortunately, short/long file names, like
C:\Progra~1
C:\Program Files
as well as case differences are all preserved by canon_path, thereby
making valid requests fail.
My solution is to simply install a _longname wrapper that tries
Win32::GetLongPathName first. It worked well in production.
I'd appreciate if it can be merged back to File::Spec.
Thanks,
/Autrijus/
--- //depot/samba/Common/perl/lib/File/Spec/Win32.pm 2003/11/08 23:32:37
+++ //depot/samba/Common/perl/lib/File/Spec/Win32.pm 2003/11/09 00:04:38
@@ -121,6 +121,11 @@
=cut
+sub _longname {
+ return $_[1] unless defined &Win32::GetLongPathName;
+ return Win32::GetLongPathName($_[1]) || $_[1];
+}
+
sub canonpath {
my ($self,$path) = @_;
my $orig_path = $path;
@@ -134,9 +139,9 @@
# xx1/xx2/xx3/../../xx -> xx1/xx
$path =~ s|\\\.\.\.\\|\\\.\.\\\.\.\\|g; # \...\ is 2 levels up
$path =~ s|^\.\.\.\\|\.\.\\\.\.\\|g; # ...\ is 2 levels up
- return $path if $path =~ m|^\.\.|; # skip relative paths
- return $path unless $path =~ /\.\./; # too few .'s to cleanup
- return $path if $path =~ /\.\.\.\./; # too many .'s to cleanup
+ return $self->_longname($path) if $path =~ m|^\.\.|; # skip relative paths
+ return $self->_longname($path) unless $path =~ /\.\./; # too few .'s to cleanup
+ return $self->_longname($path) if $path =~ /\.\.\.\./; # too many .'s to cleanup
$path =~ s{^\\\.\.$}{\\}; # \.. -> \
1 while $path =~ s{^\\\.\.}{}; # \..\xx -> \xx
@@ -162,7 +167,7 @@
$self->catdir(@base_dirs, @path_dirs),
$file
);
- return $path;
+ return $self->_longname($path);
}
=item splitpath