Core: allowed top-level scalars in the JSON parser

RFC 8259 permits any JSON value as a complete document, not just
objects and arrays.  The start state now accepts strings, numbers,
and the true/false/null literals as well.  A bare top-level number,
having no closing delimiter, is emitted when input ends.
This commit is contained in:
Roman Semenov 2026-08-12 09:42:28 -07:00 • committed by Roman S
parent 746609903e
commit 55db1978e2

View file

@ -103,35 +103,9 @@ ngx_json_parse_ctx(ngx_json_ctx_t *ctx, u_char *data, size_t len)
break;
}
if (*p == '{') {
rc = ngx_json_push_state(ctx, ngx_json_ctx_object);
if (rc != NGX_OK) {
return rc;
}
if (ngx_json_emit(ctx, NGX_JSON_OBJECT_OPEN, p, 1) != NGX_OK) {
return NGX_ERROR;
}
state = ngx_json_object;
break;
}
if (*p == '[') {
rc = ngx_json_push_state(ctx, ngx_json_ctx_array);
if (rc != NGX_OK) {
return rc;
}
if (ngx_json_emit(ctx, NGX_JSON_ARRAY_OPEN, p, 1) != NGX_OK) {
return NGX_ERROR;
}
state = ngx_json_array;
break;
}
return NGX_DECLINED;
p--;
state = ngx_json_value;
break;
case ngx_json_object:
if (ngx_json_ws(*p)) {
@ -665,6 +639,22 @@ ngx_json_parse_ctx(ngx_json_ctx_t *ctx, u_char *data, size_t len)
skip_depth = ctx->skip_until_depth;
}
/* a bare top-level number is not self-delimited; emit it at end of input */
if (ctx->depth == 0
&& (state == ngx_json_number_int_zero
|| state == ngx_json_number_int
|| state == ngx_json_number_frac_digit
|| state == ngx_json_number_exp_digit))
{
rc = ngx_json_emit(ctx, NGX_JSON_VALUE_NUMBER, start, last - start);
if (rc != NGX_OK) {
return rc;
}
state = ngx_json_done;
}
ctx->state = state;
if (state == ngx_json_done) {