-
Notifications
You must be signed in to change notification settings - Fork 30k
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
n-api: avoid crash in napi_escape_scope() #13651
Conversation
V8 will crash if escape is called twice on the same scope. Add checks to avoid crashing if napi_escape_scope() is called to try and do this. Add test that tries to call napi_create_scope() twice.
src/node_api.cc
Outdated
explicit EscapableHandleScopeWrapper(v8::Isolate* isolate) : scope(isolate) {} | ||
explicit EscapableHandleScopeWrapper(v8::Isolate* isolate) : | ||
scope(isolate), escapeCalled(false) {} | ||
bool escapeAllreadyCalled(void) { |
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.
Already
src/node_api.cc
Outdated
return scope.Escape(handle); | ||
} | ||
|
||
private: | ||
v8::EscapableHandleScope scope; | ||
bool escapeCalled; |
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.
Private members should have an underscore prefix. At least that is the style used in other classes in this file.
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.
LGTM with nits addressed.
Pushed commit to address comments: CI run: https://ci.nodejs.org/job/node-test-pull-request/8667/ |
src/node_api.cc
Outdated
return scope.Escape(handle); | ||
} | ||
|
||
private: | ||
v8::EscapableHandleScope scope; | ||
bool escapeCalled; | ||
bool _escapeCalled; |
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.
just an extremely minor nit... in various places in core we use _
as a suffix on private fields, in others we seem to use it as a prefix. It would be great to have consistency there.
src/node_api.cc
Outdated
scope(isolate), _escapeCalled(false) {} | ||
bool escapeAlreadyCalled(void) { | ||
return _escapeCalled; | ||
} |
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.
Style issues: method should be bool escape_called() const {
, the data member should be escape_called_
.
src/node_api_types.h
Outdated
@@ -67,6 +67,7 @@ typedef enum { | |||
napi_generic_failure, | |||
napi_pending_exception, | |||
napi_cancelled, | |||
napi_escape_called_twice, |
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.
If this enum is public, then inserting a field changes the ABI.
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.
It is public. At this point since we are experimental it may be ok, but more generally we have to be able to add new error codes so assuming adding to an enum cannot preserve the abi we will have to define our errors in a different way.
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.
@jasongin can you think of any alternative to changing the enums to #defines ? We definitely need to be able to add new errors to the list as we expand or update the api.
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.
How does adding an enum value change the ABI?
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.
Adding a value is okay, inserting it in the middle is not; it changes subsequent values. You're kind of painted in a corner here because of napi_status_last
.
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.
Maybe napi_status_last
should be removed, or changed to a #define
?
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.
A #define
has the same issue: its value is fixed at compile time. If there is no real use case for napi_status_last
, I'd remove it.
Pushed change to address comments. Would like to separate issue fixing use of enum for error code to a follow on PR as we should also look if there are any other instances of the same issue and then fix them and any other code that needs to be modified when we change how errors codes are returned together. Given that we are still in experimental I think even if we stick with the enum adding the new error at this point is probably ok. @bnoordhuis |
I think the best way forward is to remove napi_status_last. I'll do that unless I hear other suggestions. |
@mhdawson I agree. We can always replace it with some |
Pushed commit to remove napi_status_last. Given existing approvals will assume I can land if I don't hear any objections before tomorrow. |
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.
LGTM modulo style nits.
src/node_api.cc
Outdated
@@ -156,14 +156,20 @@ class HandleScopeWrapper { | |||
// across different versions. | |||
class EscapableHandleScopeWrapper { | |||
public: | |||
explicit EscapableHandleScopeWrapper(v8::Isolate* isolate) : scope(isolate) {} | |||
explicit EscapableHandleScopeWrapper(v8::Isolate* isolate) : | |||
scope(isolate), escape_called_(false) {} |
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.
Minuscule style nit: the colon should go on the next line and have 4 spaces of indent.
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.
fixed.
src/node_api.cc
Outdated
static_assert( | ||
(sizeof (error_messages) / sizeof (*error_messages)) == napi_status_last, | ||
(sizeof (error_messages) / sizeof (*error_messages)) == |
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.
Aside: is there a reason this doesn't use arraysize()
?
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.
don't think so, I'll change.
napi_value NewScopeEscapeTwice(napi_env env, napi_callback_info info) { | ||
napi_escapable_handle_scope scope; | ||
napi_value output = NULL; | ||
napi_value escapee = NULL; |
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.
nullptr
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 C, not C++.
pushed commit to address comments. CI run: https://ci.nodejs.org/job/node-test-pull-request/8775/ |
src/node_api.cc
Outdated
@@ -746,10 +754,14 @@ napi_status napi_get_last_error_info(napi_env env, | |||
CHECK_ENV(env); | |||
CHECK_ARG(env, result); | |||
|
|||
// you must udpate this assert to reference the last message |
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.
typo: update
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.
Thanks will fix. I wish I could type :)
Ci good landing. |
Landed as 3e18c49 |
V8 will crash if escape is called twice on the same scope. Add checks to avoid crashing if napi_escape_scope() is called to try and do this. Add test that tries to call napi_create_scope() twice. PR-URL: #13651 Reviewed-By: Jason Ginchereau <jasongin@microsoft.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
V8 will crash if escape is called twice on the same scope. Add checks to avoid crashing if napi_escape_scope() is called to try and do this. Add test that tries to call napi_create_scope() twice. PR-URL: #13651 Reviewed-By: Jason Ginchereau <jasongin@microsoft.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
V8 will crash if escape is called twice on the same scope. Add checks to avoid crashing if napi_escape_scope() is called to try and do this. Add test that tries to call napi_create_scope() twice. PR-URL: nodejs#13651 Reviewed-By: Jason Ginchereau <jasongin@microsoft.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
V8 will crash if escape is called twice on the same scope. Add checks to avoid crashing if napi_escape_scope() is called to try and do this. Add test that tries to call napi_create_scope() twice. Backport-PR-URL: #19447 PR-URL: #13651 Reviewed-By: Jason Ginchereau <jasongin@microsoft.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
V8 will crash if escape is called twice on the same
scope.
Add checks to avoid crashing if napi_escape_scope() is
called to try and do this.
Add test that tries to call napi_create_scope() twice.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
n-api