Skip to content

Commit 11f4e7b

Browse files
committed
parser.c: Introduce rest() helper
1 parent f0150e2 commit 11f4e7b

File tree

1 file changed

+39
-35
lines changed

1 file changed

+39
-35
lines changed

ext/json/ext/parser/parser.c

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
409413
static inline bool eos(JSON_ParserState *state) {
410414
return state->cursor >= state->end;
411415
}
@@ -564,39 +568,39 @@ static const bool whitespace[256] = {
564568
static void
565569
json_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

Comments
 (0)