Skip Menu |

This queue is for tickets about the PathTools CPAN distribution.

Report information
The Basics
Id: 90636
Status: open
Priority: 0/
Queue: PathTools

People
Owner: Nobody in particular
Requestors: jkeenan [...] cpan.org
MJD [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 3.40
Fixed in: (no value)



Subject: File::Spec::no_upwards does not behave as promised
The manual for File::Spec::no_upwards v3.40 promises: Given a list of file names, strip out those that refer to a parent directory. For example, perl -MFile::Spec -le 'print File::Spec->no_upwards( ".." ) ? "not ok" : "ok" ' prints "ok". perl -MFile::Spec -le 'print File::Spec->no_upwards( "../.." ) ? "not o k" : "ok" ' should also print "ok", but it doesn't. This is probably related to Bug 46960.
I suppose I'm probably missing some important edge case, and I recognize that this won't work on VMF, MS-DOS, etc., but I have not been able to find anything wrong with the following implementation: sub is_upwards { my ($path) = @_; grep $_ eq "..", split m{/}, $path; } sub no_upwards { grep ! is_upwards($_), @_ }
On Fri Nov 22 14:06:46 2013, MJD wrote: Show quoted text
> The manual for File::Spec::no_upwards v3.40 promises: > > Given a list of file names, strip out those that refer to a > parent directory. > > For example, > > perl -MFile::Spec -le 'print File::Spec->no_upwards( ".." ) ? "not ok" > : "ok" ' > > prints "ok". > > perl -MFile::Spec -le 'print File::Spec->no_upwards( "../.." ) ? "not > o > k" : "ok" ' > > should also print "ok", but it doesn't. > > This is probably related to Bug 46960.
... which I was looking at earlier this evening. But how would we know whether File::Spec::no_upwards() behaves as promised, when we never test it! ##### $ ack no_upwards dist/Cwd dist/Cwd/lib/File/Spec/Functions.pm 22: no_upwards 99: no_upwards dist/Cwd/lib/File/Spec/Unix.pm 214:=item no_upwards 221:sub no_upwards { dist/Cwd/lib/File/Spec.pm 158:=item no_upwards 163: @paths = File::Spec->no_upwards( @paths ); ##### I find no evidence that it is tested in the Perl 5 core distribution! Thank you very much. Jim Keenan
On Sat Nov 23 22:47:14 2013, JKEENAN wrote: Show quoted text
> > I find no evidence that it is tested in the Perl 5 core distribution!
Indeed, I originally wanted to submit a patch with tests in the test suite, but I gave up because I couldn't find them.
On Fri Nov 22 16:26:52 2013, MJD wrote: Show quoted text
> I suppose I'm probably missing some important edge case, and I > recognize that this won't work on VMF, MS-DOS, etc., but I have not > been able to find anything wrong with the following implementation: > > sub is_upwards { > my ($path) = @_; > grep $_ eq "..", split m{/}, $path; > } > > sub no_upwards { grep ! is_upwards($_), @_ }
The question I have is what the intended behavior is? Eliminate any path with any parent directory component? Or eliminate paths that go above the root? E.g. ".." is bad; "./foo/bar/.." is OK because it refers to "./foo" (ignoring symlinks at least). If *any* parent directory component is bad, then I think is_upwards has to be more generic like this: sub is_upwards { my ($path) = @_; my ($vol, $dir) = File::Spec->splitpath($path, 1); my $updir = File::Spec->updir; return ! scalar grep { $_ eq $updir } File::Spec->splitdir($dir); } That would allow "." (which isn't a parent directory anyway), but I don't think that's a real problem. That might not be sufficient if a platform has multiple representations for a parent directory (VMS?) E.g. apparently some versions of Windows might treat "..." as "..\..".
On Fri Nov 22 16:26:52 2013, MJD wrote: Show quoted text
> I suppose I'm probably missing some important edge case, and I > recognize that this won't work on VMF, MS-DOS, etc., but I have not > been able to find anything wrong with the following implementation: > > sub is_upwards { > my ($path) = @_; > grep $_ eq "..", split m{/}, $path; > } > > sub no_upwards { grep ! is_upwards($_), @_ }
The question I have is what the intended behavior is? Eliminate any path with any parent directory component? Or eliminate paths that go above the root? E.g. ".." is bad; "./foo/bar/.." is OK because it refers to "./foo" (ignoring symlinks at least). If *any* parent directory component is bad, then I think is_upwards has to be more generic like this: sub is_upwards { my ($path) = @_; my ($vol, $dir) = File::Spec->splitpath($path, 1); my $updir = File::Spec->updir; return ! scalar grep { $_ eq $updir } File::Spec->splitdir($dir); } That would allow "." (which isn't a parent directory anyway), but I don't think that's a real problem. That might not be sufficient if a platform has multiple representations for a parent directory (VMS?) E.g. apparently some versions of Windows might treat "..." as "..\..".