Skip to content

Commit f34b28d

Browse files
committed
string scan table
1 parent ea0db6e commit f34b28d

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

ext/json/ext/parser/parser.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -851,23 +851,44 @@ static inline VALUE json_decode_string(JSON_ParserState *state, const char *star
851851

852852
#define PUSH(result) rvalue_stack_push(state->stack, result, &state->stack_handle, &state->stack)
853853

854+
static const bool string_scan[256] = {
855+
// ASCII Control Characters
856+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
857+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
858+
// ASCII Characters
859+
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"'
860+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
861+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
862+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '\\'
863+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
864+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
865+
};
866+
854867
static inline VALUE json_parse_string(JSON_ParserState *state, bool is_name) {
855868
state->cursor++;
856869
const char *start = state->cursor;
857870
bool escaped = false;
858871

859872
while (state->cursor < state->end) {
860-
if (*state->cursor == '"') {
861-
VALUE string = json_decode_string(state, start, state->cursor, escaped, is_name);
862-
state->cursor++;
863-
return PUSH(string);
864-
} else if (*state->cursor == '\\') {
865-
state->cursor++;
866-
escaped = true;
867-
}
868-
869-
if ((unsigned char)*state->cursor < 0x20) {
870-
raise_parse_error("invalid ASCII control character in string: %s", state->cursor);
873+
if (RB_UNLIKELY(string_scan[(unsigned char)*state->cursor])) {
874+
switch (*state->cursor) {
875+
case '"': {
876+
VALUE string = json_decode_string(state, start, state->cursor, escaped, is_name);
877+
state->cursor++;
878+
return PUSH(string);
879+
}
880+
case '\\': {
881+
state->cursor++;
882+
escaped = true;
883+
if ((unsigned char)*state->cursor < 0x20) {
884+
raise_parse_error("invalid ASCII control character in string: %s", state->cursor);
885+
}
886+
break;
887+
}
888+
default:
889+
raise_parse_error("invalid ASCII control character in string: %s", state->cursor);
890+
break;
891+
}
871892
}
872893

873894
state->cursor++;

0 commit comments

Comments
 (0)