bug? in URI::Escape::uri_unescape 3.13 in list context
Nicholas Clark (nick@ccl4.org)
Wed, 16 Aug 2000 18:07:49 +0100
The URI-1.08 README suggests that bug reports should be sent here.
URI::Escape 3.13 has
sub uri_unescape
{
# Note from RFC1630: "Sequences which start with a percent sign
# but are not followed by two hexadecimal characters are reserved
# for future extension"
my $str = shift;
if (@_ && wantarray) {
# not executed for the common case of a single argument
my @str = @_; # need to copy
return map { s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg } $str, @str;
}
$str =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
$str;
}
This is sensible definition in scalar context for single:
/usr/bin/perl -MURI::Escape -wle 'foreach (@ARGV) {@foo=scalar uri_unescape ($_); print $foo[0]}' 1 2 '%33' 4 '%7E%21'
1
2
3
4
~!
and multiple arguments:
/usr/bin/perl -MURI::Escape -wle 'foreach (@ARGV) {@foo=scalar uri_unescape ($_,$_); print $foo[0]}' 1 2 '%33' 4 '%7E%21'
1
2
3
4
~!
and for list context with a single argument
/usr/bin/perl -MURI::Escape -wle 'foreach (@ARGV) {@foo=uri_unescape ($_); print $foo[0]}' 1 2 '%33' 4 '%7E%21'
1
2
3
4
~!
as for these (@_ && wantarray) is false and the sub returns $str;
However, for list context with multiple arguments one enters the if clause,
and the return value is the map of s///g in list context, which gives the
number of substitutions:
/usr/bin/perl -MURI::Escape -wle 'foreach (@ARGV) {@foo= uri_unescape ($_,$_); print $foo[0]}' 1 2 '%33' 4 '%7E%21'
1
2
This would appear to be a bug. The following would fix it:
sub uri_unescape
{
# Note from RFC1630: "Sequences which start with a percent sign
# but are not followed by two hexadecimal characters are reserved
# for future extension"
my $str = shift;
if (@_ && wantarray) {
# not executed for the common case of a single argument
my @str = ($str, @_); # need to copy
foreach (@str) {
s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg
}
return @str;
}
$str =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
$str;
}
Ideally should there be a regression test?
Nicholas Clark