Sample patch attached that shows the bug and possible fix.
A more robust test would be better though.
From aa8789b5dfe9e805d8b7ff7f5710293449685146 Mon Sep 17 00:00:00 2001
From: Matthew Horsfall <wolfsage@gmail.com>
Date: Thu, 31 Mar 2016 14:33:29 -0400
Subject: [PATCH] RT#113486 - Grab data from hash before decoding the key.
In cases where the field name of a file upload was utf8, the upload
itself wouldn't get filled in properly since the hash lookup would
fail with a decoded key.
---
lib/Catalyst/Engine.pm | 2 +-
t/utf_incoming.t | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/Catalyst/Engine.pm b/lib/Catalyst/Engine.pm
index 5e87e9f..fdd3df9 100644
--- a/lib/Catalyst/Engine.pm
+++ b/lib/Catalyst/Engine.pm
@@ -650,8 +650,8 @@ sub prepare_uploads {
my $uploads = $request->_body->upload;
my $parameters = $request->parameters;
foreach my $name (keys %$uploads) {
- $name = $c->_handle_unicode_decoding($name) if $enc;
my $files = $uploads->{$name};
+ $name = $c->_handle_unicode_decoding($name) if $enc;
my @uploads;
for my $upload (ref $files eq 'ARRAY' ? @$files : ($files)) {
my $headers = HTTP::Headers->new( %{ $upload->{headers} } );
diff --git a/t/utf_incoming.t b/t/utf_incoming.t
index 5f12ecb..e5d1ef9 100644
--- a/t/utf_incoming.t
+++ b/t/utf_incoming.t
@@ -17,6 +17,8 @@ use Scalar::Util ();
use base 'Catalyst::Controller';
+ use Encode 2.21 'encode_utf8';
+
sub heart :Path('â¥') {
my ($self, $c) = @_;
$c->response->content_type('text/html');
@@ -123,7 +125,7 @@ use Scalar::Util ();
my ($self, $c) = @_;
Test::More::is $c->req->body_parameters->{'â¥'}, 'â¥â¥';
- Test::More::ok my $upload = $c->req->uploads->{file};
+ Test::More::ok my $upload = $c->req->uploads->{'â¥ttachment.txt'};
Test::More::is $upload->charset, 'UTF-8';
my $text = $upload->slurp;
@@ -385,7 +387,7 @@ use Catalyst::Test 'MyApp';
ok my $path = File::Spec->catfile('t', 'utf8.txt');
ok my $req = POST '/root/file_upload',
Content_Type => 'form-data',
- Content => [encode_utf8('â¥')=>encode_utf8('â¥â¥'), file=>["$path", encode_utf8('â¥ttachment.txt'), 'Content-Type' =>'text/html; charset=UTF-8', ]];
+ Content => [encode_utf8('â¥')=>encode_utf8('â¥â¥'), encode_utf8('â¥ttachment.txt') =>["$path", encode_utf8('â¥ttachment.txt'), 'Content-Type' =>'text/html; charset=UTF-8', ]];
ok my $res = request $req;
is decode_utf8($res->content), "<p>This is stream_body_fh action â¥</p>\n";
--
2.1.4