From 22124b2f305ee152a79471e480a4cba5a7777a93 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Thu, 24 Sep 2026 15:48:09 -0700 Subject: [PATCH] Buffer: check QJS allocation sizes before narrowing Take a 64-bit size in qjs_buffer_alloc() and reject sizes above QJS_BUFFER_MAX_LENGTH before converting them. Previously, a caller holding a wider size had to narrow it to size_t first, which truncated it silently on 32-bit platforms. --- src/qjs.h | 5 ++++- src/qjs_buffer.c | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/qjs.h b/src/qjs.h index 69c593ab..865db0d2 100644 --- a/src/qjs.h +++ b/src/qjs.h @@ -56,6 +56,9 @@ typedef struct { } qjs_module_t; +#define QJS_BUFFER_MAX_LENGTH INT32_MAX + + 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); @@ -66,7 +69,7 @@ JSValue qjs_new_uint8_array(JSContext *ctx, int argc, JSValueConst *argv); JSValue qjs_new_array_buffer(JSContext *cx, uint8_t *src, size_t len); JSValue qjs_new_external_array_buffer(JSContext *cx, uint8_t *src, size_t len, int is_shared); -JSValue qjs_buffer_alloc(JSContext *ctx, size_t size); +JSValue qjs_buffer_alloc(JSContext *ctx, uint64_t size); JSValue qjs_buffer_create(JSContext *ctx, u_char *start, size_t size); JSValue qjs_buffer_chb_alloc(JSContext *ctx, njs_chb_t *chain); diff --git a/src/qjs_buffer.c b/src/qjs_buffer.c index b6125135..ade8559e 100644 --- a/src/qjs_buffer.c +++ b/src/qjs_buffer.c @@ -125,7 +125,7 @@ static qjs_buffer_encoding_t qjs_buffer_encodings[] = static const JSCFunctionListEntry qjs_buffer_constants[] = { - JS_PROP_INT32_DEF("MAX_LENGTH", INT32_MAX, JS_PROP_ENUMERABLE), + JS_PROP_INT32_DEF("MAX_LENGTH", QJS_BUFFER_MAX_LENGTH, JS_PROP_ENUMERABLE), JS_PROP_INT32_DEF("MAX_STRING_LENGTH", 0x3fffffff, JS_PROP_ENUMERABLE), }; @@ -2570,10 +2570,14 @@ qjs_hex_encode_length(JSContext *ctx, const njs_str_t *src) JSValue -qjs_buffer_alloc(JSContext *ctx, size_t size) +qjs_buffer_alloc(JSContext *ctx, uint64_t size) { JSValue ret, proto, value; + if (size > QJS_BUFFER_MAX_LENGTH) { + return JS_ThrowRangeError(ctx, "invalid array buffer length"); + } + value = JS_NewInt64(ctx, size); ret = qjs_new_uint8_array(ctx, 1, &value); -- 2.47.3