Skip to content

Commit d31113e

Browse files
trivikraduh95
authored andcommitted
sqlite: check database state before calling SQLite
Check whether the database is open in enableLoadExtension() and setAuthorizer() before passing the connection to SQLite. This prevents calls after close() from terminating the process and makes them throw ERR_INVALID_STATE instead. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: codex:gpt-5.6-sol PR-URL: #64812 Fixes: #64811 Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com> Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
1 parent 7adc5a4 commit d31113e

3 files changed

Lines changed: 31 additions & 2 deletions

File tree

src/node_sqlite.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,7 +2396,10 @@ void DatabaseSync::EnableLoadExtension(
23962396
const FunctionCallbackInfo<Value>& args) {
23972397
DatabaseSync* db;
23982398
ASSIGN_OR_RETURN_UNWRAP(&db, args.This());
2399-
auto isolate = args.GetIsolate();
2399+
Environment* env = Environment::GetCurrent(args);
2400+
THROW_AND_RETURN_ON_BAD_STATE(env, !db->IsOpen(), "database is not open");
2401+
2402+
Isolate* isolate = env->isolate();
24002403
if (!args[0]->IsBoolean()) {
24012404
THROW_ERR_INVALID_ARG_TYPE(isolate,
24022405
"The \"allow\" argument must be a boolean.");
@@ -2424,7 +2427,7 @@ void DatabaseSync::EnableDefensive(const FunctionCallbackInfo<Value>& args) {
24242427
Environment* env = Environment::GetCurrent(args);
24252428
THROW_AND_RETURN_ON_BAD_STATE(env, !db->IsOpen(), "database is not open");
24262429

2427-
auto isolate = args.GetIsolate();
2430+
Isolate* isolate = env->isolate();
24282431
if (!args[0]->IsBoolean()) {
24292432
THROW_ERR_INVALID_ARG_TYPE(isolate,
24302433
"The \"active\" argument must be a boolean.");
@@ -2475,6 +2478,8 @@ void DatabaseSync::SetAuthorizer(const FunctionCallbackInfo<Value>& args) {
24752478
DatabaseSync* db;
24762479
ASSIGN_OR_RETURN_UNWRAP(&db, args.This());
24772480
Environment* env = Environment::GetCurrent(args);
2481+
THROW_AND_RETURN_ON_BAD_STATE(env, !db->IsOpen(), "database is not open");
2482+
24782483
Isolate* isolate = env->isolate();
24792484

24802485
if (args[0]->IsNull()) {

test/parallel/test-sqlite-authz.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,4 +275,16 @@ suite('DatabaseSync.prototype.setAuthorizer()', () => {
275275
message: /The "callback" argument must be a function/
276276
});
277277
});
278+
279+
it('throws if database is not open', () => {
280+
const db = new DatabaseSync(':memory:');
281+
db.close();
282+
283+
assert.throws(() => {
284+
db.setAuthorizer(() => constants.SQLITE_OK);
285+
}, {
286+
code: 'ERR_INVALID_STATE',
287+
message: 'database is not open',
288+
});
289+
});
278290
});

test/parallel/test-sqlite-config.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,15 @@ test('throws if options.defensive is provided but is not a boolean', (t) => {
6161
message: 'The "options.defensive" argument must be a boolean.',
6262
});
6363
});
64+
65+
test('enableLoadExtension() throws if database is not open', (t) => {
66+
const db = new DatabaseSync(':memory:', { allowExtension: true });
67+
db.close();
68+
69+
t.assert.throws(() => {
70+
db.enableLoadExtension(false);
71+
}, {
72+
code: 'ERR_INVALID_STATE',
73+
message: 'database is not open',
74+
});
75+
});

0 commit comments

Comments
 (0)