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: https://github.com/nodejs/node/pull/44324
Fixes: https://github.com/nodejs/node/issues/44287
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Chengzhong Wu 2022-08-28 23:36:46 +08:00 committed by GitHub
parent 547f453491
commit 3370e7c53a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 3 deletions

View File

@ -556,6 +556,19 @@ Maybe<bool> InitializeContextRuntime(Local<Context> 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<bool> InitializeMainContextForSnapshot(Local<Context> 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<bool>();

View File

@ -958,6 +958,16 @@ const SnapshotData* SnapshotBuilder::GetEmbeddedSnapshotData() {
)";
}
// Reset context settings that need to be initialized again after
// deserialization.
static void ResetContextSettingsBeforeSnapshot(Local<Context> 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<intptr_t>& SnapshotBuilder::CollectExternalReferences() {
@ -1053,6 +1063,7 @@ int SnapshotBuilder::Generate(SnapshotData* out,
if (base_context.IsEmpty()) {
return BOOTSTRAP_ERROR;
}
ResetContextSettingsBeforeSnapshot(base_context);
Local<Context> 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

View File

@ -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);

View File

@ -0,0 +1,7 @@
'use strict';
require('../common');
const assert = require('assert');
// Verify that eval is allowed by default.
assert.strictEqual(eval('"eval"'), 'eval');