Skip Menu |

This queue is for tickets about the JSON CPAN distribution.

Report information
The Basics
Id: 46439
Status: resolved
Priority: 0/
Queue: JSON

People
Owner: Nobody in particular
Requestors: bohica [...] ntlworld.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Possible inconsistencies using incr_text and incr_parsing
Hi, I've only noticed this whilst trying to find an issue in JSON::XS so I'm not sure how much you will care about this. The pod for JSON::PP (and XS) says under incr_text: "This only works when a preceding call to incr_parse in scalar context successfully returned an object." The problem I'm having with JSON::XS is I call incr_text AFTER a scalar context call to incr_parse returns an object and all is ok UNLESS the string to parse contains unicode in which case I get: "incr_text can not be called when the incremental parser already started parsing" I came across JSON::PP and thought I'd see if it worked with JSON:PP or if JSON::PP had the same issue - it didn't but I think there may be a small issue in JSON::PP with the use of the object attribute "incr_parsing". It looks as if this is used to keep track of whether you are in the middle of an incremental parse or not but the code in incr_parse for a scalar context call does: else { # in scalar context $self->{incr_parsing} = 1; my $obj = $self->_incr_parse( $coder, $self->{incr_text} ); $self->{incr_parsing} = 0; return $obj; } That is it indiscriminately clears incr_parsing whether an object was returned or not. This also means the error in incr_text: sub incr_text { if ( $_[0]->{incr_parsing} ) { Carp::croak("incr_text can not be called when the incremental parser already started parsing"); } can never be reached. I believe incr_parse should really be: else { # in scalar context $self->{incr_parsing} = 1; my $obj = $self->_incr_parse( $coder, $self->{incr_text} ); $self->{incr_parsing} = 0 if $obj; # <--- NOTE return $obj; } Anyway it depends on whether the pod is right or the code was written to protect the caller from calling incr_text in the middle of a parse. Attached is a small self contained test. Martin -- Martin J. Evans Wetherby, UK
Subject: json_pp_incremental.pl
use Data::Dumper; use JSON::PP; binmode(STDOUT, ":utf8"); my $data = ["\x{53f0}\x{6240}\x{306e}\x{6d41}\x{3057}", "\x{6c60}\x{306e}\x{30ab}\x{30a8}\x{30eb}"]; # the following works: #my $data = ["fred", # "blog"]; my $j = new JSON::PP; my $js = $j->encode($data); $j = undef; print "encoded: " . $js, "\n"; my @parts = (substr($js, 0, int(length($js) / 2)), substr($js, int(length($js) / 2))); my $j = JSON::PP->new; my $object = $j->incr_parse($parts[0]); die "got object" if $object; print $j->{incr_parsing} , "\n"; eval { print "incr_text is : " . $j->incr_text, "\n"; }; print "According to docs I'd expect incr_text to fail here - error was $@\n"; my $object = $j->incr_parse($parts[1]); die "no object" if !$object; print $j->{incr_parsing} , "\n"; print Dumper($object); eval { print "incr_text is : " . $j->incr_text; }; print "Why do we get this error - $@" if $@;
Thanks for your report! I released the modified version. Regards,