-
Notifications
You must be signed in to change notification settings - Fork 567
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
PATCH: File::Spec::UNIX->abs2rel() gets it wrong with ".." components #11985
Comments
From perldoc@volkerschatz.comHello, this is a bugfix I submitted to CPAN a while ago (#61451). I have verified If you have follow-up questions, it would probably be best to CC me, though I Kind regards, Volker Here is the detailed bug description: File::Spec::UNIX->abs2rel() returns wrong results in a few cases, most To reproduce, paste the following test cases into: ../foo bar/bat Correct results when run at /home/me and no symlinks in base path: Results for File::Spec::Unix from PathTols 3.33: The error in the first test case is due to an optimisation applied when I have replaced this optimisation by a single call to _cwd() in the (hunk @@ -362,28 +363,32 @@) The error in the last test case arises because a root dir $base is As regards the second and third test case, they can be solved without (hunk @@ -391,19 +396,39 @@) It can be impossible for abs2rel() to work correctly without looking at (hunk @@ -348,9 +348,10 @@) |
From perldoc@volkerschatz.comUnix.pm.diff--- Unix.pm.3.33 2012-03-03 09:14:11.352578001 +0100
+++ Unix.pm 2012-03-03 09:17:02.348578001 +0100
@@ -348,9 +348,10 @@
If $path is relative, it is converted to absolute form using L</rel2abs()>.
This means that it is taken to be relative to L<cwd()|Cwd>.
-No checks against the filesystem are made. On VMS, there is
-interaction with the working environment, as logicals and
-macros are expanded.
+No checks against the filesystem are made, so the result may not be correct if
+C<$base> contains symbolic links. (Apply L<Cwd::abs_path()> beforehand if that
+is a concern.) On VMS, there is interaction with the working environment, as
+logicals and macros are expanded.
Based on code written by Shigio Yamaguchi.
@@ -362,28 +363,32 @@
($path, $base) = map $self->canonpath($_), $path, $base;
+ my $path_directories;
+ my $base_directories;
+
if (grep $self->file_name_is_absolute($_), $path, $base) {
($path, $base) = map $self->rel2abs($_), $path, $base;
- }
- else {
- # save a couple of cwd()s if both paths are relative
- ($path, $base) = map $self->catdir('/', $_), $path, $base;
- }
- my ($path_volume) = $self->splitpath($path, 1);
- my ($base_volume) = $self->splitpath($base, 1);
+ my ($path_volume) = $self->splitpath($path, 1);
+ my ($base_volume) = $self->splitpath($base, 1);
- # Can't relativize across volumes
- return $path unless $path_volume eq $base_volume;
+ # Can't relativize across volumes
+ return $path unless $path_volume eq $base_volume;
- my $path_directories = ($self->splitpath($path, 1))[1];
- my $base_directories = ($self->splitpath($base, 1))[1];
+ $path_directories = ($self->splitpath($path, 1))[1];
+ $base_directories = ($self->splitpath($base, 1))[1];
- # For UNC paths, the user might give a volume like //foo/bar that
- # strictly speaking has no directory portion. Treat it as if it
- # had the root directory for that volume.
- if (!length($base_directories) and $self->file_name_is_absolute($base)) {
- $base_directories = $self->rootdir;
+ # For UNC paths, the user might give a volume like //foo/bar that
+ # strictly speaking has no directory portion. Treat it as if it
+ # had the root directory for that volume.
+ if (!length($base_directories) and $self->file_name_is_absolute($base)) {
+ $base_directories = $self->rootdir;
+ }
+ }
+ else {
+ my $wd= ($self->splitpath($self->_cwd(), 1))[1];
+ $path_directories = $self->catdir($wd, $path);
+ $base_directories = $self->catdir($wd, $base);
}
# Now, remove all leading components that are the same
@@ -391,19 +396,39 @@
my @basechunks = $self->splitdir( $base_directories );
if ($base_directories eq $self->rootdir) {
+ return $self->curdir if $path_directories eq $self->rootdir;
shift @pathchunks;
return $self->canonpath( $self->catpath('', $self->catdir( @pathchunks ), '') );
}
+ my @common;
while (@pathchunks && @basechunks && $self->_same($pathchunks[0], $basechunks[0])) {
- shift @pathchunks ;
+ push @common, shift @pathchunks ;
shift @basechunks ;
}
return $self->curdir unless @pathchunks || @basechunks;
- # $base now contains the directories the resulting relative path
- # must ascend out of before it can descend to $path_directory.
- my $result_dirs = $self->catdir( ($self->updir) x @basechunks, @pathchunks );
+ # @basechunks now contains the directories the resulting relative path
+ # must ascend out of before it can descend to $path_directory. If there
+ # are updir components, we must descend into the corresponding directories
+ # (this only works if they are no symlinks).
+ my @reverse_base;
+ while( defined(my $dir= shift @basechunks) ) {
+ if( $dir ne $self->updir ) {
+ unshift @reverse_base, $self->updir;
+ push @common, $dir;
+ }
+ elsif( @common ) {
+ if( @reverse_base && $reverse_base[0] eq $self->updir ) {
+ shift @reverse_base;
+ pop @common;
+ }
+ else {
+ unshift @reverse_base, pop @common;
+ }
+ }
+ }
+ my $result_dirs = $self->catdir( @reverse_base, @pathchunks );
return $self->canonpath( $self->catpath('', $result_dirs, '') );
}
@@ -469,6 +494,8 @@
This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
+Please submit bug reports and patches to perlbug@perl.org.
+
=head1 SEE ALSO
L<File::Spec>
|
From @cpansproutOn Sat Mar 03 02:02:56 2012, perldoc@volkerschatz.com wrote:
Thank you for the patch. It looks good to me. Is there any chance you could add some tests to rel2abs2rel.t? -- Father Chrysostomos |
The RT System itself - Status changed from 'new' to 'open' |
From perldoc@volkerschatz.com
I don't understand what rel2abs2rel.t does; but Spec.t contains all the other Inline Patch--- Spec.t.orig 2010-07-23 09:55:30.000000000 +0200
+++ Spec.t 2012-05-26 20:54:57.608000003 +0200
@@ -135,6 +135,10 @@
[ "Unix->abs2rel('/t1/t2/t3', '/t1')", 't2/t3' ],
[ "Unix->abs2rel('t1/t2/t3', 't1')", 't2/t3' ],
[ "Unix->abs2rel('t1/t2/t3', 't4')", '../t1/t2/t3' ],
+[ "Unix->abs2rel('.', '.')", '.' ],
+[ "Unix->abs2rel('/', '/')", '.' ],
+[ "Unix->abs2rel('../t1', 't2/t3')", '../../../t1' ],
+[ "Unix->abs2rel('t1', 't2/../t3')", '../t1' ],
[ "Unix->rel2abs('t4','/t1/t2/t3')", '/t1/t2/t3/t4' ],
[ "Unix->rel2abs('t4/t5','/t1/t2/t3')", '/t1/t2/t3/t4/t5' ],
[ "Unix->abs2rel('t1/t2', '../t3')", '../PathTools-3.33/t1/t2' ], If the expected result is a static string, it would have to be adapted with Regards, Volker |
From @cpansproutOn Sat May 26 12:05:12 2012, perldoc@volkerschatz.com wrote:
Thank you. I’ve applied both your patches, as 70b6afc and -- Father Chrysostomos |
@cpansprout - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#111510 (status was 'resolved')
Searchable as RT111510$
The text was updated successfully, but these errors were encountered: