Skip to content

src: improve error handling in buffer and dotenv #57189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,14 @@ void SlowCopy(const FunctionCallbackInfo<Value>& args) {
ArrayBufferViewContents<char> source(args[0]);
SPREAD_BUFFER_ARG(args[1].As<Object>(), target);

const auto target_start = args[2]->Uint32Value(env->context()).ToChecked();
const auto source_start = args[3]->Uint32Value(env->context()).ToChecked();
const auto to_copy = args[4]->Uint32Value(env->context()).ToChecked();
uint32_t target_start;
uint32_t source_start;
uint32_t to_copy;
if (!args[2]->Uint32Value(env->context()).To(&target_start) ||
!args[3]->Uint32Value(env->context()).To(&source_start) ||
!args[4]->Uint32Value(env->context()).To(&to_copy)) {
return;
}

memmove(target_data + target_start, source.data() + source_start, to_copy);
args.GetReturnValue().Set(to_copy);
Expand Down Expand Up @@ -634,7 +639,9 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
return;
}

str_obj = args[1]->ToString(env->context()).ToLocalChecked();
if (!args[1]->ToString(env->context()).ToLocal(&str_obj)) {
return;
}
enc = ParseEncoding(env->isolate(), args[4], UTF8);

// Can't use StringBytes::Write() in all cases. For example if attempting
Expand Down Expand Up @@ -697,7 +704,10 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {

THROW_AND_RETURN_IF_NOT_STRING(env, args[0], "argument");

Local<String> str = args[0]->ToString(env->context()).ToLocalChecked();
Local<String> str;
if (!args[0]->ToString(env->context()).ToLocal(&str)) {
return;
}

size_t offset = 0;
size_t max_length = 0;
Expand Down Expand Up @@ -1238,10 +1248,12 @@ void GetZeroFillToggle(const FunctionCallbackInfo<Value>& args) {
ab = ArrayBuffer::New(env->isolate(), std::move(backing));
}

ab->SetPrivate(
env->context(),
env->untransferable_object_private_symbol(),
True(env->isolate())).Check();
if (ab->SetPrivate(env->context(),
env->untransferable_object_private_symbol(),
True(env->isolate()))
.IsNothing()) {
return;
}

args.GetReturnValue().Set(Uint32Array::New(ab, 0, 1));
}
Expand All @@ -1252,7 +1264,9 @@ void DetachArrayBuffer(const FunctionCallbackInfo<Value>& args) {
Local<ArrayBuffer> buf = args[0].As<ArrayBuffer>();
if (buf->IsDetachable()) {
std::shared_ptr<BackingStore> store = buf->GetBackingStore();
buf->Detach(Local<Value>()).Check();
if (buf->Detach(Local<Value>()).IsNothing()) {
return;
}
args.GetReturnValue().Set(ArrayBuffer::New(env->isolate(), store));
}
}
Expand Down Expand Up @@ -1461,7 +1475,10 @@ void SlowWriteString(const FunctionCallbackInfo<Value>& args) {

THROW_AND_RETURN_IF_NOT_STRING(env, args[1], "argument");

Local<String> str = args[1]->ToString(env->context()).ToLocalChecked();
Local<String> str;
if (!args[1]->ToString(env->context()).ToLocal(&str)) {
return;
}

size_t offset = 0;
size_t max_length = 0;
Expand Down
63 changes: 30 additions & 33 deletions src/node_dotenv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@

namespace node {

using v8::EscapableHandleScope;
using v8::JustVoid;
using v8::Local;
using v8::NewStringType;
using v8::Maybe;
using v8::MaybeLocal;
using v8::Nothing;
using v8::Object;
using v8::String;
using v8::Value;

std::vector<Dotenv::env_file_data> Dotenv::GetDataFromArgs(
const std::vector<std::string>& args) {
Expand Down Expand Up @@ -59,50 +64,42 @@ std::vector<Dotenv::env_file_data> Dotenv::GetDataFromArgs(
return env_files;
}

void Dotenv::SetEnvironment(node::Environment* env) {
auto isolate = env->isolate();
Maybe<void> Dotenv::SetEnvironment(node::Environment* env) {
Local<Value> name;
Local<Value> val;
auto context = env->context();

for (const auto& entry : store_) {
auto key = entry.first;
auto value = entry.second;

auto existing = env->env_vars()->Get(key.data());

auto existing = env->env_vars()->Get(entry.first.data());
if (!existing.has_value()) {
env->env_vars()->Set(
isolate,
v8::String::NewFromUtf8(
isolate, key.data(), NewStringType::kNormal, key.size())
.ToLocalChecked(),
v8::String::NewFromUtf8(
isolate, value.data(), NewStringType::kNormal, value.size())
.ToLocalChecked());
if (!ToV8Value(context, entry.first).ToLocal(&name) ||
!ToV8Value(context, entry.second).ToLocal(&val)) {
return Nothing<void>();
}
env->env_vars()->Set(env->isolate(), name.As<String>(), val.As<String>());
}
}

return JustVoid();
}

Local<Object> Dotenv::ToObject(Environment* env) const {
MaybeLocal<Object> Dotenv::ToObject(Environment* env) const {
EscapableHandleScope scope(env->isolate());
Local<Object> result = Object::New(env->isolate());

Local<Value> name;
Local<Value> val;
auto context = env->context();

for (const auto& entry : store_) {
auto key = entry.first;
auto value = entry.second;

result
->Set(
env->context(),
v8::String::NewFromUtf8(
env->isolate(), key.data(), NewStringType::kNormal, key.size())
.ToLocalChecked(),
v8::String::NewFromUtf8(env->isolate(),
value.data(),
NewStringType::kNormal,
value.size())
.ToLocalChecked())
.Check();
if (!ToV8Value(context, entry.first).ToLocal(&name) ||
!ToV8Value(context, entry.second).ToLocal(&val) ||
result->Set(context, name, val).IsNothing()) {
return MaybeLocal<Object>();
}
}

return result;
return scope.Escape(result);
}

// Removes space characters (spaces, tabs and newlines) from
Expand Down
4 changes: 2 additions & 2 deletions src/node_dotenv.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class Dotenv {
void ParseContent(const std::string_view content);
ParseResult ParsePath(const std::string_view path);
void AssignNodeOptionsIfAvailable(std::string* node_options) const;
void SetEnvironment(Environment* env);
v8::Local<v8::Object> ToObject(Environment* env) const;
v8::Maybe<void> SetEnvironment(Environment* env);
v8::MaybeLocal<v8::Object> ToObject(Environment* env) const;

static std::vector<env_file_data> GetDataFromArgs(
const std::vector<std::string>& args);
Expand Down
2 changes: 1 addition & 1 deletion src/node_process_methods.cc
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ static void LoadEnvFile(const v8::FunctionCallbackInfo<v8::Value>& args) {

switch (dotenv.ParsePath(path)) {
case dotenv.ParseResult::Valid: {
dotenv.SetEnvironment(env);
USE(dotenv.SetEnvironment(env));
break;
}
case dotenv.ParseResult::InvalidContent: {
Expand Down
5 changes: 4 additions & 1 deletion src/node_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,10 @@ static void ParseEnv(const FunctionCallbackInfo<Value>& args) {
Utf8Value content(env->isolate(), args[0]);
Dotenv dotenv{};
dotenv.ParseContent(content.ToStringView());
args.GetReturnValue().Set(dotenv.ToObject(env));
Local<Object> obj;
if (dotenv.ToObject(env).ToLocal(&obj)) {
args.GetReturnValue().Set(obj);
}
}

static void GetCallSites(const FunctionCallbackInfo<Value>& args) {
Expand Down
Loading