]> git.kaiwu.me - njs.git/commitdiff
QuickJS: fix body_read_len mismatch in QuickJS readRequestJSON()
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 11 Jun 2026 04:20:04 +0000 (21:20 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Thu, 11 Jun 2026 15:21:53 +0000 (08:21 -0700)
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().

nginx/ngx_http_js_module.c

index aadbcc5956bd64d5a7b923d2ed612c34653144d3..67e2124712d93c9ced146fc06c651aad9113027c 100644 (file)
@@ -6684,6 +6684,7 @@ static JSValue
 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;
 
@@ -6704,14 +6705,14 @@ ngx_http_qjs_body_to_value(JSContext *cx, ngx_http_js_ctx_t *ctx,
             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;