diff --git a/src/api/environment.cc b/src/api/environment.cc index 2cecae617f07f7..53581405bac712 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -556,6 +556,19 @@ Maybe InitializeContextRuntime(Local context) { Isolate* isolate = context->GetIsolate(); HandleScope handle_scope(isolate); + // When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path + // and ignores the ModifyCodeGenerationFromStrings callback. Set it to false + // to delegate the code generation validation to + // node::ModifyCodeGenerationFromStrings. + // The `IsCodeGenerationFromStringsAllowed` can be refreshed by V8 according + // to the runtime flags, propagate the value to the embedder data. + bool is_code_generation_from_strings_allowed = + context->IsCodeGenerationFromStringsAllowed(); + context->AllowCodeGenerationFromStrings(false); + context->SetEmbedderData( + ContextEmbedderIndex::kAllowCodeGenerationFromStrings, + is_code_generation_from_strings_allowed ? True(isolate) : False(isolate)); + if (per_process::cli_options->disable_proto == "") { return Just(true); } @@ -648,11 +661,11 @@ Maybe InitializeMainContextForSnapshot(Local context) { Isolate* isolate = context->GetIsolate(); HandleScope handle_scope(isolate); - context->AllowCodeGenerationFromStrings(false); - context->SetEmbedderData( - ContextEmbedderIndex::kAllowCodeGenerationFromStrings, True(isolate)); + // Initialize the default values. context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration, True(isolate)); + context->SetEmbedderData( + ContextEmbedderIndex::kAllowCodeGenerationFromStrings, True(isolate)); if (InitializeBaseContextForSnapshot(context).IsNothing()) { return Nothing(); diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 9aac5dd7f31d0c..98660f7d171209 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -958,6 +958,16 @@ const SnapshotData* SnapshotBuilder::GetEmbeddedSnapshotData() { )"; } +// Reset context settings that need to be initialized again after +// deserialization. +static void ResetContextSettingsBeforeSnapshot(Local context) { + // Reset the AllowCodeGenerationFromStrings flag to true (default value) so + // that it can be re-initialized with v8 flag + // --disallow-code-generation-from-strings and recognized in + // node::InitializeContextRuntime. + context->AllowCodeGenerationFromStrings(true); +} + Mutex SnapshotBuilder::snapshot_data_mutex_; const std::vector& SnapshotBuilder::CollectExternalReferences() { @@ -1053,6 +1063,7 @@ int SnapshotBuilder::Generate(SnapshotData* out, if (base_context.IsEmpty()) { return BOOTSTRAP_ERROR; } + ResetContextSettingsBeforeSnapshot(base_context); Local main_context = NewContext(isolate); if (main_context.IsEmpty()) { @@ -1121,6 +1132,8 @@ int SnapshotBuilder::Generate(SnapshotData* out, size_str.c_str()); } #endif + + ResetContextSettingsBeforeSnapshot(main_context); } // Global handles to the contexts can't be disposed before the diff --git a/test/parallel/test-eval-disallow-code-generation-from-strings.js b/test/parallel/test-eval-disallow-code-generation-from-strings.js new file mode 100644 index 00000000000000..c9c0c60b773ce8 --- /dev/null +++ b/test/parallel/test-eval-disallow-code-generation-from-strings.js @@ -0,0 +1,9 @@ +// Flags: --disallow-code-generation-from-strings +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Verify that v8 option --disallow-code-generation-from-strings is still +// respected +assert.throws(() => eval('"eval"'), EvalError); diff --git a/test/parallel/test-eval.js b/test/parallel/test-eval.js new file mode 100644 index 00000000000000..46a4b7c54689b1 --- /dev/null +++ b/test/parallel/test-eval.js @@ -0,0 +1,7 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Verify that eval is allowed by default. +assert.strictEqual(eval('"eval"'), 'eval');