-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
process: introduce codeGenerationFromString event #48295
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,7 @@ typedef int mode_t; | |
|
||
namespace node { | ||
|
||
using errors::TryCatchScope; | ||
using v8::Array; | ||
using v8::ArrayBuffer; | ||
using v8::CFunction; | ||
|
@@ -463,6 +464,49 @@ static void ReallyExit(const FunctionCallbackInfo<Value>& args) { | |
env->Exit(code); | ||
} | ||
|
||
static void CodeGenerationFromStringsAllowed( | ||
const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
Local<Context> context = env->context(); | ||
Local<Value> allow_code_gen = context->GetEmbedderData( | ||
ContextEmbedderIndex::kAllowCodeGenerationFromStrings); | ||
bool codegen_allowed = | ||
allow_code_gen->IsUndefined() || allow_code_gen->IsTrue(); | ||
args.GetReturnValue().Set(codegen_allowed); | ||
} | ||
|
||
static v8::Maybe<v8::ModifyCodeGenerationFromStringsResult> CodeGenCallback( | ||
Local<Context> context, | ||
Local<Value> source, | ||
bool is_code_like) { | ||
Environment* env = Environment::GetCurrent(context); | ||
ProcessEmit(env, "codeGenerationFromString", source); | ||
|
||
// returning {true, val} where val.IsEmpty() makes v8 | ||
// use the orignal value passed to `eval` which does not impact | ||
// calls as `eval({})` | ||
return v8::Just({true, v8::MaybeLocal<v8::String>()}); | ||
} | ||
|
||
static void SetEmitCodeGenFromStringEvent( | ||
const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
Isolate* isolate = args.GetIsolate(); | ||
Local<Context> context = env->context(); | ||
|
||
CHECK(args[0]->IsBoolean()); | ||
|
||
bool val = args[0]->BooleanValue(args.GetIsolate()); | ||
if (val) { | ||
context->AllowCodeGenerationFromStrings(false); | ||
isolate->SetModifyCodeGenerationFromStringsCallback(CodeGenCallback); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would replace the I also noticed that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the callback can be installed when needed (either with the cli flag |
||
} else { | ||
// This is enough to disable the handler. V8 will not call it anymore | ||
// until set back to false | ||
context->AllowCodeGenerationFromStrings(true); | ||
} | ||
} | ||
|
||
namespace process { | ||
|
||
BindingData::BindingData(Realm* realm, v8::Local<v8::Object> object) | ||
|
@@ -600,6 +644,10 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, | |
SetMethod(isolate, target, "reallyExit", ReallyExit); | ||
SetMethodNoSideEffect(isolate, target, "uptime", Uptime); | ||
SetMethod(isolate, target, "patchProcessObject", PatchProcessObject); | ||
SetMethod(isolate, target, "codeGenerationFromStringsAllowed", | ||
CodeGenerationFromStringsAllowed); | ||
SetMethod(isolate, target, "setEmitCodeGenFromStringEvent", | ||
SetEmitCodeGenFromStringEvent); | ||
} | ||
|
||
static void CreatePerContextProperties(Local<Object> target, | ||
|
@@ -637,6 +685,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |
registry->Register(ReallyExit); | ||
registry->Register(Uptime); | ||
registry->Register(PatchProcessObject); | ||
registry->Register(CodeGenerationFromStringsAllowed); | ||
registry->Register(SetEmitCodeGenFromStringEvent); | ||
} | ||
|
||
} // namespace process | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const assert = require('assert'); | ||
|
||
const item = { foo: 0 }; | ||
eval('++item.foo'); | ||
|
||
assert.strictEqual(item.foo, 1); | ||
|
||
// Basic eval() test | ||
process.on('codeGenerationFromString', common.mustCall((code) => { | ||
assert.strictEqual(code, 'item.foo++'); | ||
})); | ||
|
||
eval('item.foo++'); | ||
assert.strictEqual(item.foo, 2); | ||
|
||
process.removeAllListeners('codeGenerationFromString'); | ||
|
||
// Basic Function() test | ||
process.on('codeGenerationFromString', common.mustCall((code) => { | ||
assert.strictEqual(code, '(function anonymous(a,b\n) {\nreturn a + b\n})'); | ||
})); | ||
|
||
const fct = new Function('a', 'b', 'return a + b'); | ||
assert.strictEqual(fct(1, 2), 3); | ||
|
||
process.removeAllListeners('codeGenerationFromString'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.