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