Skip to content

Commit

Permalink
[v16.x backport] src: return Maybe<bool> from InitializeContextRuntime()
Browse files Browse the repository at this point in the history
Signed-off-by: Darshan Sen <darshan.sen@postman.com>

PR-URL: nodejs#39695
Backport-PR-URL: nodejs#39834
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
RaisinTen committed Aug 21, 2021
1 parent 7410d41 commit 2717fe6
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 36 deletions.
123 changes: 90 additions & 33 deletions src/api/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ using v8::Function;
using v8::FunctionCallbackInfo;
using v8::HandleScope;
using v8::Isolate;
using v8::Just;
using v8::Local;
using v8::Maybe;
using v8::MaybeLocal;
using v8::Nothing;
using v8::Null;
using v8::Object;
using v8::ObjectTemplate;
Expand Down Expand Up @@ -523,58 +526,113 @@ void ProtoThrower(const FunctionCallbackInfo<Value>& info) {

// This runs at runtime, regardless of whether the context
// is created from a snapshot.
void InitializeContextRuntime(Local<Context> context) {
Maybe<bool> InitializeContextRuntime(Local<Context> context) {
Isolate* isolate = context->GetIsolate();
HandleScope handle_scope(isolate);

// Delete `Intl.v8BreakIterator`
// https://github.com/nodejs/node/issues/14909
Local<String> intl_string = FIXED_ONE_BYTE_STRING(isolate, "Intl");
Local<String> break_iter_string =
FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");
Local<Value> intl_v;
if (context->Global()->Get(context, intl_string).ToLocal(&intl_v) &&
intl_v->IsObject()) {
Local<Object> intl = intl_v.As<Object>();
intl->Delete(context, break_iter_string).Check();
{
Local<String> intl_string =
FIXED_ONE_BYTE_STRING(isolate, "Intl");
Local<String> break_iter_string =
FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");

Local<Value> intl_v;
if (!context->Global()
->Get(context, intl_string)
.ToLocal(&intl_v)) {
return Nothing<bool>();
}

if (intl_v->IsObject() &&
intl_v.As<Object>()
->Delete(context, break_iter_string)
.IsNothing()) {
return Nothing<bool>();
}
}

// Delete `Atomics.wake`
// https://github.com/nodejs/node/issues/21219
Local<String> atomics_string = FIXED_ONE_BYTE_STRING(isolate, "Atomics");
Local<String> wake_string = FIXED_ONE_BYTE_STRING(isolate, "wake");
Local<Value> atomics_v;
if (context->Global()->Get(context, atomics_string).ToLocal(&atomics_v) &&
atomics_v->IsObject()) {
Local<Object> atomics = atomics_v.As<Object>();
atomics->Delete(context, wake_string).Check();
{
Local<String> atomics_string =
FIXED_ONE_BYTE_STRING(isolate, "Atomics");
Local<String> wake_string =
FIXED_ONE_BYTE_STRING(isolate, "wake");

Local<Value> atomics_v;
if (!context->Global()
->Get(context, atomics_string)
.ToLocal(&atomics_v)) {
return Nothing<bool>();
}

if (atomics_v->IsObject() &&
atomics_v.As<Object>()
->Delete(context, wake_string)
.IsNothing()) {
return Nothing<bool>();
}
}

// Remove __proto__
// https://github.com/nodejs/node/issues/31951
Local<String> object_string = FIXED_ONE_BYTE_STRING(isolate, "Object");
Local<String> prototype_string = FIXED_ONE_BYTE_STRING(isolate, "prototype");
Local<Object> prototype = context->Global()
->Get(context, object_string)
.ToLocalChecked()
.As<Object>()
->Get(context, prototype_string)
.ToLocalChecked()
.As<Object>();
Local<String> proto_string = FIXED_ONE_BYTE_STRING(isolate, "__proto__");
Local<Object> prototype;
{
Local<String> object_string =
FIXED_ONE_BYTE_STRING(isolate, "Object");
Local<String> prototype_string =
FIXED_ONE_BYTE_STRING(isolate, "prototype");

Local<Value> object_v;
if (!context->Global()
->Get(context, object_string)
.ToLocal(&object_v)) {
return Nothing<bool>();
}

Local<Value> prototype_v;
if (!object_v.As<Object>()
->Get(context, prototype_string)
.ToLocal(&prototype_v)) {
return Nothing<bool>();
}

prototype = prototype_v.As<Object>();
}

Local<String> proto_string =
FIXED_ONE_BYTE_STRING(isolate, "__proto__");

if (per_process::cli_options->disable_proto == "delete") {
prototype->Delete(context, proto_string).ToChecked();
if (prototype
->Delete(context, proto_string)
.IsNothing()) {
return Nothing<bool>();
}
} else if (per_process::cli_options->disable_proto == "throw") {
Local<Value> thrower =
Function::New(context, ProtoThrower).ToLocalChecked();
Local<Value> thrower;
if (!Function::New(context, ProtoThrower)
.ToLocal(&thrower)) {
return Nothing<bool>();
}

PropertyDescriptor descriptor(thrower, thrower);
descriptor.set_enumerable(false);
descriptor.set_configurable(true);
prototype->DefineProperty(context, proto_string, descriptor).ToChecked();
if (prototype
->DefineProperty(context, proto_string, descriptor)
.IsNothing()) {
return Nothing<bool>();
}
} else if (per_process::cli_options->disable_proto != "") {
// Validated in ProcessGlobalArgs
FatalError("InitializeContextRuntime()", "invalid --disable-proto mode");
FatalError("InitializeContextRuntime()",
"invalid --disable-proto mode");
}

return Just(true);
}

bool InitializeContextForSnapshot(Local<Context> context) {
Expand Down Expand Up @@ -638,8 +696,7 @@ bool InitializeContext(Local<Context> context) {
return false;
}

InitializeContextRuntime(context);
return true;
return InitializeContextRuntime(context).IsJust();
}

uv_loop_t* GetCurrentEventLoop(Isolate* isolate) {
Expand Down
4 changes: 3 additions & 1 deletion src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
if (ctx.IsEmpty()) return MaybeLocal<Context>();
// Only partially initialize the context - the primordials are left out
// and only initialized when necessary.
InitializeContextRuntime(ctx);
if (InitializeContextRuntime(ctx).IsNothing()) {
return MaybeLocal<Context>();
}

if (ctx.IsEmpty()) {
return MaybeLocal<Context>();
Expand Down
2 changes: 1 addition & 1 deletion src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void SignalExit(int signal, siginfo_t* info, void* ucontext);
std::string GetProcessTitle(const char* default_title);
std::string GetHumanReadableProcessName();

void InitializeContextRuntime(v8::Local<v8::Context>);
v8::Maybe<bool> InitializeContextRuntime(v8::Local<v8::Context> context);
bool InitializePrimordials(v8::Local<v8::Context> context);

class NodeArrayBufferAllocator : public ArrayBufferAllocator {
Expand Down
2 changes: 1 addition & 1 deletion src/node_main_instance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ NodeMainInstance::CreateMainEnvironment(int* exit_code,

CHECK(!context.IsEmpty());
Context::Scope context_scope(context);
InitializeContextRuntime(context);
CHECK(InitializeContextRuntime(context).IsJust());
SetIsolateErrorHandlers(isolate_, {});
env->InitializeMainContext(context, env_info);
#if HAVE_INSPECTOR
Expand Down

0 comments on commit 2717fe6

Please sign in to comment.