Merged
Conversation
9f95be0 to
6aeb463
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug: In the old code,
currQueryResult->Unref()was called unconditionally at the start.Unref()decrementsthe NAPI reference count on the JS wrapper object. If this was the last reference, the JS object could be garbage
collected, which would destroy the C++
NodeQueryResultobject (since it's an ObjectWrapper). After that, accessingcurrQueryResult->connectionandcurrQueryResult->databasewould be a use-after-free.The fix:
- When
nextOwnedResult == nullptr, we just return undefined. We release/unref first, then callback. That'sfine.
- When
nextOwnedResult != nullptr, we FIRST copy out connection and database (both are std::shared_ptr, socopying increments their ref counts and is safe). Then we create the new instance. Only THEN do we
ReleaseAsyncUse() and Unref() the current result. This ensures we don't access currQueryResult after it could be
freed.