[njs] QuickJS: freeing temporary strings.
noreply at nginx.com
noreply at nginx.com
Mon Sep 8 23:00:02 UTC 2025
details: https://github.com/nginx/njs/commit/a9dabca11201f5e56196c876a6b4791e858c0358
branches: master
commit: a9dabca11201f5e56196c876a6b4791e858c0358
user: Dmitry Volyntsev <xeioex at 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;
}
More information about the nginx-devel
mailing list