Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/node_buffer.cc9
-rw-r--r--src/node_crypto.cc9
-rw-r--r--src/node_encoding.cc2
-rw-r--r--src/node_file.cc5
-rw-r--r--src/spawn_sync.cc125
-rw-r--r--src/spawn_sync.h12
-rw-r--r--src/stream_base.cc21
-rw-r--r--src/string_bytes.cc42
-rw-r--r--src/string_bytes.h37
-rw-r--r--src/util.cc4
10 files changed, 149 insertions, 117 deletions
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 9a280f7c127..d2cb79d4145 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -236,7 +236,9 @@ MaybeLocal<Object> New(Isolate* isolate,
enum encoding enc) {
EscapableHandleScope scope(isolate);
- const size_t length = StringBytes::Size(isolate, string, enc);
+ size_t length;
+ if (!StringBytes::Size(isolate, string, enc).To(&length))
+ return Local<Object>();
size_t actual = 0;
char* data = nullptr;
@@ -828,7 +830,8 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
const size_t haystack_length = (enc == UCS2) ?
ts_obj_length &~ 1 : ts_obj_length; // NOLINT(whitespace/operators)
- const size_t needle_length = StringBytes::Size(isolate, needle, enc);
+ size_t needle_length;
+ if (!StringBytes::Size(isolate, needle, enc).To(&needle_length)) return;
int64_t opt_offset = IndexOfOffset(haystack_length,
offset_i64,
@@ -868,7 +871,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
if (IsBigEndian()) {
StringBytes::InlineDecoder decoder;
- decoder.Decode(env, needle, args[3], UCS2);
+ if (decoder.Decode(env, needle, args[3], UCS2).IsNothing()) return;
const uint16_t* decoded_string =
reinterpret_cast<const uint16_t*>(decoder.out());
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index c28ae3098bf..2063fb948d1 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -3062,7 +3062,8 @@ void CipherBase::Update(const FunctionCallbackInfo<Value>& args) {
// Only copy the data if we have to, because it's a string
if (args[0]->IsString()) {
StringBytes::InlineDecoder decoder;
- if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8))
+ if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8)
+ .FromMaybe(false))
return;
r = cipher->Update(decoder.out(), decoder.size(), &out, &out_len);
} else {
@@ -3252,7 +3253,8 @@ void Hmac::HmacUpdate(const FunctionCallbackInfo<Value>& args) {
bool r = false;
if (args[0]->IsString()) {
StringBytes::InlineDecoder decoder;
- if (decoder.Decode(env, args[0].As<String>(), args[1], UTF8)) {
+ if (decoder.Decode(env, args[0].As<String>(), args[1], UTF8)
+ .FromMaybe(false)) {
r = hmac->HmacUpdate(decoder.out(), decoder.size());
}
} else {
@@ -3359,7 +3361,8 @@ void Hash::HashUpdate(const FunctionCallbackInfo<Value>& args) {
bool r = true;
if (args[0]->IsString()) {
StringBytes::InlineDecoder decoder;
- if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8)) {
+ if (!decoder.Decode(env, args[0].As<String>(), args[1], UTF8)
+ .FromMaybe(false)) {
args.GetReturnValue().Set(false);
return;
}
diff --git a/src/node_encoding.cc b/src/node_encoding.cc
index d5c6bcab488..21d32750972 100644
--- a/src/node_encoding.cc
+++ b/src/node_encoding.cc
@@ -121,7 +121,7 @@ ssize_t DecodeBytes(Isolate* isolate,
enum encoding encoding) {
HandleScope scope(isolate);
- return StringBytes::Size(isolate, val, encoding);
+ return StringBytes::Size(isolate, val, encoding).FromMaybe(-1);
}
// Returns number of bytes written.
diff --git a/src/node_file.cc b/src/node_file.cc
index 70e57e5a7f1..aff6f27682a 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -1675,7 +1675,7 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
if (is_async) { // write(fd, string, pos, enc, req)
CHECK_NOT_NULL(req_wrap_async);
- len = StringBytes::StorageSize(env->isolate(), value, enc);
+ if (!StringBytes::StorageSize(env->isolate(), value, enc).To(&len)) return;
FSReqBase::FSReqBuffer& stack_buffer =
req_wrap_async->Init("write", len, enc);
// StorageSize may return too large a char, so correct the actual length
@@ -1703,7 +1703,8 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
FSReqWrapSync req_wrap_sync;
FSReqBase::FSReqBuffer stack_buffer;
if (buf == nullptr) {
- len = StringBytes::StorageSize(env->isolate(), value, enc);
+ if (!StringBytes::StorageSize(env->isolate(), value, enc).To(&len))
+ return;
stack_buffer.AllocateSufficientStorage(len + 1);
// StorageSize may return too large a char, so correct the actual length
// by the write size
diff --git a/src/spawn_sync.cc b/src/spawn_sync.cc
index ba29aaeef03..77449b9569d 100644
--- a/src/spawn_sync.cc
+++ b/src/spawn_sync.cc
@@ -37,7 +37,11 @@ using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Integer;
using v8::Isolate;
+using v8::Just;
using v8::Local;
+using v8::Maybe;
+using v8::MaybeLocal;
+using v8::Nothing;
using v8::Null;
using v8::Number;
using v8::Object;
@@ -372,7 +376,8 @@ void SyncProcessRunner::Spawn(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
env->PrintSyncTrace();
SyncProcessRunner p(env);
- Local<Value> result = p.Run(args[0]);
+ Local<Value> result;
+ if (!p.Run(args[0]).ToLocal(&result)) return;
args.GetReturnValue().Set(result);
}
@@ -430,22 +435,21 @@ Environment* SyncProcessRunner::env() const {
return env_;
}
-
-Local<Object> SyncProcessRunner::Run(Local<Value> options) {
+MaybeLocal<Object> SyncProcessRunner::Run(Local<Value> options) {
EscapableHandleScope scope(env()->isolate());
CHECK_EQ(lifecycle_, kUninitialized);
- TryInitializeAndRunLoop(options);
+ Maybe<bool> r = TryInitializeAndRunLoop(options);
CloseHandlesAndDeleteLoop();
+ if (r.IsNothing()) return MaybeLocal<Object>();
Local<Object> result = BuildResultObject();
return scope.Escape(result);
}
-
-void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
+Maybe<bool> SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
int r;
// There is no recovery from failure inside TryInitializeAndRunLoop - the
@@ -454,18 +458,24 @@ void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
lifecycle_ = kInitialized;
uv_loop_ = new uv_loop_t;
- if (uv_loop_ == nullptr)
- return SetError(UV_ENOMEM);
+ if (uv_loop_ == nullptr) {
+ SetError(UV_ENOMEM);
+ return Just(false);
+ }
CHECK_EQ(uv_loop_init(uv_loop_), 0);
- r = ParseOptions(options);
- if (r < 0)
- return SetError(r);
+ if (!ParseOptions(options).To(&r)) return Nothing<bool>();
+ if (r < 0) {
+ SetError(r);
+ return Just(false);
+ }
if (timeout_ > 0) {
r = uv_timer_init(uv_loop_, &uv_timer_);
- if (r < 0)
- return SetError(r);
+ if (r < 0) {
+ SetError(r);
+ return Just(false);
+ }
uv_unref(reinterpret_cast<uv_handle_t*>(&uv_timer_));
@@ -477,22 +487,28 @@ void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
// which implicitly stops it, so there is no risk that the timeout callback
// runs when the process didn't start.
r = uv_timer_start(&uv_timer_, KillTimerCallback, timeout_, 0);
- if (r < 0)
- return SetError(r);
+ if (r < 0) {
+ SetError(r);
+ return Just(false);
+ }
}
uv_process_options_.exit_cb = ExitCallback;
r = uv_spawn(uv_loop_, &uv_process_, &uv_process_options_);
- if (r < 0)
- return SetError(r);
+ if (r < 0) {
+ SetError(r);
+ return Just(false);
+ }
uv_process_.data = this;
for (uint32_t i = 0; i < stdio_count_; i++) {
SyncProcessStdioPipe* h = stdio_pipes_[i].get();
if (h != nullptr) {
r = h->Start();
- if (r < 0)
- return SetPipeError(r);
+ if (r < 0) {
+ SetPipeError(r);
+ return Just(false);
+ }
}
}
@@ -503,6 +519,7 @@ void SyncProcessRunner::TryInitializeAndRunLoop(Local<Value> options) {
// If we get here the process should have exited.
CHECK_GE(exit_status_, 0);
+ return Just(true);
}
@@ -724,46 +741,41 @@ Local<Array> SyncProcessRunner::BuildOutputArray() {
return scope.Escape(js_output);
}
-
-int SyncProcessRunner::ParseOptions(Local<Value> js_value) {
+Maybe<int> SyncProcessRunner::ParseOptions(Local<Value> js_value) {
HandleScope scope(env()->isolate());
int r;
- if (!js_value->IsObject())
- return UV_EINVAL;
+ if (!js_value->IsObject()) return Just<int>(UV_EINVAL);
Local<Context> context = env()->context();
Local<Object> js_options = js_value.As<Object>();
Local<Value> js_file =
js_options->Get(context, env()->file_string()).ToLocalChecked();
- r = CopyJsString(js_file, &file_buffer_);
- if (r < 0)
- return r;
+ if (!CopyJsString(js_file, &file_buffer_).To(&r)) return Nothing<int>();
+ if (r < 0) return Just(r);
uv_process_options_.file = file_buffer_;
Local<Value> js_args =
js_options->Get(context, env()->args_string()).ToLocalChecked();
- r = CopyJsStringArray(js_args, &args_buffer_);
- if (r < 0)
- return r;
+ if (!CopyJsStringArray(js_args, &args_buffer_).To(&r)) return Nothing<int>();
+ if (r < 0) return Just(r);
uv_process_options_.args = reinterpret_cast<char**>(args_buffer_);
Local<Value> js_cwd =
js_options->Get(context, env()->cwd_string()).ToLocalChecked();
if (IsSet(js_cwd)) {
- r = CopyJsString(js_cwd, &cwd_buffer_);
- if (r < 0)
- return r;
+ if (!CopyJsString(js_cwd, &cwd_buffer_).To(&r)) return Nothing<int>();
+ if (r < 0) return Just(r);
uv_process_options_.cwd = cwd_buffer_;
}
Local<Value> js_env_pairs =
js_options->Get(context, env()->env_pairs_string()).ToLocalChecked();
if (IsSet(js_env_pairs)) {
- r = CopyJsStringArray(js_env_pairs, &env_buffer_);
- if (r < 0)
- return r;
+ if (!CopyJsStringArray(js_env_pairs, &env_buffer_).To(&r))
+ return Nothing<int>();
+ if (r < 0) return Just(r);
uv_process_options_.env = reinterpret_cast<char**>(env_buffer_);
}
@@ -827,10 +839,9 @@ int SyncProcessRunner::ParseOptions(Local<Value> js_value) {
Local<Value> js_stdio =
js_options->Get(context, env()->stdio_string()).ToLocalChecked();
r = ParseStdioOptions(js_stdio);
- if (r < 0)
- return r;
+ if (r < 0) return Just(r);
- return 0;
+ return Just(0);
}
@@ -970,9 +981,8 @@ bool SyncProcessRunner::IsSet(Local<Value> value) {
return !value->IsUndefined() && !value->IsNull();
}
-
-int SyncProcessRunner::CopyJsString(Local<Value> js_value,
- const char** target) {
+Maybe<int> SyncProcessRunner::CopyJsString(Local<Value> js_value,
+ const char** target) {
Isolate* isolate = env()->isolate();
Local<String> js_string;
size_t size, written;
@@ -980,12 +990,14 @@ int SyncProcessRunner::CopyJsString(Local<Value> js_value,
if (js_value->IsString())
js_string = js_value.As<String>();
- else
- js_string = js_value->ToString(env()->isolate()->GetCurrentContext())
- .ToLocalChecked();
+ else if (!js_value->ToString(env()->isolate()->GetCurrentContext())
+ .ToLocal(&js_string))
+ return Nothing<int>();
// Include space for null terminator byte.
- size = StringBytes::StorageSize(isolate, js_string, UTF8) + 1;
+ if (!StringBytes::StorageSize(isolate, js_string, UTF8).To(&size))
+ return Nothing<int>();
+ size += 1;
buffer = new char[size];
@@ -993,12 +1005,11 @@ int SyncProcessRunner::CopyJsString(Local<Value> js_value,
buffer[written] = '\0';
*target = buffer;
- return 0;
+ return Just(0);
}
-
-int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
- char** target) {
+Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
+ char** target) {
Isolate* isolate = env()->isolate();
Local<Array> js_array;
uint32_t length;
@@ -1006,8 +1017,7 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
char** list;
char* buffer;
- if (!js_value->IsArray())
- return UV_EINVAL;
+ if (!js_value->IsArray()) return Just<int>(UV_EINVAL);
Local<Context> context = env()->context();
js_array = js_value.As<Array>()->Clone().As<Array>();
@@ -1025,15 +1035,22 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
for (uint32_t i = 0; i < length; i++) {
auto value = js_array->Get(context, i).ToLocalChecked();
- if (!value->IsString())
+ if (!value->IsString()) {
+ Local<String> string;
+ if (!value->ToString(env()->isolate()->GetCurrentContext())
+ .ToLocal(&string))
+ return Nothing<int>();
js_array
->Set(context,
i,
value->ToString(env()->isolate()->GetCurrentContext())
.ToLocalChecked())
.FromJust();
+ }
- data_size += StringBytes::StorageSize(isolate, value, UTF8) + 1;
+ Maybe<size_t> maybe_size = StringBytes::StorageSize(isolate, value, UTF8);
+ if (maybe_size.IsNothing()) return Nothing<int>();
+ data_size += maybe_size.FromJust() + 1;
data_size = ROUND_UP(data_size, sizeof(void*));
}
@@ -1057,7 +1074,7 @@ int SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
list[length] = nullptr;
*target = buffer;
- return 0;
+ return Just(0);
}
diff --git a/src/spawn_sync.h b/src/spawn_sync.h
index fed14532960..adb2618cc5f 100644
--- a/src/spawn_sync.h
+++ b/src/spawn_sync.h
@@ -152,8 +152,8 @@ class SyncProcessRunner {
inline Environment* env() const;
- v8::Local<v8::Object> Run(v8::Local<v8::Value> options);
- void TryInitializeAndRunLoop(v8::Local<v8::Value> options);
+ v8::MaybeLocal<v8::Object> Run(v8::Local<v8::Value> options);
+ v8::Maybe<bool> TryInitializeAndRunLoop(v8::Local<v8::Value> options);
void CloseHandlesAndDeleteLoop();
void CloseStdioPipes();
@@ -172,7 +172,7 @@ class SyncProcessRunner {
v8::Local<v8::Object> BuildResultObject();
v8::Local<v8::Array> BuildOutputArray();
- int ParseOptions(v8::Local<v8::Value> js_value);
+ v8::Maybe<int> ParseOptions(v8::Local<v8::Value> js_value);
int ParseStdioOptions(v8::Local<v8::Value> js_value);
int ParseStdioOption(int child_fd, v8::Local<v8::Object> js_stdio_option);
@@ -184,8 +184,10 @@ class SyncProcessRunner {
inline int AddStdioInheritFD(uint32_t child_fd, int inherit_fd);
static bool IsSet(v8::Local<v8::Value> value);
- int CopyJsString(v8::Local<v8::Value> js_value, const char** target);
- int CopyJsStringArray(v8::Local<v8::Value> js_value, char** target);
+ v8::Maybe<int> CopyJsString(v8::Local<v8::Value> js_value,
+ const char** target);
+ v8::Maybe<int> CopyJsStringArray(v8::Local<v8::Value> js_value,
+ char** target);
static void ExitCallback(uv_process_t* handle,
int64_t exit_status,
diff --git a/src/stream_base.cc b/src/stream_base.cc
index bb46ea1febb..f429f3593fd 100644
--- a/src/stream_base.cc
+++ b/src/stream_base.cc
@@ -108,11 +108,12 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
enum encoding encoding = ParseEncoding(env->isolate(),
chunks->Get(i * 2 + 1));
size_t chunk_size;
- if (encoding == UTF8 && string->Length() > 65535)
- chunk_size = StringBytes::Size(env->isolate(), string, encoding);
- else
- chunk_size = StringBytes::StorageSize(env->isolate(), string, encoding);
-
+ if (encoding == UTF8 && string->Length() > 65535 &&
+ !StringBytes::Size(env->isolate(), string, encoding).To(&chunk_size))
+ return 0;
+ else if (!StringBytes::StorageSize(env->isolate(), string, encoding)
+ .To(&chunk_size))
+ return 0;
storage_size += chunk_size;
}
@@ -214,10 +215,12 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
// For UTF8 strings that are very long, go ahead and take the hit for
// computing their actual size, rather than tripling the storage.
size_t storage_size;
- if (enc == UTF8 && string->Length() > 65535)
- storage_size = StringBytes::Size(env->isolate(), string, enc);
- else
- storage_size = StringBytes::StorageSize(env->isolate(), string, enc);
+ if (enc == UTF8 && string->Length() > 65535 &&
+ !StringBytes::Size(env->isolate(), string, enc).To(&storage_size))
+ return 0;
+ else if (!StringBytes::StorageSize(env->isolate(), string, enc)
+ .To(&storage_size))
+ return 0;
if (storage_size > INT_MAX)
return UV_ENOBUFS;
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
index 82d699db9a8..c38f368d418 100644
--- a/src/string_bytes.cc
+++ b/src/string_bytes.cc
@@ -41,8 +41,11 @@ namespace node {
using v8::HandleScope;
using v8::Isolate;
+using v8::Just;
using v8::Local;
+using v8::Maybe;
using v8::MaybeLocal;
+using v8::Nothing;
using v8::String;
using v8::Value;
@@ -399,19 +402,20 @@ bool StringBytes::IsValidString(Local<String> string,
// Quick and dirty size calculation
// Will always be at least big enough, but may have some extra
// UTF8 can be as much as 3x the size, Base64 can have 1-2 extra bytes
-size_t StringBytes::StorageSize(Isolate* isolate,
- Local<Value> val,
- enum encoding encoding) {
+Maybe<size_t> StringBytes::StorageSize(Isolate* isolate,
+ Local<Value> val,
+ enum encoding encoding) {
HandleScope scope(isolate);
size_t data_size = 0;
bool is_buffer = Buffer::HasInstance(val);
if (is_buffer && (encoding == BUFFER || encoding == LATIN1)) {
- return Buffer::Length(val);
+ return Just(Buffer::Length(val));
}
- Local<String> str =
- val->ToString(isolate->GetCurrentContext()).ToLocalChecked();
+ Local<String> str;
+ if (!val->ToString(isolate->GetCurrentContext()).ToLocal(&str))
+ return Nothing<size_t>();
switch (encoding) {
case ASCII:
@@ -445,40 +449,40 @@ size_t StringBytes::StorageSize(Isolate* isolate,
break;
}
- return data_size;
+ return Just(data_size);
}
-
-size_t StringBytes::Size(Isolate* isolate,
- Local<Value> val,
- enum encoding encoding) {
+Maybe<size_t> StringBytes::Size(Isolate* isolate,
+ Local<Value> val,
+ enum encoding encoding) {
HandleScope scope(isolate);
if (Buffer::HasInstance(val) && (encoding == BUFFER || encoding == LATIN1))
- return Buffer::Length(val);
+ return Just(Buffer::Length(val));
- Local<String> str =
- val->ToString(isolate->GetCurrentContext()).ToLocalChecked();
+ Local<String> str;
+ if (!val->ToString(isolate->GetCurrentContext()).ToLocal(&str))
+ return Nothing<size_t>();
switch (encoding) {
case ASCII:
case LATIN1:
- return str->Length();
+ return Just<size_t>(str->Length());
case BUFFER:
case UTF8:
- return str->Utf8Length(isolate);
+ return Just<size_t>(str->Utf8Length(isolate));
case UCS2:
- return str->Length() * sizeof(uint16_t);
+ return Just(str->Length() * sizeof(uint16_t));
case BASE64: {
String::Value value(isolate, str);
- return base64_decoded_size(*value, value.length());
+ return Just(base64_decoded_size(*value, value.length()));
}
case HEX:
- return str->Length() / 2;
+ return Just<size_t>(str->Length() / 2);
}
UNREACHABLE();
diff --git a/src/string_bytes.h b/src/string_bytes.h
index 5f5fcd9fa0f..8280e379877 100644
--- a/src/string_bytes.h
+++ b/src/string_bytes.h
@@ -35,29 +35,26 @@ class StringBytes {
public:
class InlineDecoder : public MaybeStackBuffer<char> {
public:
- inline bool Decode(Environment* env,
- v8::Local<v8::String> string,
- v8::Local<v8::Value> encoding,
- enum encoding _default) {
+ inline v8::Maybe<bool> Decode(Environment* env,
+ v8::Local<v8::String> string,
+ v8::Local<v8::Value> encoding,
+ enum encoding _default) {
enum encoding enc = ParseEncoding(env->isolate(), encoding, _default);
if (!StringBytes::IsValidString(string, enc)) {
env->ThrowTypeError("Bad input string");
- return false;
+ return v8::Just(false);
}
- const size_t storage = StringBytes::StorageSize(env->isolate(),
- string,
- enc);
+ size_t storage;
+ if (!StringBytes::StorageSize(env->isolate(), string, enc).To(&storage))
+ return v8::Nothing<bool>();
AllocateSufficientStorage(storage);
- const size_t length = StringBytes::Write(env->isolate(),
- out(),
- storage,
- string,
- enc);
+ const size_t length =
+ StringBytes::Write(env->isolate(), out(), storage, string, enc);
// No zero terminator is included when using this method.
SetLength(length);
- return true;
+ return v8::Just(true);
}
inline size_t size() const { return length(); }
@@ -71,15 +68,15 @@ class StringBytes {
// Fast, but can be 2 bytes oversized for Base64, and
// as much as triple UTF-8 strings <= 65536 chars in length
- static size_t StorageSize(v8::Isolate* isolate,
- v8::Local<v8::Value> val,
- enum encoding enc);
+ static v8::Maybe<size_t> StorageSize(v8::Isolate* isolate,
+ v8::Local<v8::Value> val,
+ enum encoding enc);
// Precise byte count, but slightly slower for Base64 and
// very much slower for UTF-8
- static size_t Size(v8::Isolate* isolate,
- v8::Local<v8::Value> val,
- enum encoding enc);
+ static v8::Maybe<size_t> Size(v8::Isolate* isolate,
+ v8::Local<v8::Value> val,
+ enum encoding enc);
// Write the bytes from the string or buffer into the char*
// returns the number of bytes written, which will always be
diff --git a/src/util.cc b/src/util.cc
index 44c47f0f916..a9d26fe86ae 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -40,7 +40,9 @@ static void MakeUtf8String(Isolate* isolate,
Local<String> string;
if (!value->ToString(isolate->GetCurrentContext()).ToLocal(&string)) return;
- const size_t storage = StringBytes::StorageSize(isolate, string, UTF8) + 1;
+ size_t storage;
+ if (!StringBytes::StorageSize(isolate, string, UTF8).To(&storage)) return;
+ storage += 1;
target->AllocateSufficientStorage(storage);
const int flags =
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8;