Previously, for the JSON body type without a NUL terminator,
ngx_http_qjs_body_to_value() round-tripped the raw body through
qjs_string_create() (JS_NewStringLen) and JS_ToCString(), then parsed
the result with JS_ParseJSON() using the original body_read_len.
JS_NewStringLen() collapses invalid UTF-8 (a run of continuation bytes
becomes a single U+FFFD), so the byte length of the C string no longer
matches body_read_len. With a body containing such bytes the parser was
handed the wrong length and a valid body was truncated and rejected as a
SyntaxError.
The fix is to use JS_ToCStringLen() to capture the actual C string
length and pass it to JS_ParseJSON().
ngx_http_qjs_body_to_value(JSContext *cx, ngx_http_js_ctx_t *ctx,
ngx_uint_t type)
{
+ size_t cstr_len;
JSValue str;
const char *cstr;
return str;
}
- cstr = JS_ToCString(cx, str);
+ cstr = JS_ToCStringLen(cx, &cstr_len, str);
JS_FreeValue(cx, str);
if (cstr == NULL) {
return JS_EXCEPTION;
}
- str = JS_ParseJSON(cx, cstr, ctx->body_read_len, "<body>");
+ str = JS_ParseJSON(cx, cstr, cstr_len, "<body>");
JS_FreeCString(cx, cstr);
return str;