Skip to content

Commit

Permalink
src: do not unnecessarily re-assign uv handle data
Browse files Browse the repository at this point in the history
a555be2 re-assigned `async_.data` to indicate success
or failure of the constructor. As the `HandleWrap` implementation
uses that field to access the `HandleWrap` instance from the
libuv handle, this introduced two issues:

- It implicitly assumed that casting
  `MessagePort*` → `void*` → `HandleWrap*` would be valid.
- It made the `HandleWrap::OnClose()` function fail with a
  `nullptr` dereference if the constructor did fail.

In particular, the second issue made
test/parallel/test-worker-cleanexit-with-moduleload.js` crash at
least once in CI.

Since re-assigning `async_.data` isn’t actually necessary here
(only a leftover from earlier versions of that commit), fix this by
using a local variable instead, and add a `CHECK` that provides better
error messages for this type of issue in the future.

Refs: #31605

PR-URL: #31696
Reviewed-By: Santiago Gimeno <[email protected]>
Reviewed-By: David Carlier <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: James M Snell <[email protected]>
  • Loading branch information
addaleax authored and targos committed Apr 28, 2020
1 parent 2fc72ca commit 38de40a
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/handle_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ HandleWrap::HandleWrap(Environment* env,


void HandleWrap::OnClose(uv_handle_t* handle) {
CHECK_NOT_NULL(handle->data);
BaseObjectPtr<HandleWrap> wrap { static_cast<HandleWrap*>(handle->data) };
wrap->Detach();

Expand Down
9 changes: 4 additions & 5 deletions src/node_messaging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,9 @@ MessagePort::MessagePort(Environment* env,
CHECK_EQ(uv_async_init(env->event_loop(),
&async_,
onmessage), 0);
async_.data = nullptr; // Reset later to indicate success of the constructor.
auto cleanup = OnScopeLeave([&]() {
if (async_.data == nullptr) Close();
});
// Reset later to indicate success of the constructor.
bool succeeded = false;
auto cleanup = OnScopeLeave([&]() { if (!succeeded) Close(); });

Local<Value> fn;
if (!wrap->Get(context, env->oninit_symbol()).ToLocal(&fn))
Expand All @@ -535,7 +534,7 @@ MessagePort::MessagePort(Environment* env,
return;
emit_message_fn_.Reset(env->isolate(), emit_message_fn);

async_.data = static_cast<void*>(this);
succeeded = true;
Debug(this, "Created message port");
}

Expand Down

0 comments on commit 38de40a

Please sign in to comment.