details:   
https://github.com/nginx/njs/commit/a9dabca11201f5e56196c876a6b4791e858c0358
branches:  master
commit:    a9dabca11201f5e56196c876a6b4791e858c0358
user:      Dmitry Volyntsev <xei...@nginx.com>
date:      Thu, 28 Aug 2025 16:29:22 -0700
description:
QuickJS: freeing temporary strings.


---
 nginx/ngx_js_shared_dict.c   | 73 ++++++++++++++++++++++++++++++++------------
 nginx/ngx_qjs_fetch.c        | 46 +++++++++++++++++-----------
 nginx/ngx_stream_js_module.c | 33 ++++++++++----------
 3 files changed, 99 insertions(+), 53 deletions(-)

diff --git a/nginx/ngx_js_shared_dict.c b/nginx/ngx_js_shared_dict.c
index 5445b4f2..28eed0da 100644
--- a/nginx/ngx_js_shared_dict.c
+++ b/nginx/ngx_js_shared_dict.c
@@ -3202,6 +3202,7 @@ static JSValue
 ngx_qjs_ext_shared_dict_delete(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv)
 {
+    JSValue          ret;
     ngx_str_t        key;
     ngx_shm_zone_t  *shm_zone;
 
@@ -3210,11 +3211,16 @@ ngx_qjs_ext_shared_dict_delete(JSContext *cx, 
JSValueConst this_val,
         return JS_ThrowTypeError(cx, "\"this\" is not a shared dict");
     }
 
-    if (ngx_qjs_string(cx, argv[0], &key) != NGX_OK) {
+    key.data = (u_char *) JS_ToCStringLen(cx, &key.len, argv[0]);
+    if (key.data == NULL) {
         return JS_EXCEPTION;
     }
 
-    return ngx_qjs_dict_delete(cx, shm_zone->data, &key, 0);
+    ret = ngx_qjs_dict_delete(cx, shm_zone->data, &key, 0);
+
+    JS_FreeCString(cx, (char *) key.data);
+
+    return ret;
 }
 
 
@@ -3245,6 +3251,7 @@ static JSValue
 ngx_qjs_ext_shared_dict_get(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv)
 {
+    JSValue          ret;
     ngx_str_t        key;
     ngx_shm_zone_t  *shm_zone;
 
@@ -3253,11 +3260,16 @@ ngx_qjs_ext_shared_dict_get(JSContext *cx, JSValueConst 
this_val,
         return JS_ThrowTypeError(cx, "\"this\" is not a shared dict");
     }
 
-    if (ngx_qjs_string(cx, argv[0], &key) != NGX_OK) {
+    key.data = (u_char *) JS_ToCStringLen(cx, &key.len, argv[0]);
+    if (key.data == NULL) {
         return JS_EXCEPTION;
     }
 
-    return ngx_qjs_dict_get(cx, shm_zone->data, &key);
+    ret = ngx_qjs_dict_get(cx, shm_zone->data, &key);
+
+    JS_FreeCString(cx, (char *) key.data);
+
+    return ret;
 }
 
 
@@ -3277,7 +3289,8 @@ ngx_qjs_ext_shared_dict_has(JSContext *cx, JSValueConst 
this_val,
         return JS_ThrowTypeError(cx, "\"this\" is not a shared dict");
     }
 
-    if (ngx_qjs_string(cx, argv[0], &key) != NGX_OK) {
+    key.data = (u_char *) JS_ToCStringLen(cx, &key.len, argv[0]);
+    if (key.data == NULL) {
         return JS_EXCEPTION;
     }
 
@@ -3298,6 +3311,8 @@ ngx_qjs_ext_shared_dict_has(JSContext *cx, JSValueConst 
this_val,
 
     ngx_rwlock_unlock(&dict->sh->rwlock);
 
+    JS_FreeCString(cx, (char *) key.data);
+
     return JS_NewBool(cx, node != NULL);
 }
 
@@ -3306,6 +3321,7 @@ static JSValue
 ngx_qjs_ext_shared_dict_incr(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv)
 {
+    JSValue          ret;
     double           delta, init;
     uint32_t         timeout;
     ngx_str_t        key;
@@ -3323,10 +3339,6 @@ ngx_qjs_ext_shared_dict_incr(JSContext *cx, JSValueConst 
this_val,
         return JS_ThrowTypeError(cx, "shared dict is not a number dict");
     }
 
-    if (ngx_qjs_string(cx, argv[0], &key) != NGX_OK) {
-        return JS_EXCEPTION;
-    }
-
     if (JS_ToFloat64(cx, &delta, argv[1]) < 0) {
         return JS_EXCEPTION;
     }
@@ -3357,7 +3369,16 @@ ngx_qjs_ext_shared_dict_incr(JSContext *cx, JSValueConst 
this_val,
         timeout = dict->timeout;
     }
 
-    return ngx_qjs_dict_incr(cx, dict, &key, delta, init, timeout);
+    key.data = (u_char *) JS_ToCStringLen(cx, &key.len, argv[0]);
+    if (key.data == NULL) {
+        return JS_EXCEPTION;
+    }
+
+    ret = ngx_qjs_dict_incr(cx, dict, &key, delta, init, timeout);
+
+    JS_FreeCString(cx, (char *) key.data);
+
+    return ret;
 }
 
 
@@ -3576,6 +3597,7 @@ static JSValue
 ngx_qjs_ext_shared_dict_pop(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv)
 {
+    JSValue          ret;
     ngx_str_t        key;
     ngx_shm_zone_t  *shm_zone;
 
@@ -3584,11 +3606,16 @@ ngx_qjs_ext_shared_dict_pop(JSContext *cx, JSValueConst 
this_val,
         return JS_ThrowTypeError(cx, "\"this\" is not a shared dict");
     }
 
-    if (ngx_qjs_string(cx, argv[0], &key) != NGX_OK) {
+    key.data = (u_char *) JS_ToCStringLen(cx, &key.len, argv[0]);
+    if (key.data == NULL) {
         return JS_EXCEPTION;
     }
 
-    return ngx_qjs_dict_delete(cx, shm_zone->data, &key, 1);
+    ret = ngx_qjs_dict_delete(cx, shm_zone->data, &key, 1);
+
+    JS_FreeCString(cx, (char *) key.data);
+
+    return ret;
 }
 
 
@@ -3607,10 +3634,6 @@ ngx_qjs_ext_shared_dict_set(JSContext *cx, JSValueConst 
this_val,
         return JS_ThrowTypeError(cx, "\"this\" is not a shared dict");
     }
 
-    if (ngx_qjs_string(cx, argv[0], &key) != NGX_OK) {
-        return JS_EXCEPTION;
-    }
-
     dict = shm_zone->data;
 
     if (dict->type == NGX_JS_DICT_TYPE_STRING) {
@@ -3647,17 +3670,29 @@ ngx_qjs_ext_shared_dict_set(JSContext *cx, JSValueConst 
this_val,
         timeout = dict->timeout;
     }
 
+    key.data = (u_char *) JS_ToCStringLen(cx, &key.len, argv[0]);
+    if (key.data == NULL) {
+        return JS_EXCEPTION;
+    }
+
     ret = ngx_qjs_dict_set(cx, shm_zone->data, &key, argv[1], timeout, flags);
     if (JS_IsException(ret)) {
-        return JS_EXCEPTION;
+        goto done;
     }
 
     if (flags) {
         /* add() or replace(). */
-        return ret;
+        goto done;
     }
 
-    return JS_DupValue(cx, this_val);
+    JS_FreeValue(cx, ret);
+    ret = JS_DupValue(cx, this_val);
+
+done:
+
+    JS_FreeCString(cx, (char *) key.data);
+
+    return ret;
 }
 
 
diff --git a/nginx/ngx_qjs_fetch.c b/nginx/ngx_qjs_fetch.c
index 5ed8fc30..d043bd5d 100644
--- a/nginx/ngx_qjs_fetch.c
+++ b/nginx/ngx_qjs_fetch.c
@@ -1768,7 +1768,6 @@ static JSValue
 ngx_qjs_ext_fetch_headers_delete(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv)
 {
-    ngx_int_t          rc;
     ngx_str_t          name;
     ngx_uint_t         i;
     ngx_list_part_t   *part;
@@ -1781,8 +1780,8 @@ ngx_qjs_ext_fetch_headers_delete(JSContext *cx, 
JSValueConst this_val,
                                      "\"this\" is not fetch headers object");
     }
 
-    rc = ngx_qjs_string(cx, argv[0], &name);
-    if (rc != NGX_OK) {
+    name.data = (u_char *) JS_ToCStringLen(cx, &name.len, argv[0]);
+    if (name.data == NULL) {
         return JS_EXCEPTION;
     }
 
@@ -1819,6 +1818,8 @@ ngx_qjs_ext_fetch_headers_delete(JSContext *cx, 
JSValueConst this_val,
         headers->content_type = NULL;
     }
 
+    JS_FreeCString(cx, (const char *) name.data);
+
     return JS_UNDEFINED;
 }
 
@@ -1827,7 +1828,6 @@ static JSValue
 ngx_qjs_ext_fetch_headers_foreach(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv)
 {
-    int                ret;
     JSValue            callback, keys, key;
     JSValue            header, retval, arguments[2];
     uint32_t           length;;
@@ -1862,13 +1862,14 @@ ngx_qjs_ext_fetch_headers_foreach(JSContext *cx, 
JSValueConst this_val,
             goto fail;
         }
 
-        ret = ngx_qjs_string(cx, key, &name);
-        if (ret != NGX_OK) {
+        name.data = (u_char *) JS_ToCStringLen(cx, &name.len, key);
+        if (name.data == NULL) {
             JS_FreeValue(cx, key);
             goto fail;
         }
 
         header = ngx_qjs_headers_get(cx, this_val, &name, 0);
+        JS_FreeCString(cx, (char *) name.data);
         if (JS_IsException(header)) {
             JS_FreeValue(cx, key);
             goto fail;
@@ -1900,15 +1901,19 @@ static JSValue
 ngx_qjs_ext_fetch_headers_get(JSContext *cx, JSValueConst this_val,
     int argc, JSValueConst *argv, int magic)
 {
-    ngx_int_t  rc;
+    JSValue    ret;
     ngx_str_t  name;
 
-    rc = ngx_qjs_string(cx, argv[0], &name);
-    if (rc != NGX_OK) {
+    name.data = (u_char *) JS_ToCStringLen(cx, &name.len, argv[0]);
+    if (name.data == NULL) {
         return JS_EXCEPTION;
     }
 
-    return ngx_qjs_headers_get(cx, this_val, &name, magic);
+    ret = ngx_qjs_headers_get(cx, this_val, &name, magic);
+
+    JS_FreeCString(cx, (char *) name.data);
+
+    return ret;
 }
 
 
@@ -1920,12 +1925,13 @@ ngx_qjs_ext_fetch_headers_has(JSContext *cx, 
JSValueConst this_val,
     ngx_int_t  rc;
     ngx_str_t  name;
 
-    rc = ngx_qjs_string(cx, argv[0], &name);
-    if (rc != NGX_OK) {
+    name.data = (u_char *) JS_ToCStringLen(cx, &name.len, argv[0]);
+    if (name.data == NULL) {
         return JS_EXCEPTION;
     }
 
     retval = ngx_qjs_headers_get(cx, this_val, &name, 0);
+    JS_FreeCString(cx, (char *) name.data);
     if (JS_IsException(retval)) {
         return JS_EXCEPTION;
     }
@@ -1954,13 +1960,14 @@ ngx_qjs_ext_fetch_headers_set(JSContext *cx, 
JSValueConst this_val,
                                      "\"this\" is not fetch headers object");
     }
 
-    rc = ngx_qjs_string(cx, argv[0], &name);
-    if (rc != NGX_OK) {
+    name.data = (u_char *) JS_ToCStringLen(cx, &name.len, argv[0]);
+    if (name.data == NULL) {
         return JS_EXCEPTION;
     }
 
     rc = ngx_qjs_string(cx, argv[1], &value);
     if (rc != NGX_OK) {
+        JS_FreeCString(cx, (const char *) name.data);
         return JS_EXCEPTION;
     }
 
@@ -1997,12 +2004,15 @@ ngx_qjs_ext_fetch_headers_set(JSContext *cx, 
JSValueConst this_val,
                 *pp = NULL;
             }
 
+            JS_FreeCString(cx, (const char *) name.data);
+
             return JS_UNDEFINED;
         }
     }
 
     rc = ngx_qjs_headers_append(cx, headers, name.data, name.len,
                                  value.data, value.len);
+    JS_FreeCString(cx, (const char *) name.data);
     if (rc != NGX_OK) {
         return JS_EXCEPTION;
     }
@@ -2426,7 +2436,6 @@ ngx_qjs_fetch_flag_set(JSContext *cx, const 
ngx_qjs_entry_t *entries,
      JSValue object, const char *prop)
 {
     JSValue                value;
-    ngx_int_t              rc;
     ngx_str_t              flag;
     const ngx_qjs_entry_t  *e;
 
@@ -2440,9 +2449,9 @@ ngx_qjs_fetch_flag_set(JSContext *cx, const 
ngx_qjs_entry_t *entries,
         return entries[0].value;
     }
 
-    rc = ngx_qjs_string(cx, value, &flag);
+    flag.data = (u_char *) JS_ToCStringLen(cx, &flag.len, value);
     JS_FreeValue(cx, value);
-    if (rc != NGX_OK) {
+    if (flag.data == NULL) {
         return NGX_ERROR;
     }
 
@@ -2450,6 +2459,7 @@ ngx_qjs_fetch_flag_set(JSContext *cx, const 
ngx_qjs_entry_t *entries,
         if (flag.len == e->name.len
             && ngx_strncasecmp(e->name.data, flag.data, flag.len) == 0)
         {
+            JS_FreeCString(cx, (const char *) flag.data);
             return e->value;
         }
     }
@@ -2457,6 +2467,8 @@ ngx_qjs_fetch_flag_set(JSContext *cx, const 
ngx_qjs_entry_t *entries,
     JS_ThrowInternalError(cx, "unknown %s type: %.*s", prop,
                           (int) flag.len, flag.data);
 
+    JS_FreeCString(cx, (const char *) flag.data);
+
     return NGX_ERROR;
 }
 
diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c
index 13b685e5..cb44aa1f 100644
--- a/nginx/ngx_stream_js_module.c
+++ b/nginx/ngx_stream_js_module.c
@@ -2085,9 +2085,10 @@ ngx_stream_qjs_ext_log(JSContext *cx, JSValueConst 
this_val, int argc,
 
 
 static const ngx_stream_qjs_event_t *
-ngx_stream_qjs_event(ngx_stream_session_t *s, JSContext *cx, ngx_str_t *event)
+ngx_stream_qjs_event(ngx_stream_session_t *s, JSContext *cx, JSValue name)
 {
     ngx_uint_t            i, n, type;
+    ngx_str_t             event;
     ngx_stream_js_ctx_t  *ctx;
 
     static const ngx_stream_qjs_event_t events[] = {
@@ -2116,14 +2117,19 @@ ngx_stream_qjs_event(ngx_stream_session_t *s, JSContext 
*cx, ngx_str_t *event)
         },
     };
 
+    event.data = (u_char *) JS_ToCStringLen(cx, &event.len, name);
+    if (event.data == NULL) {
+        return NULL;
+    }
+
     ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
 
     i = 0;
     n = sizeof(events) / sizeof(events[0]);
 
     while (i < n) {
-        if (event->len == events[i].name.len
-            && ngx_memcmp(event->data, events[i].name.data, event->len)
+        if (event.len == events[i].name.len
+            && ngx_memcmp(event.data, events[i].name.data, event.len)
                == 0)
         {
             break;
@@ -2134,10 +2140,13 @@ ngx_stream_qjs_event(ngx_stream_session_t *s, JSContext 
*cx, ngx_str_t *event)
 
     if (i == n) {
         (void) JS_ThrowInternalError(cx, "unknown event \"%.*s\"",
-                                     (int) event->len, event->data);
+                                     (int) event.len, event.data);
+        JS_FreeCString(cx, (char *) event.data);
         return NULL;
     }
 
+    JS_FreeCString(cx, (char *) event.data);
+
     ctx->events[events[i].id].data_type = events[i].data_type;
 
     for (n = 0; n < NGX_JS_EVENT_MAX; n++) {
@@ -2157,7 +2166,6 @@ static JSValue
 ngx_stream_qjs_ext_on(JSContext *cx, JSValueConst this_val, int argc,
     JSValueConst *argv)
 {
-    ngx_str_t                      name;
     ngx_stream_js_ctx_t           *ctx;
     ngx_stream_qjs_session_t      *ses;
     const ngx_stream_qjs_event_t  *e;
@@ -2169,18 +2177,14 @@ ngx_stream_qjs_ext_on(JSContext *cx, JSValueConst 
this_val, int argc,
 
     ctx = ngx_stream_get_module_ctx(ses->session, ngx_stream_js_module);
 
-    if (ngx_qjs_string(cx, argv[0], &name) != NGX_OK) {
-        return JS_EXCEPTION;
-    }
-
-    e = ngx_stream_qjs_event(ses->session, cx, &name);
+    e = ngx_stream_qjs_event(ses->session, cx, argv[0]);
     if (e == NULL) {
         return JS_EXCEPTION;
     }
 
     if (JS_IsFunction(cx, ngx_qjs_arg(ctx->events[e->id].function))) {
         return JS_ThrowInternalError(cx, "event handler \"%s\" is already set",
-                                     name.data);
+                                     e->name.data);
     }
 
     if (!JS_IsFunction(cx, argv[1])) {
@@ -2200,7 +2204,6 @@ static JSValue
 ngx_stream_qjs_ext_off(JSContext *cx, JSValueConst this_val, int argc,
     JSValueConst *argv)
 {
-    ngx_str_t                      name;
     ngx_stream_js_ctx_t           *ctx;
     ngx_stream_session_t          *s;
     const ngx_stream_qjs_event_t  *e;
@@ -2212,11 +2215,7 @@ ngx_stream_qjs_ext_off(JSContext *cx, JSValueConst 
this_val, int argc,
 
     ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
 
-    if (ngx_qjs_string(cx, argv[0], &name) != NGX_OK) {
-        return JS_EXCEPTION;
-    }
-
-    e = ngx_stream_qjs_event(s, cx, &name);
+    e = ngx_stream_qjs_event(s, cx, argv[0]);
     if (e == NULL) {
         return JS_EXCEPTION;
     }
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to