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())));