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