Hello. There is a new bug in &Dancer::FileUtils::normalize_path at 1.3072 :( Sample test: use Dancer::FileUtils 'path'; use Test::More 'no_plan'; is path('a/../b') => 'b'; is path('a/b/../../c') => 'c'; is path('a/b/c/../../../d') => 'd'; Output: ok 1 ok 2 not ok 3 # Failed test at t/q line 8. # got: 'a/b/d' # expected: 'd' There is wrong usage of regex with /g modifier. Simple patch is below: --- Dancer/FileUtils.pm.orig 2011-09-06 01:11:42.000000000 +0400 +++ Dancer/FileUtils.pm 2011-09-06 01:11:49.000000000 +0400 @@ -102,8 +102,7 @@ }x; $path =~ s{/\./}{/}g; - $path =~ s{$seqregex}{}g; - $path =~ s{$seqregex}{}g; + while ( $path =~ s{$seqregex}{} ) {} return $path; } But, imho, it's a bad idea to do any kind of 'universal path normalization'. What's the point? Only desire for aesthetics? Underlying FS is able to do it more reliable any case. POD on &File::Spec::canonpath talks us: "Note that this does *not* collapse x/../y sections into y. This is by design. If /foo on your system is a symlink to /bar/baz, then /foo/../quux is actually /bar/quux, not /quux as a naive ../−removal would give you. If you want to do this kind of processing, you probably want "Cwd"’s "realpath()" function to actually traverse the filesystem cleaning up paths like this." How do you suppose to handle hierarchy with symlinks? And &Cwd::realpath works like (3) realpath: "All components of file_name must exist when realpath() is called." Perhaps the best way is to drop path normalization code from Dancer::FileUtils completely? -- Cheers, Oleg A. Mamontov mailto: oleg@mamontov.net jabber: lonerr@charla.mamontov.net icq uin: 79-521-617 cell: +7-903-798-1352