fix: potential async_hooks crash in NotifyWindowRestore on Windows (#40576)

* fix: potential async_hooks crash in NotifyWindowRestore on Windows

* fix: don't use CallbackScope for Error objects
This commit is contained in:
Shelley Vohr 2024-01-26 19:53:07 +01:00 committed by GitHub
parent db2bf1a0d1
commit 8104c7908a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 10 deletions

View file

@ -32,13 +32,26 @@ void AutoUpdater::OnError(const std::string& message) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Object> wrapper;
// We do not use gin::EmitEvent here because we do not want to
// put this in its own CallbackScope and delegate to Node.js'
// specialized handling for Error objects.
if (GetWrapper(isolate).ToLocal(&wrapper)) {
auto error = v8::Exception::Error(gin::StringToV8(isolate, message));
gin_helper::EmitEvent(
isolate, wrapper, "error",
error->ToObject(isolate->GetCurrentContext()).ToLocalChecked(),
// Message is also emitted to keep compatibility with old code.
message);
std::vector<v8::Local<v8::Value>> args = {
gin::StringToV8(isolate, "error"),
gin::ConvertToV8(
isolate,
error->ToObject(isolate->GetCurrentContext()).ToLocalChecked()),
gin::StringToV8(isolate, message),
};
gin_helper::MicrotasksScope microtasks_scope(
isolate, wrapper->GetCreationContextChecked()->GetMicrotaskQueue(),
true);
node::MakeCallback(isolate, wrapper, "emit", args.size(), args.data(),
{0, 0});
}
}

View file

@ -13,6 +13,14 @@ v8::Local<v8::Value> CallMethodWithArgs(v8::Isolate* isolate,
v8::Local<v8::Object> obj,
const char* method,
ValueVector* args) {
// Only set up the node::CallbackScope if there's a node environment.
std::unique_ptr<node::CallbackScope> callback_scope;
if (node::Environment::GetCurrent(isolate)) {
v8::HandleScope handle_scope(isolate);
callback_scope = std::make_unique<node::CallbackScope>(
isolate, v8::Object::New(isolate), node::async_context{0, 0});
}
// Perform microtask checkpoint after running JavaScript.
gin_helper::MicrotasksScope microtasks_scope(
isolate, obj->GetCreationContextChecked()->GetMicrotaskQueue(), true);

View file

@ -61,12 +61,10 @@ void InvokeIpcCallback(v8::Local<v8::Context> context,
// Only set up the node::CallbackScope if there's a node environment.
// Sandboxed renderers don't have a node environment.
node::Environment* env = node::Environment::GetCurrent(context);
std::unique_ptr<node::CallbackScope> callback_scope;
if (env) {
node::async_context async_context = {};
callback_scope = std::make_unique<node::CallbackScope>(isolate, ipcNative,
async_context);
if (node::Environment::GetCurrent(context)) {
callback_scope = std::make_unique<node::CallbackScope>(
isolate, ipcNative, node::async_context{0, 0});
}
auto callback_key = gin::ConvertToV8(isolate, callback_name)