]> git.kaiwu.me - njs.git/commitdiff
QuickJS: fixed js_body_filter with multiple chunks.
authorDmitry Volyntsev <xeioex@nginx.com>
Sat, 10 Jan 2026 02:08:56 +0000 (18:08 -0800)
committerDmitry Volyntsev <xeioexception@gmail.com>
Mon, 12 Jan 2026 22:24:14 +0000 (14:24 -0800)
Previously, last_key atoms was freed too early. Also, js_body_filter.t
is modified to ensure js_body_filter sees multiple data chains to catch
the issue.

nginx/ngx_http_js_module.c
nginx/t/js_body_filter.t

index 6bc2bca3a3360320cd14c34e21f90788cf541c9e..d7bcd78f4345df3eceddfefa5e6bdef288a921dc 100644 (file)
@@ -7525,11 +7525,11 @@ ngx_http_qjs_body_filter(ngx_http_request_t *r, ngx_http_js_loc_conf_t *jlcf,
             rc = ctx->engine->call((ngx_js_ctx_t *) ctx, &jlcf->body_filter,
                                    (njs_opaque_value_t *) &arguments[0], 3);
 
-            JS_FreeAtom(cx, last_key);
             JS_FreeValue(cx, arguments[1]);
             JS_FreeValue(cx, arguments[2]);
 
             if (rc == NGX_ERROR) {
+                JS_FreeAtom(cx, last_key);
                 return NGX_ERROR;
             }
 
@@ -7537,6 +7537,7 @@ ngx_http_qjs_body_filter(ngx_http_request_t *r, ngx_http_js_loc_conf_t *jlcf,
                 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                               "async operation inside \"%V\" body filter",
                               &jlcf->body_filter);
+                JS_FreeAtom(cx, last_key);
                 return NGX_ERROR;
             }
 
@@ -7545,6 +7546,7 @@ ngx_http_qjs_body_filter(ngx_http_request_t *r, ngx_http_js_loc_conf_t *jlcf,
         } else {
             cl = ngx_alloc_chain_link(c->pool);
             if (cl == NULL) {
+                JS_FreeAtom(cx, last_key);
                 return NGX_ERROR;
             }
 
@@ -7557,6 +7559,8 @@ ngx_http_qjs_body_filter(ngx_http_request_t *r, ngx_http_js_loc_conf_t *jlcf,
         in = in->next;
     }
 
+    JS_FreeAtom(cx, last_key);
+
     return NGX_OK;
 }
 
index 6bd6bddb640f9b00456cfda8a085bde4b0949c12..afe77bc36e88c35f1c86b8173074c3515d3e9158 100644 (file)
@@ -156,9 +156,24 @@ like(http_get('/prepend'), qr/XXXAAABBCDDDD$/, 'prepend');
 
 ###############################################################################
 
+sub send_chunked {
+       my ($client, @chunks) = @_;
+
+       print $client
+               "HTTP/1.1 200 OK" . CRLF .
+               "Transfer-Encoding: chunked" . CRLF .
+               "Connection: close" . CRLF .
+               CRLF;
+
+       for my $chunk (@chunks) {
+               printf $client "%x\r\n%s\r\n", length($chunk), $chunk;
+       }
+
+       print $client "0\r\n\r\n";
+}
+
 sub http_daemon {
        my $port = shift;
-       my $delay = shift || 0.05;
 
        my $server = IO::Socket::INET->new(
                Proto => 'tcp',
@@ -189,34 +204,10 @@ sub http_daemon {
                log2c("(new connection $client $uri)");
 
                if ($uri eq '/source') {
-                       print $client
-                               "HTTP/1.1 200 OK" . CRLF .
-                               "Content-Length: 10" . CRLF .
-                               "Connection: close" . CRLF .
-                               CRLF;
-
-                       print $client "AAA";
-                       select undef, undef, undef, $delay;
-                       print $client "BB";
-                       select undef, undef, undef, $delay;
-                       print $client "C";
-                       select undef, undef, undef, $delay;
-                       print $client "DDDD";
-
-               }  elsif ($uri eq '/nonutf8_source') {
-                       print $client
-                               "HTTP/1.1 200 OK" . CRLF .
-                               "Content-Length: 6" . CRLF .
-                               "Connection: close" . CRLF .
-                               CRLF;
+                       send_chunked($client, "AAA", "BB", "C", "DDDD");
 
-                       print $client "\xaa\xaa";
-                       select undef, undef, undef, $delay;
-                       print $client "\xbb";
-                       select undef, undef, undef, $delay;
-                       print $client "\xcc";
-                       select undef, undef, undef, $delay;
-                       print $client "\xdd\xdd";
+               } elsif ($uri eq '/nonutf8_source') {
+                       send_chunked($client, "\xaa\xaa", "\xbb", "\xcc", "\xdd\xdd");
 
                } else {
                        print $client