Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fixed userinfo normalization bugs in Mojo::URL (closes #725)
  • Loading branch information
kraih committed Dec 29, 2014
1 parent 97a8761 commit 2c5d2d0
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 23 deletions.
3 changes: 2 additions & 1 deletion Changes
@@ -1,7 +1,8 @@

5.71 2014-12-28
5.71 2014-12-29
- Updated Net::DNS::Native requirement to 0.15 for some important bug fixes.
- Updated jQuery to version 2.1.3.
- Fixed userinfo normalization bugs in Mojo::URL.

5.70 2014-12-18
- Improved Mojo::Template performance.
Expand Down
26 changes: 16 additions & 10 deletions lib/Mojo/URL.pm
Expand Up @@ -4,7 +4,8 @@ use overload bool => sub {1}, '""' => sub { shift->to_string }, fallback => 1;

use Mojo::Parameters;
use Mojo::Path;
use Mojo::Util qw(punycode_decode punycode_encode url_escape url_unescape);
use Mojo::Util
qw(decode encode punycode_decode punycode_encode url_escape url_unescape);

has base => sub { Mojo::URL->new };
has [qw(fragment host port scheme userinfo)];
Expand All @@ -17,7 +18,10 @@ sub authority {
return $self unless defined(my $authority = shift);

# Userinfo
$authority =~ s/^([^\@]+)\@// and $self->userinfo(url_unescape $1);
if ($authority =~ s/^([^\@]+)\@//) {
my $info = url_unescape $1;
$self->userinfo(decode('UTF-8', $info) // $info);
}

# Port
$authority =~ s/:(\d+)$// and $self->port($1);
Expand All @@ -28,9 +32,10 @@ sub authority {
}

# Build authority
return undef unless defined(my $authority = $self->host_port);
return $authority unless my $info = $self->userinfo;
return url_escape($info, '^A-Za-z0-9\-._~!$&\'()*+,;=:') . '@' . $authority;
return undef unless defined(my $authority = $self->host_port);
return $authority unless defined(my $info = $self->userinfo);
$info = url_escape encode('UTF-8', $info), '^A-Za-z0-9\-._~!$&\'()*+,;=:';
return "$info\@$authority";
}

sub host_port {
Expand Down Expand Up @@ -219,9 +224,10 @@ Mojo::URL - Uniform Resource Locator
=head1 DESCRIPTION
L<Mojo::URL> implements a subset of
L<RFC 3986|http://tools.ietf.org/html/rfc3986> and
L<RFC 3987|http://tools.ietf.org/html/rfc3987> for Uniform Resource Locators
with support for IDNA and IRIs.
L<RFC 3986|http://tools.ietf.org/html/rfc3986>,
L<RFC 3987|http://tools.ietf.org/html/rfc3987> and the
L<URL Living Standard|https://url.spec.whatwg.org> for Uniform Resource
Locators with support for IDNA and IRIs.
=head1 ATTRIBUTES
Expand Down Expand Up @@ -265,7 +271,7 @@ Scheme part of this URL.
=head2 userinfo
my $info = $url->userinfo;
$url = $url->userinfo('root:pass%3Bw0rd');
$url = $url->userinfo('root:');
Userinfo part of this URL.
Expand All @@ -277,7 +283,7 @@ following new ones.
=head2 authority
my $authority = $url->authority;
$url = $url->authority('root:pass%3Bw0rd@localhost:8080');
$url = $url->authority('root:%E2%99%A5@localhost:8080');
Authority part of this URL.
Expand Down
33 changes: 21 additions & 12 deletions t/mojo/url.t
Expand Up @@ -340,20 +340,22 @@ is "$url", 'http://xn--bcher-kva.xn--bcher-kva.xn--bcher-kva.ch:3000/foo',
'right format';

# IDNA (escaped userinfo and host)
$url = Mojo::URL->new('https://foo:b%E4r@kr%E4ih.com:3000');
is $url->host, "kr\xe4ih.com", 'right host';
is $url->ihost, 'xn--krih-moa.com', 'right internationalized host';
is $url->port, 3000, 'right port';
is "$url", 'https://foo:b%E4r@xn--krih-moa.com:3000', 'right format';
$url = Mojo::URL->new('https://%E2%99%A5:%E2%99%A5@kr%E4ih.com:3000');
is $url->userinfo, '♥:♥', 'right userinfo';
is $url->host, "kr\xe4ih.com", 'right host';
is $url->ihost, 'xn--krih-moa.com', 'right internationalized host';
is $url->port, 3000, 'right port';
is "$url", 'https://%E2%99%A5:%E2%99%A5@xn--krih-moa.com:3000', 'right format';

# IDNA (snowman)
$url = Mojo::URL->new('http://☃.net/');
ok $url->is_abs, 'is absolute';
is $url->scheme, 'http', 'right scheme';
is $url->host, '☃.net', 'right host';
is $url->ihost, 'xn--n3h.net', 'right internationalized host';
is $url->path, '/', 'right path';
is "$url", 'http://xn--n3h.net/', 'right format';
$url = Mojo::URL->new('http://☃:☃@☃.net/');
ok $url->is_abs, 'is absolute';
is $url->scheme, 'http', 'right scheme';
is $url->userinfo, '☃:☃', 'right userinfo';
is $url->host, '☃.net', 'right host';
is $url->ihost, 'xn--n3h.net', 'right internationalized host';
is $url->path, '/', 'right path';
is "$url", 'http://%E2%98%83:%E2%98%83@xn--n3h.net/', 'right format';

# IRI/IDNA
$url = Mojo::URL->new('http://☃.net/♥/?q=♥☃');
Expand Down Expand Up @@ -387,6 +389,13 @@ is "$url", 'http://xn--n3h.net/%E2%99%A5/%E2%99%A5/?%E2%99%A5=%E2%98%83',
$url = Mojo::URL->new('http://foo.com/');
is $url->to_abs, 'http://foo.com/', 'right absolute version';

# "0"
$url = Mojo::URL->new('http://0@foo.com');
is $url->scheme, 'http', 'right scheme';
is $url->userinfo, '0', 'right userinfo';
is $url->host, 'foo.com', 'right host';
is "$url", 'http://0@foo.com', 'right format';

# Empty path elements
$url = Mojo::URL->new('http://example.com/foo//bar/23/');
ok $url->is_abs, 'is absolute';
Expand Down

0 comments on commit 2c5d2d0

Please sign in to comment.