@@ -406,6 +406,10 @@ typedef struct JSON_ParserStateStruct {
406406 int current_nesting ;
407407} JSON_ParserState ;
408408
409+ static inline ssize_t rest (JSON_ParserState * state ) {
410+ return state -> end - state -> cursor ;
411+ }
412+
409413static inline bool eos (JSON_ParserState * state ) {
410414 return state -> cursor >= state -> end ;
411415}
@@ -564,39 +568,39 @@ static const bool whitespace[256] = {
564568static void
565569json_eat_comments (JSON_ParserState * state )
566570{
567- if ( state -> cursor + 1 < state -> end ) {
568- switch ( state -> cursor [ 1 ]) {
569- case '/' : {
570- state -> cursor = memchr ( state -> cursor , '\n' , state -> end - state -> cursor );
571- if (! state -> cursor ) {
572- state -> cursor = state -> end ;
573- } else {
574- state -> cursor ++ ;
575- }
576- break ;
571+ const char * start = state -> cursor ;
572+ state -> cursor ++ ;
573+
574+ switch ( peek ( state )) {
575+ case '/' : {
576+ state -> cursor = memchr ( state -> cursor , '\n' , state -> end - state -> cursor ) ;
577+ if (! state -> cursor ) {
578+ state -> cursor = state -> end ;
579+ } else {
580+ state -> cursor ++ ;
577581 }
578- case '*' : {
579- state -> cursor += 2 ;
580- while (true) {
581- state -> cursor = memchr (state -> cursor , '*' , state -> end - state -> cursor );
582- if (!state -> cursor ) {
583- raise_parse_error_at ("unexpected end of input, expected closing '*/'" , state , state -> end );
584- } else {
585- state -> cursor ++ ;
586- if (peek (state ) == '/' ) {
587- state -> cursor ++ ;
588- break ;
589- }
590- }
582+ break ;
583+ }
584+ case '*' : {
585+ state -> cursor ++ ;
586+
587+ while (true) {
588+ const char * next_match = memchr (state -> cursor , '*' , state -> end - state -> cursor );
589+ if (!next_match ) {
590+ raise_parse_error_at ("unterminated comment, expected closing '*/'" , state , start );
591+ }
592+
593+ state -> cursor = next_match + 1 ;
594+ if (peek (state ) == '/' ) {
595+ state -> cursor ++ ;
596+ break ;
591597 }
592- break ;
593598 }
594- default :
595- raise_parse_error ("unexpected token %s" , state );
596- break ;
599+ break ;
597600 }
598- } else {
599- raise_parse_error ("unexpected token %s" , state );
601+ default :
602+ raise_parse_error_at ("unexpected token %s" , state , start );
603+ break ;
600604 }
601605}
602606
@@ -1130,15 +1134,15 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11301134
11311135 switch (peek (state )) {
11321136 case 'n' :
1133- if ((state -> end - state -> cursor > = 4 ) && (memcmp (state -> cursor , "null" , 4 ) == 0 )) {
1137+ if (rest (state ) > = 4 && (memcmp (state -> cursor , "null" , 4 ) == 0 )) {
11341138 state -> cursor += 4 ;
11351139 return json_push_value (state , config , Qnil );
11361140 }
11371141
11381142 raise_parse_error ("unexpected token %s" , state );
11391143 break ;
11401144 case 't' :
1141- if ((state -> end - state -> cursor > = 4 ) && (memcmp (state -> cursor , "true" , 4 ) == 0 )) {
1145+ if (rest (state ) > = 4 && (memcmp (state -> cursor , "true" , 4 ) == 0 )) {
11421146 state -> cursor += 4 ;
11431147 return json_push_value (state , config , Qtrue );
11441148 }
@@ -1147,7 +1151,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11471151 break ;
11481152 case 'f' :
11491153 // Note: memcmp with a small power of two compile to an integer comparison
1150- if ((state -> end - state -> cursor > = 5 ) && (memcmp (state -> cursor + 1 , "alse" , 4 ) == 0 )) {
1154+ if (rest (state ) > = 5 && (memcmp (state -> cursor + 1 , "alse" , 4 ) == 0 )) {
11511155 state -> cursor += 5 ;
11521156 return json_push_value (state , config , Qfalse );
11531157 }
@@ -1156,15 +1160,15 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11561160 break ;
11571161 case 'N' :
11581162 // Note: memcmp with a small power of two compile to an integer comparison
1159- if (config -> allow_nan && (state -> end - state -> cursor > = 3 ) && (memcmp (state -> cursor + 1 , "aN" , 2 ) == 0 )) {
1163+ if (config -> allow_nan && rest (state ) > = 3 && (memcmp (state -> cursor + 1 , "aN" , 2 ) == 0 )) {
11601164 state -> cursor += 3 ;
11611165 return json_push_value (state , config , CNaN );
11621166 }
11631167
11641168 raise_parse_error ("unexpected token %s" , state );
11651169 break ;
11661170 case 'I' :
1167- if (config -> allow_nan && (state -> end - state -> cursor > = 8 ) && (memcmp (state -> cursor , "Infinity" , 8 ) == 0 )) {
1171+ if (config -> allow_nan && rest (state ) > = 8 && (memcmp (state -> cursor , "Infinity" , 8 ) == 0 )) {
11681172 state -> cursor += 8 ;
11691173 return json_push_value (state , config , CInfinity );
11701174 }
@@ -1173,7 +1177,7 @@ static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config)
11731177 break ;
11741178 case '-' : {
11751179 // Note: memcmp with a small power of two compile to an integer comparison
1176- if ((state -> end - state -> cursor > = 9 ) && (memcmp (state -> cursor + 1 , "Infinity" , 8 ) == 0 )) {
1180+ if (rest (state ) > = 9 && (memcmp (state -> cursor + 1 , "Infinity" , 8 ) == 0 )) {
11771181 if (config -> allow_nan ) {
11781182 state -> cursor += 9 ;
11791183 return json_push_value (state , config , CMinusInfinity );
0 commit comments