diff --git a/FU.pm b/FU.pm index 3a8c94c..f43dbaf 100644 --- a/FU.pm +++ b/FU.pm @@ -1267,7 +1267,7 @@ handler being run. Any other exception is passed to the C<500> error handler. While the C namespace is used for global configuration and utility functions, the C object is intended for methods that deal with request -processing (although some are useful used outside of request handlers as well). +processing (although some are useful outside of request handlers as well). The C object itself can be used to store request-local data. For example, the following is a valid approach to handle user authentication: diff --git a/FU/Util.pm b/FU/Util.pm index 3228694..2074ada 100644 --- a/FU/Util.pm +++ b/FU/Util.pm @@ -4,6 +4,7 @@ use v5.36; use FU::XS; use Carp 'confess'; use Exporter 'import'; +use Encode (); use POSIX (); use experimental 'builtin'; @@ -19,7 +20,10 @@ our @EXPORT_OK = qw/ sub utf8_decode :prototype($) { return if !defined $_[0]; - confess 'Invalid UTF-8' if !utf8::decode($_[0]); + eval { + $_[0] = Encode::decode('UTF-8', $_[0], Encode::FB_CROAK); + 1 + } || confess($@ =~ s/ at .+\n$//r); confess 'Invalid control character' if $_[0] =~ /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/; $_[0] } diff --git a/t/query.t b/t/query.t index 80f2b00..9d1ca4a 100644 --- a/t/query.t +++ b/t/query.t @@ -10,6 +10,9 @@ is_deeply ok !eval { query_decode('%10'); 1 }; like $@, qr/Invalid control character/; +ok !eval { query_decode('a=%fe%83%bf%bf%bf%bf%bf%0a'); 1 }; +like $@, qr/does not map to Unicode/; + is_deeply query_decode('&&&a=b'), { a => 'b' }; is query_encode