Skip to content

Commit c77b2bc

Browse files
doriantayloroalders
authored andcommitted
closes #57 (canonical always clones)
1 parent 5ad7306 commit c77b2bc

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

lib/URI.pm

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -302,21 +302,22 @@ sub canonical
302302
# Make sure scheme is lowercased, that we don't escape unreserved chars,
303303
# and that we use upcase escape sequences.
304304

305-
my $self = shift;
306-
my $scheme = $self->_scheme || "";
305+
# We now clone unconditionally; see
306+
# https://github.com/libwww-perl/URI/issues/57
307+
308+
my $other = $_[0]->clone;
309+
my $scheme = $other->_scheme || "";
307310
my $uc_scheme = $scheme =~ /[A-Z]/;
308-
my $esc = $$self =~ /%[a-fA-F0-9]{2}/;
309-
return $self unless $uc_scheme || $esc;
311+
my $esc = $$other =~ /%[a-fA-F0-9]{2}/;
312+
return $other unless $uc_scheme || $esc;
313+
314+
$other->_scheme(lc $scheme) if $uc_scheme;
310315

311-
my $other = $self->clone;
312-
if ($uc_scheme) {
313-
$other->_scheme(lc $scheme);
314-
}
315316
if ($esc) {
316-
$$other =~ s{%([0-9a-fA-F]{2})}
317-
{ my $a = chr(hex($1));
317+
$$other =~ s{%([0-9a-fA-F]{2})}
318+
{ my $a = chr(hex($1));
318319
$a =~ /^[$unreserved]\z/o ? $a : "%\U$1"
319-
}ge;
320+
}ge;
320321
}
321322
return $other;
322323
}
@@ -571,8 +572,12 @@ removing the explicit port specification if it matches the default port,
571572
uppercasing all escape sequences, and unescaping octets that can be
572573
better represented as plain characters.
573574
574-
For efficiency reasons, if the $uri is already in normalized form,
575-
then a reference to it is returned instead of a copy.
575+
Before version 1.75, this method would return the original unchanged
576+
C<$uri> object if it detected nothing to change. To make the return
577+
value consistent (and since the efficiency gains from this behaviour
578+
were marginal), this method now unconditionally returns a clone. This
579+
means idioms like C<< $uri->clone->canonical >> are no longer
580+
necessary.
576581
577582
=item $uri->eq( $other_uri )
578583

t/generic.t

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use strict;
22
use warnings;
33

4-
print "1..48\n";
4+
print "1..49\n";
55

66
use URI;
7+
use Scalar::Util qw(refaddr);
78

89
my $foo = URI->new("Foo:opaque#frag");
910

@@ -217,3 +218,8 @@ $old = $foo->query("q");
217218
print "not " unless !defined($old) && $foo eq "?q";
218219
print "ok 48\n";
219220

221+
# canonical must always be a clone
222+
my $c1 = $foo->canonical; # canonicalize first
223+
my $c2 = $c1->canonical; # canonicalize again
224+
print 'not ' if refaddr($c1) == refaddr($c2) or $$c1 ne $$c2;
225+
print "ok 49\n";

0 commit comments

Comments
 (0)