From 53c5a4bfb95ab5b5875ba6795268c2ee789e4bb9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:12:16 +0000 Subject: [PATCH] Add NativeStringContext::free and fix pool allocation in NativeString Agent-Logs-Url: https://github.com/uNetworking/uWebSockets.js/sessions/32b57b77-b272-4971-920c-090468456f40 Co-authored-by: uNetworkingAB <110806833+uNetworkingAB@users.noreply.github.com> --- src/Utilities.h | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Utilities.h b/src/Utilities.h index 0e5c9e8e..9d955752 100644 --- a/src/Utilities.h +++ b/src/Utilities.h @@ -22,6 +22,7 @@ #include #include #include +#include using namespace v8; /* Unfortunately we _have_ to depend on Node.js crap */ @@ -125,20 +126,29 @@ class NativeStringContext { public: char *alloc(size_t size) { if (pool_offset + size > pool.size()) { - pool.resize(pool_offset + size); + return (char *) malloc(size); } char *ptr = pool.data() + pool_offset; pool_offset += size; return ptr; } + + void free(char *ptr) { + if (ptr >= pool.data() && ptr < pool.data() + pool.size()) { + return; + } + ::free(ptr); + } }; class NativeString { char *data; size_t length; bool invalid = false; + bool allocated = false; + NativeStringContext *ctx = nullptr; public: - NativeString(NativeStringContext &ctx, Isolate *isolate, const Local &value) { + NativeString(NativeStringContext &ctx, Isolate *isolate, const Local &value) : ctx(&ctx) { if (value->IsUndefined()) { data = nullptr; length = 0; @@ -154,11 +164,13 @@ public: // utf16: copy and convert to utf8 length = string->Utf8LengthV2(isolate); data = ctx.alloc(length); + allocated = true; string->WriteUtf8V2(isolate, data, length); } #else // Fallback Node.js < 24 length = string->Utf8Length(isolate); data = ctx.alloc(length); + allocated = true; string->WriteUtf8(isolate, data, length, nullptr, String::WriteOptions::NO_NULL_TERMINATION); #endif } else if (value->IsArrayBufferView()) { /* DataView or TypedArray */ @@ -181,6 +193,15 @@ public: } } + ~NativeString() noexcept { + if (allocated) { + ctx->free(data); + } + } + + NativeString(const NativeString &) = delete; + NativeString &operator=(const NativeString &) = delete; + bool isInvalid(const FunctionCallbackInfo &args) { if (invalid) { args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(String::NewFromUtf8(args.GetIsolate(), "Text and data can only be passed by String, ArrayBuffer, SharedArrayBuffer or ArrayBufferView.", NewStringType::kNormal).ToLocalChecked())));