From: Dmitry Volyntsev Date: Tue, 10 Nov 2026 01:42:56 +0000 (-0800) Subject: QuickJS: add runtime-owned byte storage helpers X-Git-Url: https://git.kaiwu.me/ngx_http_auth_basic_module.html?a=commitdiff_plain;h=ff9760164051ac2606ad96e3bce2ab37ee7c53f0;p=njs.git QuickJS: add runtime-owned byte storage helpers Fetch ownership needs native copies and chain allocations that do not depend on request pools or a surviving JSContext. Provide common helpers for these operations while preserving nginx value conversion semantics. --- diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 5101d92a..a85251b9 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -1769,6 +1769,69 @@ ngx_qjs_header_value(JSContext *cx, ngx_pool_t *pool, JSValueConst val, } +ngx_int_t +ngx_qjs_bytes_copy(JSContext *cx, ngx_str_t *dst, const ngx_str_t *src) +{ + dst->data = js_malloc(cx, njs_max(src->len, 1)); + if (dst->data == NULL) { + return NGX_ERROR; + } + + dst->len = src->len; + + if (src->len != 0) { + ngx_memcpy(dst->data, src->data, src->len); + } + + return NGX_OK; +} + + +ngx_int_t +ngx_qjs_value_bytes_copy(JSContext *cx, JSValueConst value, ngx_str_t *str) +{ + size_t offset, length; + JSValue buffer; + ngx_int_t rc; + ngx_str_t source; + const char *p; + + if (JS_IsNullOrUndefined(value)) { + ngx_str_null(&source); + + return ngx_qjs_bytes_copy(cx, str, &source); + } + + if (!JS_IsString(value)) { + buffer = JS_GetTypedArrayBuffer(cx, value, &offset, &length, NULL); + if (!JS_IsException(buffer)) { + source.data = JS_GetArrayBuffer(cx, &source.len, buffer); + if (source.data != NULL) { + source.data += offset; + source.len = length; + rc = ngx_qjs_bytes_copy(cx, str, &source); + JS_FreeValue(cx, buffer); + + return rc; + } + + JS_FreeValue(cx, buffer); + } + } + + p = JS_ToCStringLen(cx, &source.len, value); + if (p == NULL) { + return NGX_ERROR; + } + + source.data = (u_char *) p; + rc = ngx_qjs_bytes_copy(cx, str, &source); + JS_FreeCString(cx, p); + + return rc; +} + + static void ngx_qjs_timer_handler(ngx_event_t *ev) { diff --git a/nginx/ngx_js.h b/nginx/ngx_js.h index ec1f536a..7d5cd4e0 100644 --- a/nginx/ngx_js.h +++ b/nginx/ngx_js.h @@ -404,6 +404,10 @@ ngx_int_t ngx_qjs_log_exception(ngx_engine_t *e, ngx_log_t *log, ngx_int_t ngx_qjs_integer(JSContext *cx, JSValueConst val, ngx_int_t *n); ngx_int_t ngx_qjs_string(JSContext *cx, ngx_pool_t *pool, JSValueConst val, ngx_str_t *dst); +ngx_int_t ngx_qjs_bytes_copy(JSContext *cx, ngx_str_t *dst, + const ngx_str_t *src); +ngx_int_t ngx_qjs_value_bytes_copy(JSContext *cx, JSValueConst value, + ngx_str_t *str); ngx_int_t ngx_qjs_header_value(JSContext *cx, ngx_pool_t *pool, JSValueConst val, ngx_str_t *dst); diff --git a/src/qjs.c b/src/qjs.c index 99fdd944..4c5e971a 100644 --- a/src/qjs.c +++ b/src/qjs.c @@ -338,6 +338,20 @@ qjs_chb_ctx_free(void *ctx, void *p) } +void * +qjs_chb_rt_alloc(void *rt, size_t size) +{ + return js_malloc_rt(rt, size); +} + + +void +qjs_chb_rt_free(void *rt, void *p) +{ + js_free_rt(rt, p); +} + + JSValue qjs_call_exit_hook(JSContext *ctx) { diff --git a/src/qjs.h b/src/qjs.h index 41df9046..3b89bb71 100644 --- a/src/qjs.h +++ b/src/qjs.h @@ -63,6 +63,8 @@ JSContext *qjs_new_context(JSRuntime *rt, qjs_module_t **addons); JSValue qjs_call_exit_hook(JSContext *ctx); void *qjs_chb_ctx_alloc(void *ctx, size_t size); void qjs_chb_ctx_free(void *ctx, void *p); +void *qjs_chb_rt_alloc(void *rt, size_t size); +void qjs_chb_rt_free(void *rt, void *p); JSValue qjs_new_uint8_array(JSContext *ctx, int argc, JSValueConst *argv);