Description: Fix path traversal security vulnerability
Origin: backport, commit: b09854988c5b5b6a2ba5
Bug: https://github.com/kraih/mojo/issues/114
Bug-Debian: http://bugs.debian.org/622952 
Forwarded: no
Author: Salvatore Bonaccorso <carnil@debian.org>
Last-Update: 2011-04-16

--- a/lib/Mojo/Path.pm
+++ b/lib/Mojo/Path.pm
@@ -85,6 +85,9 @@
     $self->leading_slash(1)  if $path =~ /^\//;
     $self->trailing_slash(1) if $path =~ /\/$/;
 
+    # Unescape
+    $path = b($path)->url_unescape($Mojo::URL::PCHAR)->to_string;
+
     # Parse
     my @parts;
     for my $part (split '/', $path) {
@@ -93,7 +96,7 @@
         next unless length $part;
 
         # Store
-        push @parts, b($part)->url_unescape($Mojo::URL::PCHAR)->to_string;
+        push @parts, $part;
     }
 
     $self->parts(\@parts);
--- a/t/mojo/path.t
+++ b/t/mojo/path.t
@@ -5,7 +5,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 3;
+use Test::More tests => 11;
 
 # This is the greatest case of false advertising I’ve seen since I sued the
 # movie “The Never Ending Story.”
@@ -14,3 +14,18 @@
 my $path = Mojo::Path->new;
 is($path->parse('/path')->to_string,   '/path',   'right path');
 is($path->parse('/path/0')->to_string, '/path/0', 'right path');
+
+# Canonicalizing
+$path = Mojo::Path->new(
+  '/%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd');
+is "$path", '/../../../../../../../../../../etc/passwd', 'rigth result';
+is $path->parts->[0], '..', 'right part';
+is $path->canonicalize, '/../../../../../../../../../../etc/passwd',
+  'rigth result';
+is $path->parts->[0], '..', 'right part';
+$path = Mojo::Path->new(
+  '/%2ftest%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd');
+is "$path", '/test/../../../../../../../../../etc/passwd', 'rigth result';
+is $path->parts->[0], 'test', 'right part';
+is $path->canonicalize, '/../../../../../../../../etc/passwd', 'rigth result';
+is $path->parts->[0], '..', 'right part';
--- a/t/mojo/url.t
+++ b/t/mojo/url.t
@@ -121,12 +121,12 @@
 is($url->userinfo, undef,                                     'no userinfo');
 is($url->host,     'acme.s3.amazonaws.com',                   'right host');
 is($url->port,     undef,                                     'no port');
-is($url->path,     '/mojo%2Fg++-4.2_4.2.3-2ubuntu7_i386.deb', 'right path');
+is($url->path,     '/mojo/g++-4.2_4.2.3-2ubuntu7_i386.deb', 'right path');
 ok(!$url->query, 'no query');
 is_deeply($url->query->to_hash, {}, 'right structure');
 is($url->fragment, undef, 'no fragment');
 is("$url",
-    'http://acme.s3.amazonaws.com/mojo%2Fg++-4.2_4.2.3-2ubuntu7_i386.deb',
+    'http://acme.s3.amazonaws.com/mojo/g++-4.2_4.2.3-2ubuntu7_i386.deb',
     'right format');
 
 # Clone (advanced)
