@@ -21824,6 +21824,7 @@ static __exception int next_token(JSParseState *s)
21824
21824
}
21825
21825
21826
21826
/* 'c' is the first character. Return JS_ATOM_NULL in case of error */
21827
+ /* XXX: accept unicode identifiers as JSON5 ? */
21827
21828
static JSAtom json_parse_ident(JSParseState *s, const uint8_t **pp, int c)
21828
21829
{
21829
21830
const uint8_t *p;
@@ -21899,11 +21900,22 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp, int sep)
21899
21900
c = (c << 4) | h;
21900
21901
}
21901
21902
break;
21903
+ case '\n':
21904
+ if (s->ext_json)
21905
+ continue;
21906
+ goto bad_escape;
21907
+ case 'v':
21908
+ if (s->ext_json) {
21909
+ c = '\v';
21910
+ break;
21911
+ }
21912
+ goto bad_escape;
21902
21913
default:
21903
21914
if (c == sep)
21904
21915
break;
21905
21916
if (p > s->buf_end)
21906
21917
goto end_of_input;
21918
+ bad_escape:
21907
21919
js_parse_error_pos(s, p - 1, "Bad escaped character");
21908
21920
goto fail;
21909
21921
}
@@ -21943,8 +21955,23 @@ static int json_parse_number(JSParseState *s, const uint8_t **pp)
21943
21955
if (*p == '+' || *p == '-')
21944
21956
p++;
21945
21957
21946
- if (!is_digit(*p))
21947
- return js_parse_error_pos(s, p, "Unexpected token '%c'", *p_start);
21958
+ if (!is_digit(*p)) {
21959
+ if (s->ext_json) {
21960
+ if (strstart((const char *)p, "Infinity", (const char **)&p)) {
21961
+ d = 1.0 / 0.0;
21962
+ if (*p_start == '-')
21963
+ d = -d;
21964
+ goto done;
21965
+ } else if (strstart((const char *)p, "NaN", (const char **)&p)) {
21966
+ d = NAN;
21967
+ goto done;
21968
+ } else if (*p != '.') {
21969
+ goto unexpected_token;
21970
+ }
21971
+ } else {
21972
+ goto unexpected_token;
21973
+ }
21974
+ }
21948
21975
21949
21976
if (p[0] == '0') {
21950
21977
if (s->ext_json) {
@@ -21962,8 +21989,10 @@ static int json_parse_number(JSParseState *s, const uint8_t **pp)
21962
21989
}
21963
21990
if (radix != 10) {
21964
21991
/* prefix is present */
21965
- if (to_digit(*p) >= radix)
21992
+ if (to_digit(*p) >= radix) {
21993
+ unexpected_token:
21966
21994
return js_parse_error_pos(s, p, "Unexpected token '%c'", *p);
21995
+ }
21967
21996
d = js_atod((const char *)p_start, (const char **)&p, 0,
21968
21997
JS_ATOD_INT_ONLY | JS_ATOD_ACCEPT_BIN_OCT, &atod_mem);
21969
21998
goto done;
@@ -22122,7 +22151,6 @@ static __exception int json_next_token(JSParseState *s)
22122
22151
case 'Y': case 'Z':
22123
22152
case '_':
22124
22153
case '$':
22125
- /* identifier : only pure ascii characters are accepted */
22126
22154
p++;
22127
22155
atom = json_parse_ident(s, &p, c);
22128
22156
if (atom == JS_ATOM_NULL)
@@ -22133,17 +22161,16 @@ static __exception int json_next_token(JSParseState *s)
22133
22161
s->token.val = TOK_IDENT;
22134
22162
break;
22135
22163
case '+':
22136
- if (!s->ext_json || !is_digit(p[1]) )
22164
+ if (!s->ext_json)
22137
22165
goto def_token;
22138
22166
goto parse_number;
22139
- case '0':
22140
- if (is_digit(p[1]))
22167
+ case '.':
22168
+ if (s->ext_json && is_digit(p[1]))
22169
+ goto parse_number;
22170
+ else
22141
22171
goto def_token;
22142
- goto parse_number;
22143
22172
case '-':
22144
- if (!is_digit(p[1]))
22145
- goto def_token;
22146
- goto parse_number;
22173
+ case '0':
22147
22174
case '1': case '2': case '3': case '4':
22148
22175
case '5': case '6': case '7': case '8':
22149
22176
case '9':
@@ -46187,6 +46214,12 @@ static JSValue json_parse_value(JSParseState *s)
46187
46214
val = JS_NewBool(ctx, s->token.u.ident.atom == JS_ATOM_true);
46188
46215
} else if (s->token.u.ident.atom == JS_ATOM_null) {
46189
46216
val = JS_NULL;
46217
+ } else if (s->token.u.ident.atom == JS_ATOM_NaN && s->ext_json) {
46218
+ /* Note: json5 identifier handling is ambiguous e.g. is
46219
+ '{ NaN: 1 }' a valid JSON5 production ? */
46220
+ val = JS_NewFloat64(s->ctx, NAN);
46221
+ } else if (s->token.u.ident.atom == JS_ATOM_Infinity && s->ext_json) {
46222
+ val = JS_NewFloat64(s->ctx, INFINITY);
46190
46223
} else {
46191
46224
goto def_token;
46192
46225
}
0 commit comments