From 26d373dbb03287c5478de5349ec386d91a094943 Mon Sep 17 00:00:00 2001 From: Alexander Kuehne Date: Fri, 28 Mar 2025 14:54:32 +0100 Subject: [PATCH] psgi env: fix double encoding of path parts Fix double encoding of path parts when parsing a PSGI env with a SCRIPT_NAME set. Make sure path is decoded and unescaped as expected by to_string. The test $env used in the regression test included is a stripped down version of the result of: use HTTP::Request::Common 'GET'; use HTTP::Message::PSGI 'req_to_psgi'; my $script_name = ...; my $path = ...; $env = req_to_psgi( GET( 'http://localhost:8080'.$script_name.$path ), SCRIPT_NAME => $script_name ); --- lib/Mojo/Message/Request.pm | 1 + t/mojo/request_cgi.t | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/Mojo/Message/Request.pm b/lib/Mojo/Message/Request.pm index c9bbd01395..0b7c132a76 100644 --- a/lib/Mojo/Message/Request.pm +++ b/lib/Mojo/Message/Request.pm @@ -197,6 +197,7 @@ sub _parse_env { $base->path->parse($value =~ m!/$! ? $value : "$value/"); # Remove SCRIPT_NAME prefix if necessary + $path->parts; my $buffer = $path->to_string; $value =~ s!^/|/$!!g; $buffer =~ s!^/?\Q$value\E/?!!; diff --git a/t/mojo/request_cgi.t b/t/mojo/request_cgi.t index d902dc421d..87119e0530 100644 --- a/t/mojo/request_cgi.t +++ b/t/mojo/request_cgi.t @@ -2,6 +2,7 @@ use Mojo::Base -strict; use Test::More; use Mojo::Message::Request; +use Mojo::Util qw(encode url_escape); subtest 'Parse Lighttpd CGI environment variables and body' => sub { my $req = Mojo::Message::Request->new; @@ -124,6 +125,25 @@ subtest 'Parse CGI environment with maximum message size' => sub { 'right absolute URL'; }; +subtest 'Parse CGI environment with SCRIPT_NAME set and path part with UTF-8 character' => sub { + my $req = Mojo::Message::Request->new; + my $script_name = '/app/'; + my $path_stub = 'some/action/blub/'; + my $part_utf8 = encode('utf-8', "\x{1d120}"); + my $path = $path_stub.url_escape($part_utf8); + $req->parse({ + CONTENT_LENGTH => 0, + PATH_INFO => '/'.$path_stub.$part_utf8, + REQUEST_URI => $script_name.$path, + QUERY_STRING => '', + REQUEST_METHOD => 'GET', + SCRIPT_NAME => $script_name, + HTTP_HOST => 'localhost:8080', + SERVER_PROTOCOL => 'HTTP/1.1' + }); + is $req->url->path->to_string, $path, 'round tripping yields same path'; +}; + subtest 'Parse Apache CGI environment variables and body (file storage)' => sub { local $ENV{MOJO_MAX_MEMORY_SIZE} = 10; my $req = Mojo::Message::Request->new;