sqlite: do not leave database open after failed open#63854
Open
anonrig wants to merge 1 commit into
Open
Conversation
When sqlite3_open_v2() fails, SQLite still assigns a database handle in a "sick" state. Such a handle may only be used to retrieve the error and must then be released with sqlite3_close(). Keeping it in connection_ meant that after a failed open(): - isOpen incorrectly reported true, - every method passed the "database is not open" check and called SQLite APIs on the sick handle, which is an API misuse, - registering a user-defined function leaked its user data in builds with SQLITE_ENABLE_API_ARMOR, because SQLite rejects the call before taking ownership of the user data, - open() could not be retried since the database appeared open. Close and reset the connection handle when open() fails at any point so that the database remains closed and open() can be retried. Fixes: nodejs#63831 Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Collaborator
|
Review requested:
|
Collaborator
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.
When
sqlite3_open_v2()fails, SQLite still assigns a database handle in a "sick" state. Such a handle may only be used to retrieve error information and must then be released withsqlite3_close().DatabaseSync::Open()kept the handle inconnection_, so after a failedopen():database.isOpenincorrectly reportedtrue.database.function()anddatabase.aggregate()leaked their user data in builds withSQLITE_ENABLE_API_ARMOR, because SQLite rejects calls on a sick handle withSQLITE_MISUSEbefore taking ownership of the user data. This is the leak reported by LeakSanitizer in the issue.open()could not be retried because the database appeared to be open.This change closes and resets the connection handle when
open()fails at any point, so a failedopen()leaves the database closed, subsequent method calls throwERR_INVALID_STATE, andopen()can be retried once the underlying problem is resolved. Error reporting is unchanged: the error message is read from the sick handle before it is closed.Before (v24.16.0):
Fixes: #63831