-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
src: log warning on process.binding('natives') #2741
Changes from 2 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 |
---|---|---|
|
@@ -59,6 +59,7 @@ | |
#include <string.h> | ||
#include <sys/types.h> | ||
|
||
#include <algorithm> | ||
#include <string> | ||
#include <vector> | ||
|
||
|
@@ -123,6 +124,7 @@ using v8::PromiseRejectMessage; | |
using v8::PropertyCallbackInfo; | ||
using v8::ScriptOrigin; | ||
using v8::SealHandleScope; | ||
using v8::StackTrace; | ||
using v8::String; | ||
using v8::TryCatch; | ||
using v8::Uint32Array; | ||
|
@@ -1659,35 +1661,6 @@ static void ReportException(Environment* env, const TryCatch& try_catch) { | |
} | ||
|
||
|
||
// Executes a str within the current v8 context. | ||
static Local<Value> ExecuteString(Environment* env, | ||
Local<String> source, | ||
Local<String> filename) { | ||
EscapableHandleScope scope(env->isolate()); | ||
TryCatch try_catch(env->isolate()); | ||
|
||
// try_catch must be nonverbose to disable FatalException() handler, | ||
// we will handle exceptions ourself. | ||
try_catch.SetVerbose(false); | ||
|
||
ScriptOrigin origin(filename); | ||
MaybeLocal<v8::Script> script = | ||
v8::Script::Compile(env->context(), source, &origin); | ||
if (script.IsEmpty()) { | ||
ReportException(env, try_catch); | ||
exit(3); | ||
} | ||
|
||
Local<Value> result = script.ToLocalChecked()->Run(); | ||
if (result.IsEmpty()) { | ||
ReportException(env, try_catch); | ||
exit(4); | ||
} | ||
|
||
return scope.Escape(result); | ||
} | ||
|
||
|
||
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
|
||
|
@@ -2543,6 +2516,21 @@ void ClearFatalExceptionHandlers(Environment* env) { | |
} | ||
|
||
|
||
int GetCallerScriptId(v8::Isolate* isolate) { | ||
auto options = StackTrace::kScriptId; | ||
auto stack_trace = StackTrace::CurrentStackTrace(isolate, 1, options); | ||
if (stack_trace->GetFrameCount() > 0) | ||
return stack_trace->GetFrame(0)->GetScriptId(); | ||
return Message::kNoScriptIdInfo; | ||
} | ||
|
||
|
||
inline bool IsInternalScriptId(Environment* env, int script_id) { | ||
auto ids = env->internal_script_ids(); | ||
return ids->end() != std::find(ids->begin(), ids->end(), script_id); | ||
} | ||
|
||
|
||
static void Binding(const FunctionCallbackInfo<Value>& args) { | ||
Environment* env = Environment::GetCurrent(args); | ||
|
||
|
@@ -2581,9 +2569,26 @@ static void Binding(const FunctionCallbackInfo<Value>& args) { | |
DefineConstants(env->isolate(), exports); | ||
cache->Set(module, exports); | ||
} else if (!strcmp(*module_v, "natives")) { | ||
auto caller_script_id = GetCallerScriptId(env->isolate()); | ||
if (!IsInternalScriptId(env, caller_script_id)) { | ||
// graceful-fs < 4 evals process.binding('natives').fs, which prohibits | ||
// using internal modules in that module. Encourage people to upgrade. | ||
auto pid = getpid(); | ||
fprintf(stderr, | ||
"(node:%d) process.binding('natives') is deprecated.\n", pid); | ||
fprintf(stderr, | ||
"(node:%d) If you use graceful-fs < 4, please update.\n", pid); | ||
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.
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. Another question: do we need to specifically note graceful-fs here? It's not the only package that uses 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. Flashback: #2741 (comment) 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. @bnoordhuis yes, but see the list at #2741 (comment), that wasn't considered back then. Also, graceful-fs@2 and graceful-fs@3 usage significantly decreased in past months. 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. I guess I could check if the caller is graceful-fs and customize the error based on that but meh. I have to be selective with my time in the next few weeks so I'm probably not going to expend too much effort on this PR. 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. If you don't have the time to work on it, I am willing to take it over. |
||
auto stack_trace = StackTrace::CurrentStackTrace(env->isolate(), 12); | ||
for (int i = 0, n = stack_trace->GetFrameCount(); i < n; i += 1) { | ||
Local<v8::StackFrame> frame = stack_trace->GetFrame(i); | ||
node::Utf8Value name(env->isolate(), frame->GetScriptName()); | ||
fprintf(stderr, | ||
"(node:%d) at %s:%d\n", pid, *name, frame->GetLineNumber()); | ||
} | ||
fflush(stderr); | ||
} | ||
exports = Object::New(env->isolate()); | ||
DefineJavaScript(env, exports); | ||
cache->Set(module, exports); | ||
} else { | ||
char errmsg[1024]; | ||
snprintf(errmsg, | ||
|
@@ -3377,14 +3382,32 @@ void LoadEnvironment(Environment* env) { | |
// 'internal_bootstrap_node_native' is the string containing that source code. | ||
Local<String> script_name = FIXED_ONE_BYTE_STRING(env->isolate(), | ||
"bootstrap_node.js"); | ||
Local<Value> f_value = ExecuteString(env, MainSource(env), script_name); | ||
ScriptOrigin origin(script_name); | ||
Local<v8::Script> script; | ||
auto maybe_script = | ||
v8::Script::Compile(env->context(), MainSource(env), &origin); | ||
if (!maybe_script.ToLocal(&script)) { | ||
ReportException(env, try_catch); | ||
exit(3); | ||
} | ||
|
||
auto internal_script_ids = env->internal_script_ids(); | ||
CHECK(internal_script_ids->empty()); | ||
internal_script_ids->push_back(script->GetUnboundScript()->GetId()); | ||
|
||
Local<Value> result = script->Run(); | ||
if (result.IsEmpty()) { | ||
ReportException(env, try_catch); | ||
exit(4); | ||
} | ||
|
||
if (try_catch.HasCaught()) { | ||
ReportException(env, try_catch); | ||
exit(10); | ||
} | ||
// The bootstrap_node.js file returns a function 'f' | ||
CHECK(f_value->IsFunction()); | ||
Local<Function> f = Local<Function>::Cast(f_value); | ||
CHECK(result->IsFunction()); | ||
Local<Function> f = Local<Function>::Cast(result); | ||
|
||
// Now we call 'f' with the 'process' variable that we've built up with | ||
// all our bindings. Inside bootstrap_node.js we'll take care of | ||
|
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.
This is not accurate any more, they evaded that, and it now reevalutes internal modules with more dark magic, internal API usage, and relying on implementation details.