Skip to content

Commit

Permalink
fixed JSON Pointer escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Jun 10, 2012
1 parent 6b05524 commit d291b79
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
1 change: 1 addition & 0 deletions Changes
Expand Up @@ -3,6 +3,7 @@
- Improved message parser performance slightly.
- Improved documentation. (ichesnokov, sri)
- Improved tests.
- Fixed JSON Pointer escaping.
- Fixed small JSON Pointer bug in get command. (avkhozov)

2.98 2012-05-30
Expand Down
24 changes: 19 additions & 5 deletions lib/Mojo/JSON/Pointer.pm
Expand Up @@ -12,10 +12,24 @@ sub get { shift->_pointer(0, @_) }
sub _pointer {
my ($self, $contains, $data, $pointer) = @_;

# Parse pointer and walk data structure
return unless $pointer =~ s!^/!!;
for my $p (split '/', $pointer) {
$p = decode('UTF-8', url_unescape $p);
# Tokenize pointer
$pointer = decode('UTF-8', url_unescape $pointer);
my ($escaped, @parts);
while (length(my $char = substr $pointer, 0, 1, '')) {

# Caret escaped
++$escaped and next if $char eq '^' && !$escaped;

# Slash
if ($char eq '/' && !$escaped) { push @parts, '' }

# Character
else { $parts[-1] .= $char }
$escaped = undef;
}

# Walk data structure
for my $p (@parts) {

# Hash
if (ref $data eq 'HASH' && exists $data->{$p}) { $data = $data->{$p} }
Expand Down Expand Up @@ -48,7 +62,7 @@ Mojo::JSON::Pointer - JSON Pointers
=head1 DESCRIPTION
L<Mojo::JSON::Pointer> implements JSON Pointers without caret escaping.
L<Mojo::JSON::Pointer> implements JSON Pointers.
=head1 METHODS
Expand Down
22 changes: 18 additions & 4 deletions t/mojo/json_pointer.t
Expand Up @@ -2,7 +2,7 @@ use Mojo::Base -strict;

use utf8;

use Test::More tests => 18;
use Test::More tests => 24;

# "I've had it with this school, Skinner.
# Low test scores, class after class of ugly, ugly children..."
Expand Down Expand Up @@ -40,8 +40,22 @@ is $p->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/6'), undef,
'"/foo/bar/6" is "undef"';

# "get" (encoded)
is $p->get({'' => [0, 1]}, '/%E2%99%A5/0'), 0, '"/%E2%99%A5/0" is "0"';
is $p->get([{'foob ar' => 'foo'}], '/0/foob%20ar'), 'foo',
'"/0/foob%20ar" is "foo"';
is $p->get([{'foo/bar' => 'bar'}], '/0/foo%2Fbar'), 'bar',
'"/0/foo%2Fbar" is "bar"';
is $p->get({'' => [0, 1]}, '/%E2%99%A5/0'), 0, '"/%E2%99%A5/0" is "0"';
is $p->get([{'foo/bar' => 'bar'}], '/0/foo%2Fbar'), undef,
'"/0/foo%2Fbar" is "undef"';
is $p->get([{'foo/bar' => 'bar'}], '/0/foo^%2Fbar'), 'bar',
'"/0/foo^%2Fbar" is "bar"';
is $p->get([{'foo/bar' => 'bar'}], '/0/foo%5E%2Fbar'), 'bar',
'"/0/foo%5E%2Fbar" is "bar"';
is $p->get([{'foo^/bar' => 'bar'}], '/0/foo^^^/bar'), 'bar',
'"/0/foo^^^/bar" is "bar"';
is $p->get([{'foo^/bar' => 'bar'}], '/0/foo%5E%5E%5E/bar'), 'bar',
'"/0/foo%5E%5E%5E/bar" is "bar"';
is $p->get(
[{'f^o^o^/b^' => {'a^' => {'r' => 'baz'}}}] => '/0/f^^o^^o^^^/b^^/a^^/r'),
'baz', '"/0/f^^o^^o^^^/b^^/a^^/r" is "baz"';
is $p->get([{'f^o^o^/b^' => {'a^' => {'r' => 'baz'}}}] =>
'%2F0%2Ff%5E%5Eo%5E%5Eo%5E%5E%5E%2Fb%5E%5E%2Fa%5E%5E%2Fr'), 'baz',
'"%2F0%2Ff%5E%5Eo%5E%5Eo%5E%5E%5E%2Fb%5E%5E%2Fa%5E%5E%2Fr" is "baz"';

0 comments on commit d291b79

Please sign in to comment.