Skip to content

Commit 3370e7c

Browse files
authored
src: restore context default IsCodeGenerationFromStringsAllowed value
Context's default IsCodeGenerationFromStringsAllowed value can be changed by v8 flag `--disallow-code-generation-from-strings`. Restore the value at runtime when delegating the code generation validation to `node::ModifyCodeGenerationFromStrings`. The context's settings are serialized in the snapshot. Reset the setting values to its default values before the serialization so that it can be correctly re-initialized after deserialization at runtime. PR-URL: #44324 Fixes: #44287 Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 547f453 commit 3370e7c

4 files changed

+45
-3
lines changed

src/api/environment.cc

+16-3
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,19 @@ Maybe<bool> InitializeContextRuntime(Local<Context> context) {
556556
Isolate* isolate = context->GetIsolate();
557557
HandleScope handle_scope(isolate);
558558

559+
// When `IsCodeGenerationFromStringsAllowed` is true, V8 takes the fast path
560+
// and ignores the ModifyCodeGenerationFromStrings callback. Set it to false
561+
// to delegate the code generation validation to
562+
// node::ModifyCodeGenerationFromStrings.
563+
// The `IsCodeGenerationFromStringsAllowed` can be refreshed by V8 according
564+
// to the runtime flags, propagate the value to the embedder data.
565+
bool is_code_generation_from_strings_allowed =
566+
context->IsCodeGenerationFromStringsAllowed();
567+
context->AllowCodeGenerationFromStrings(false);
568+
context->SetEmbedderData(
569+
ContextEmbedderIndex::kAllowCodeGenerationFromStrings,
570+
is_code_generation_from_strings_allowed ? True(isolate) : False(isolate));
571+
559572
if (per_process::cli_options->disable_proto == "") {
560573
return Just(true);
561574
}
@@ -648,11 +661,11 @@ Maybe<bool> InitializeMainContextForSnapshot(Local<Context> context) {
648661
Isolate* isolate = context->GetIsolate();
649662
HandleScope handle_scope(isolate);
650663

651-
context->AllowCodeGenerationFromStrings(false);
652-
context->SetEmbedderData(
653-
ContextEmbedderIndex::kAllowCodeGenerationFromStrings, True(isolate));
664+
// Initialize the default values.
654665
context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration,
655666
True(isolate));
667+
context->SetEmbedderData(
668+
ContextEmbedderIndex::kAllowCodeGenerationFromStrings, True(isolate));
656669

657670
if (InitializeBaseContextForSnapshot(context).IsNothing()) {
658671
return Nothing<bool>();

src/node_snapshotable.cc

+13
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,16 @@ const SnapshotData* SnapshotBuilder::GetEmbeddedSnapshotData() {
958958
)";
959959
}
960960

961+
// Reset context settings that need to be initialized again after
962+
// deserialization.
963+
static void ResetContextSettingsBeforeSnapshot(Local<Context> context) {
964+
// Reset the AllowCodeGenerationFromStrings flag to true (default value) so
965+
// that it can be re-initialized with v8 flag
966+
// --disallow-code-generation-from-strings and recognized in
967+
// node::InitializeContextRuntime.
968+
context->AllowCodeGenerationFromStrings(true);
969+
}
970+
961971
Mutex SnapshotBuilder::snapshot_data_mutex_;
962972

963973
const std::vector<intptr_t>& SnapshotBuilder::CollectExternalReferences() {
@@ -1053,6 +1063,7 @@ int SnapshotBuilder::Generate(SnapshotData* out,
10531063
if (base_context.IsEmpty()) {
10541064
return BOOTSTRAP_ERROR;
10551065
}
1066+
ResetContextSettingsBeforeSnapshot(base_context);
10561067

10571068
Local<Context> main_context = NewContext(isolate);
10581069
if (main_context.IsEmpty()) {
@@ -1121,6 +1132,8 @@ int SnapshotBuilder::Generate(SnapshotData* out,
11211132
size_str.c_str());
11221133
}
11231134
#endif
1135+
1136+
ResetContextSettingsBeforeSnapshot(main_context);
11241137
}
11251138

11261139
// Global handles to the contexts can't be disposed before the
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Flags: --disallow-code-generation-from-strings
2+
'use strict';
3+
4+
require('../common');
5+
const assert = require('assert');
6+
7+
// Verify that v8 option --disallow-code-generation-from-strings is still
8+
// respected
9+
assert.throws(() => eval('"eval"'), EvalError);

test/parallel/test-eval.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
6+
// Verify that eval is allowed by default.
7+
assert.strictEqual(eval('"eval"'), 'eval');

0 commit comments

Comments
 (0)