@@ -639,44 +639,43 @@ static inline VALUE json_string_fastpath(JSON_ParserState *state, const char *st
639639static VALUE json_string_unescape (JSON_ParserState * state , const char * string , const char * stringEnd , bool is_name , bool intern , bool symbolize )
640640{
641641 size_t bufferSize = stringEnd - string ;
642- const char * p = string , * pe = string , * unescape , * bufferStart ;
642+ const char * p = string , * pe = string , * bufferStart ;
643643 char * buffer ;
644- int unescape_len ;
645- char buf [4 ];
646644
647645 VALUE result = rb_str_buf_new (bufferSize );
648646 rb_enc_associate_index (result , utf8_encindex );
649647 buffer = RSTRING_PTR (result );
650648 bufferStart = buffer ;
651649
650+ #define APPEND_CHAR (chr ) *buffer++ = chr; p = ++pe;
651+
652652 while (pe < stringEnd && (pe = memchr (pe , '\\' , stringEnd - pe ))) {
653- unescape = (char * ) "?" ;
654- unescape_len = 1 ;
655653 if (pe > p ) {
656654 MEMCPY (buffer , p , char , pe - p );
657655 buffer += pe - p ;
658656 }
659657 switch (* ++ pe ) {
658+ case '"' :
659+ case '/' :
660+ p = pe ; // nothing to unescape just need to skip the backslash
661+ break ;
662+ case '\\' :
663+ APPEND_CHAR ('\\' );
664+ break ;
660665 case 'n' :
661- unescape = ( char * ) "\n" ;
666+ APPEND_CHAR ( '\n' ) ;
662667 break ;
663668 case 'r' :
664- unescape = ( char * ) "\r" ;
669+ APPEND_CHAR ( '\r' ) ;
665670 break ;
666671 case 't' :
667- unescape = (char * ) "\t" ;
668- break ;
669- case '"' :
670- unescape = (char * ) "\"" ;
671- break ;
672- case '\\' :
673- unescape = (char * ) "\\" ;
672+ APPEND_CHAR ('\t' );
674673 break ;
675674 case 'b' :
676- unescape = ( char * ) "\b" ;
675+ APPEND_CHAR ( '\b' ) ;
677676 break ;
678677 case 'f' :
679- unescape = ( char * ) "\f" ;
678+ APPEND_CHAR ( '\f' ) ;
680679 break ;
681680 case 'u' :
682681 if (pe > stringEnd - 5 ) {
@@ -714,18 +713,23 @@ static VALUE json_string_unescape(JSON_ParserState *state, const char *string, c
714713 break ;
715714 }
716715 }
717- unescape_len = convert_UTF32_to_UTF8 (buf , ch );
718- unescape = buf ;
716+
717+ char buf [4 ];
718+ int unescape_len = convert_UTF32_to_UTF8 (buf , ch );
719+ MEMCPY (buffer , buf , char , unescape_len );
720+ buffer += unescape_len ;
721+ p = ++ pe ;
719722 }
720723 break ;
721724 default :
722- p = pe ;
723- continue ;
725+ if ((unsigned char )* pe < 0x20 ) {
726+ raise_parse_error_at ("invalid ASCII control character in string: %s" , state , pe - 1 );
727+ }
728+ raise_parse_error_at ("invalid escape character in string: %s" , state , pe - 1 );
729+ break ;
724730 }
725- MEMCPY (buffer , unescape , char , unescape_len );
726- buffer += unescape_len ;
727- p = ++ pe ;
728731 }
732+ #undef APPEND_CHAR
729733
730734 if (stringEnd > p ) {
731735 MEMCPY (buffer , p , char , stringEnd - p );
@@ -976,9 +980,6 @@ static inline VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig
976980 case '\\' : {
977981 state -> cursor ++ ;
978982 escaped = true;
979- if ((unsigned char )* state -> cursor < 0x20 ) {
980- raise_parse_error ("invalid ASCII control character in string: %s" , state );
981- }
982983 break ;
983984 }
984985 default :
0 commit comments