@@ -1543,6 +1543,8 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
15431543 json_eat_whitespace (state , config );
15441544
15451545 VALUE value ;
1546+ const char * value_start = state -> cursor ;
1547+
15461548 switch (peek (state )) {
15471549 case 'n' :
15481550 json_match_keyword (state , "null" , 0 );
@@ -1578,13 +1580,12 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
15781580 break ;
15791581
15801582 case '-' : {
1581- const char * start = state -> cursor ;
15821583 state -> cursor ++ ;
15831584
1584- value = json_parse_number (state , config , true, start );
1585+ value = json_parse_number (state , config , true, value_start );
15851586
15861587 if (RB_UNLIKELY (UNDEF_P (value ) && config -> allow_nan && peek (state ) == 'I' )) {
1587- state -> cursor = start ;
1588+ state -> cursor = value_start ;
15881589 json_match_keyword (state , "-Infinity" , 1 );
15891590 value = CMinusInfinity ;
15901591 break ;
@@ -1593,51 +1594,49 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
15931594 // Top level numbers are ambiguous when parsing streams, we can't
15941595 // know if we parsed all the digits if we hit EOS.
15951596 if (RB_UNLIKELY (resumable && eos (state ))) {
1596- state -> cursor = start ;
1597+ state -> cursor = value_start ;
15971598 return false;
15981599 }
15991600
16001601 if (RB_UNLIKELY (UNDEF_P (value ))) {
1601- raise_syntax_error_at ("invalid number: %s" , state , start );
1602+ raise_syntax_error_at ("invalid number: %s" , state , value_start );
16021603 }
16031604 break ;
16041605 }
16051606
16061607 case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : {
1607- const char * start = state -> cursor ;
1608-
1609- value = json_parse_number (state , config , false, start );
1608+ value = json_parse_number (state , config , false, value_start );
16101609
16111610 // Top level numbers are ambiguous when parsing streams, we can't
16121611 // know if we parsed all the digits if we hit EOS.
16131612 if (RB_UNLIKELY (resumable && eos (state ))) {
1614- state -> cursor = start ;
1613+ state -> cursor = value_start ;
16151614 return false;
16161615 }
16171616
16181617 if (RB_UNLIKELY (UNDEF_P (value ))) {
1619- raise_syntax_error_at ("invalid number: %s" , state , start );
1618+ raise_syntax_error_at ("invalid number: %s" , state , value_start );
16201619 }
16211620 break ;
16221621 }
16231622
16241623 case '"' : {
16251624 // %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"}
1626- const char * start = state -> cursor ;
16271625 value = json_parse_string (state , config , false);
16281626
16291627 if (RB_UNLIKELY (UNDEF_P (value ))) {
16301628 bool is_eos = eos (state );
1631- if (resumable ) {
1632- state -> cursor = start ;
1629+ if (resumable && is_eos ) {
1630+ state -> cursor = value_start ;
1631+ return false;
16331632 }
16341633 raise_parse_error ("unexpected end of input, expected closing \"" , state , is_eos );
16351634 }
16361635 break ;
16371636 }
16381637
16391638 case '[' : {
1640- const char * start = state -> cursor ++ ;
1639+ state -> cursor ++ ;
16411640 json_eat_whitespace (state , config );
16421641
16431642 const char next = peek (state );
@@ -1646,7 +1645,7 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
16461645 value = json_decode_array (state , config , 0 );
16471646 break ;
16481647 } else if (resumable && next == 0 ) {
1649- state -> cursor = start ;
1648+ state -> cursor = value_start ;
16501649 return false;
16511650 }
16521651
@@ -1666,8 +1665,6 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
16661665 }
16671666
16681667 case '{' : {
1669- const char * object_start_cursor = state -> cursor ;
1670-
16711668 state -> cursor ++ ;
16721669 json_eat_whitespace (state , config );
16731670
@@ -1676,7 +1673,7 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
16761673 value = json_decode_object (state , config , 0 );
16771674 break ;
16781675 } else if (resumable && eos (state )) {
1679- state -> cursor = object_start_cursor ;
1676+ state -> cursor = value_start ;
16801677 return false;
16811678 }
16821679
@@ -1690,7 +1687,7 @@ ALWAYS_INLINE(static) bool json_parse_any(JSON_ParserState *state, JSON_ParserCo
16901687 .type = JSON_FRAME_OBJECT ,
16911688 .phase = JSON_PHASE_OBJECT_KEY ,
16921689 .value_stack_head = state -> value_stack -> head ,
1693- .start_offset = object_start_cursor - state -> start ,
1690+ .start_offset = value_start - state -> start ,
16941691 });
16951692 goto JSON_PHASE_OBJECT_KEY ;
16961693 }
0 commit comments