]> git.kaiwu.me - njs.git/commitdiff
Fixed NULL pointer dereference when processing If-* headers.
authorDmitry Volyntsev <xeioex@nginx.com>
Tue, 8 Jul 2025 05:40:45 +0000 (22:40 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Tue, 8 Jul 2025 22:25:58 +0000 (15:25 -0700)
Previously, when processing requests with If-Match and
If-Unmodified-Since headers worker process crashed.

For example with the following code:
try { r.return(200) }
catch (e) { r.internalRedirect() }

The fix is to disable not_modified filter as it was done in
nginx perl module nginx/nginx@d9887ee2.

nginx/ngx_http_js_module.c
nginx/t/js_internal_redirect.t

index 1e0a927f3dd534ed5f8a9ada255953ee60a7ad14..45ddf17ef8ff64dbbefc65dbb35857a0abf57629 100644 (file)
@@ -2455,6 +2455,8 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         return NJS_ERROR;
     }
 
+    r->disable_not_modified = 1;
+
     if (ngx_http_send_header(r) == NGX_ERROR) {
         return NJS_ERROR;
     }
@@ -2738,6 +2740,8 @@ ngx_http_js_ext_return(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         cv.value.data = text.start;
         cv.value.len = text.length;
 
+        r->disable_not_modified = 1;
+
         ctx->status = ngx_http_send_response(r, status, NULL, &cv);
 
         if (ctx->status == NGX_ERROR) {
@@ -5445,6 +5449,8 @@ ngx_http_qjs_ext_return(JSContext *cx, JSValueConst this_val,
         cv.value.data = body.data;
         cv.value.len = body.len;
 
+        r->disable_not_modified = 1;
+
         ctx->status = ngx_http_send_response(r, status, NULL, &cv);
 
         if (ctx->status == NGX_ERROR) {
@@ -5670,6 +5676,8 @@ ngx_http_qjs_ext_send_header(JSContext *cx, JSValueConst this_val,
         return JS_ThrowInternalError(cx, "failed to set content type");
     }
 
+    r->disable_not_modified = 1;
+
     if (ngx_http_send_header(r) == NGX_ERROR) {
         return JS_ThrowInternalError(cx, "failed to send header");
     }
index abfe79f9a20972b5fed881d42b0ab6b480b3d25b..721113bb43dcb70bafe2ff96f02f7f48a1576590 100644 (file)
@@ -11,6 +11,7 @@ use warnings;
 use strict;
 
 use Test::More;
+use Socket qw/ CRLF /;
 
 BEGIN { use FindBin; chdir($FindBin::Bin); }
 
@@ -54,6 +55,10 @@ http {
             return 200 redirect$arg_b;
         }
 
+        location /destroyed_ctx {
+            js_content test.destroyed_ctx;
+        }
+
         location @named {
             return 200 named;
         }
@@ -87,7 +92,16 @@ $t->write_file('test.js', <<EOF);
         }
     }
 
-    export default {njs:test_njs, redirect};
+    function destroyed_ctx(r) {
+        try {
+            r.return(200);
+
+        } catch (e) {
+            r.internalRedirect("\@sub");
+        }
+    }
+
+    export default {njs:test_njs, redirect, destroyed_ctx};
 
 EOF
 
@@ -103,5 +117,18 @@ like(http_get('/test?unsafe=1'), qr/500 Internal Server/s,
        'unsafe redirect');
 like(http_get('/test?quoted=1'), qr/200 .*redirect/s,
        'quoted redirect');
+get('/destroyed_ctx', 'If-Match: tt');
 
 ###############################################################################
+
+sub get {
+    my ($url, @headers) = @_;
+    return http(
+        "GET $url HTTP/1.1" . CRLF .
+        'Host: localhost' . CRLF .
+        'Connection: close' . CRLF .
+        join(CRLF, @headers) . CRLF . CRLF
+    );
+}
+
+################################################################################