sqlite: restore connection state on reopen · nodejs/node@fe76deb · GitHub
Skip to content

Commit fe76deb

Browse files
araujoguiaduh95
authored andcommitted
sqlite: restore connection state on reopen
close() destroys the connection but keeps the DatabaseSync object, and open() did not replay the state held on it. An authorizer set with setAuthorizer() was not reinstalled, silently dropping a deny-all policy. Limits written through db.limits.* reverted to the constructor values. Extension loading was re-enabled from the constructor ceiling rather than the current setting, so the connection flag contradicted a previous enableLoadExtension(false), though loadExtension() itself stayed blocked by its own check. Signed-off-by: Guilherme Araújo <arauujogui@gmail.com> Assisted-by: Claude Code PR-URL: #66042 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent 5f54bc7 commit fe76deb

4 files changed

Lines changed: 71 additions & 12 deletions

File tree

‎src/node_sqlite.cc‎

Lines changed: 18 additions & 6 deletions

‎src/node_sqlite.h‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,13 @@ class DatabaseOpenConfiguration {
139139

140140
inline bool get_enable_defensive() const { return defensive_; }
141141

142-
inline void set_initial_limit(int sqlite_limit_id, int value) {
143-
initial_limits_.at(sqlite_limit_id) = value;
142+
inline void set_limit(int sqlite_limit_id, int value) {
143+
limits_.at(sqlite_limit_id) = value;
144144
}
145145

146-
inline const std::array<std::optional<int>, kLimitMapping.size()>&
147-
initial_limits() const {
148-
return initial_limits_;
146+
inline const std::array<std::optional<int>, kLimitMapping.size()>& limits()
147+
const {
148+
return limits_;
149149
}
150150

151151
private:
@@ -159,7 +159,7 @@ class DatabaseOpenConfiguration {
159159
bool allow_bare_named_params_ = true;
160160
bool allow_unknown_named_params_ = false;
161161
bool defensive_ = true;
162-
std::array<std::optional<int>, kLimitMapping.size()> initial_limits_{};
162+
std::array<std::optional<int>, kLimitMapping.size()> limits_{};
163163
};
164164

165165
class Database;
@@ -277,6 +277,7 @@ class Database : public BaseObject {
277277
return open_config_.get_allow_unknown_named_params();
278278
}
279279
sqlite3* Connection();
280+
void SetLimit(int sqlite_limit_id, int value);
280281

281282
// In some situations, such as when using custom functions, it is possible
282283
// that SQLite reports an error while JavaScript already has a pending

‎test/parallel/test-sqlite-authz.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,37 @@ suite('Database.prototype.setAuthorizer()', () => {
287287
message: 'database is not open',
288288
});
289289
});
290+
291+
it('remains installed after close() and open()', (t) => {
292+
const db = new Database(':memory:');
293+
const authorizer = t.mock.fn(() => constants.SQLITE_DENY);
294+
db.setAuthorizer(authorizer);
295+
296+
assert.throws(() => {
297+
db.exec('CREATE TABLE x (a)');
298+
}, { code: 'ERR_SQLITE_ERROR' });
299+
const callsBefore = authorizer.mock.callCount();
300+
assert.ok(callsBefore > 0);
301+
302+
db.close();
303+
db.open();
304+
305+
assert.throws(() => {
306+
db.exec('CREATE TABLE x (a)');
307+
}, { code: 'ERR_SQLITE_ERROR' });
308+
assert.ok(authorizer.mock.callCount() > callsBefore);
309+
});
310+
311+
it('stays cleared after close() and open()', () => {
312+
const db = new Database(':memory:');
313+
db.setAuthorizer(() => constants.SQLITE_DENY);
314+
db.setAuthorizer(null);
315+
316+
db.close();
317+
db.open();
318+
319+
db.exec('CREATE TABLE x (a)');
320+
});
290321
});
291322

292323
// SQLite forbids an authorizer callback from modifying the connection that

‎test/parallel/test-sqlite-limits.js‎

Lines changed: 15 additions & 0 deletions

0 commit comments

Comments
 (0)