I can't believe there isn't a solution out there that does this. But since I didn't find one, here's mine. It handles the symlink issue. Rather minimally tested.
#!perl -l use strict; use warnings; use File::Spec; my %seen; # Find the last symlink in the path # Find the absolute path to that symlink # Tack on whatever is after it # squeeze out .. entries sub true_path { my ($path, $base, $stuff_to_tack_on) = @_; $path = File::Spec->rel2abs( $path, $base ) ; #print "*** Checking <$path>"; die "Circular!" if $seen{$path}++; my $last_symlink = ''; my $stuff_after_last_symlink = ''; my $built_path = ''; for my $dir (File::Spec->splitdir($path)) { my $test_path = File::Spec->catdir($built_path, $dir); if (-l $test_path) { #print "Found symlink $test_path"; $base = $built_path; $last_symlink = readlink $test_path; $stuff_after_last_symlink = ''; } else { #print "non-symlink $test_path"; $stuff_after_last_symlink = File::Spec->catdir($stuff_afte +r_last_symlink, $dir); } $built_path = $test_path; } if ($last_symlink ne '') { #print "Symlink=$last_symlink; Base=$base"; true_path($last_symlink, $base, File::Spec->catdir($stuff_afte +r_last_symlink, $stuff_to_tack_on)); } else { # Safe from symlinks, strip out foo/.. my @dirlist = (); for my $dir (File::Spec->splitdir(File::Spec->catdir($built_pa +th, $stuff_to_tack_on))) { if ($dir eq '..') { pop @dirlist } else { push @dirlist, $dir }; } $path = @dirlist ? File::Spec->catdir(@dirlist) : ''; } } s/\s+$//, %seen=(), print "$_\n -->", true_path($_, '', '') while <DAT +A>; __DATA__ /var/log/../../home/poletti/../../etc/passwd . /var/../..

Caution: Contents may have been coded under pressure.

In reply to Re: Cleaning up a path by Roy Johnson
in thread Cleaning up a path by polettix

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.