Uh oh!
There was an error while loading. Please reload this page.
sqlite: validate connection after reading options - #65591
Conversation
Signed-off-by: Lazizbek Ergashev <lazerg2@gmail.com>
nodejs-github-bot
commented
Aug 27, 2026
Review requested:
|
Signed-off-by: Lazizbek Ergashev <lazerg2@gmail.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@## main #65591 +/- ##
=======================================
Coverage 90.07% 90.08% =======================================
Files 751 751 Lines 254875 254895 +20 Branches 48108 48137 +29 =======================================
+ Hits 229579 229617 +38 + Misses 16466 16459 -7 + Partials 8830 8819 -11
🚀 New features to boost your workflow:
|
| @@ -1738,6 +1718,10 @@ void DatabaseSync::Prepare(const FunctionCallbackInfo<Value>& args) { | |||
| } | |||
| } | |||
| // Reading the options bag can run a getter that closes the connection. | |||
There was a problem hiding this comment.
Maybe we can just check only once after arguments validation
There was a problem hiding this comment.
Thanks for the review. I kept the early check on purpose, and the fix that landed in #65595 made the same call.
Checking only after argument validation changes which error wins when the database is already closed. Two existing tests depend on the current order:
test/parallel/test-sqlite-database-sync.js:379callsdb.prepare()with no arguments on a closed database and expectsERR_INVALID_STATE. Without the early check the missingsqlargument throwsERR_INVALID_ARG_TYPEfirst.test/parallel/test-sqlite-serialize.js:182callsdb.deserialize(new Uint8Array(0))on a closed database and expectsERR_INVALID_STATE. Without the early check it becomesERR_INVALID_ARG_VALUE. I applied that change and rebuilt to confirm it.
The early check also rejects the call while an authorizer callback is running, so the options getters never run re-entrantly there.
Since #65595 covers the same six functions, I am closing this PR.
lazerg
commented
Sep 3, 2026
#65595 landed the same fix for One site is still unguarded on constdb=newDatabaseSync(':memory:');constsql=db.createTagStore(10);conststrings=['SELECT ',''];Object.defineProperty(strings,0,{get(){db.close();return'SELECT ';}});sql.get(strings,1);// ERR_SQLITE_ERROR: out of memoryThe guard needs to be written by hand there, because |
function(),aggregate(),deserialize(),prepare(),applyChangeset(),backup()and the tag store check that the connection is open before reading their options bag. A getter on that object can calldb.close(), leaving the rest of the call running against a null connection. Five of them segfault;prepare()and the tag store reportERR_SQLITE_ERROR: out of memoryinstead.The open check now runs again once the options have been read, right before the connection reaches SQLite. Re-checking keeps the current error precedence, which parsing the options up front the way
createSession()does would change.Fixes: #65586