Skip to content

Commit 800d5a1

Browse files
committed
sqlite: fix segfault SQLTagStore when db handle is garbage collected
1 parent 77d8197 commit 800d5a1

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

src/node_sqlite.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ void DatabaseSync::CreateTagStore(const FunctionCallbackInfo<Value>& args) {
832832
}
833833

834834
BaseObjectPtr<SQLTagStore> session =
835-
SQLTagStore::Create(env, BaseObjectWeakPtr<DatabaseSync>(db), capacity);
835+
SQLTagStore::Create(env, BaseObjectPtr<DatabaseSync>(db), capacity);
836836
if (!session) {
837837
// Handle error if creation failed
838838
THROW_ERR_SQLITE_ERROR(env->isolate(), "Failed to create SQLTagStore");
@@ -2660,7 +2660,7 @@ void IllegalConstructor(const FunctionCallbackInfo<Value>& args) {
26602660

26612661
SQLTagStore::SQLTagStore(Environment* env,
26622662
Local<Object> object,
2663-
BaseObjectWeakPtr<DatabaseSync> database,
2663+
BaseObjectPtr<DatabaseSync> database,
26642664
int capacity)
26652665
: BaseObject(env, object),
26662666
database_(std::move(database)),
@@ -2709,7 +2709,7 @@ Local<FunctionTemplate> SQLTagStore::GetConstructorTemplate(Environment* env) {
27092709
}
27102710

27112711
BaseObjectPtr<SQLTagStore> SQLTagStore::Create(
2712-
Environment* env, BaseObjectWeakPtr<DatabaseSync> database, int capacity) {
2712+
Environment* env, BaseObjectPtr<DatabaseSync> database, int capacity) {
27132713
Local<Object> obj;
27142714
if (!GetConstructorTemplate(env)
27152715
->InstanceTemplate()

src/node_sqlite.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,12 @@ class SQLTagStore : public BaseObject {
306306
public:
307307
SQLTagStore(Environment* env,
308308
v8::Local<v8::Object> object,
309-
BaseObjectWeakPtr<DatabaseSync> database,
309+
BaseObjectPtr<DatabaseSync> database,
310310
int capacity);
311311
~SQLTagStore() override;
312-
static BaseObjectPtr<SQLTagStore> Create(
313-
Environment* env, BaseObjectWeakPtr<DatabaseSync> database, int capacity);
312+
static BaseObjectPtr<SQLTagStore> Create(Environment* env,
313+
BaseObjectPtr<DatabaseSync> database,
314+
int capacity);
314315
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
315316
Environment* env);
316317
static void All(const v8::FunctionCallbackInfo<v8::Value>& info);
@@ -329,7 +330,7 @@ class SQLTagStore : public BaseObject {
329330
private:
330331
static BaseObjectPtr<StatementSync> PrepareStatement(
331332
const v8::FunctionCallbackInfo<v8::Value>& args);
332-
BaseObjectWeakPtr<DatabaseSync> database_;
333+
BaseObjectPtr<DatabaseSync> database_;
333334
LRUCache<std::string, BaseObjectPtr<StatementSync>> sql_tags_;
334335
int capacity_;
335336
friend class StatementExecutionHelper;

test/parallel/test-sqlite-template-tag.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,17 @@ test('TagStore capacity, size, and clear', () => {
100100
test('sql.db returns the associated DatabaseSync instance', () => {
101101
assert.strictEqual(sql.db, db);
102102
});
103+
104+
test('regression test https://github.com/nodejs/node/issues/60448', () => {
105+
const sql = new DatabaseSync(':memory:').createTagStore();
106+
107+
sql.db.exec('CREATE TABLE test (data NUMBER)');
108+
109+
// Simulating meaningful work/likely triggering garbage collection...
110+
for (const x of new Array(100_000).fill(0)) {
111+
// eslint-disable-next-line no-unused-expressions
112+
x + x;
113+
}
114+
// eslint-disable-next-line no-unused-expressions
115+
sql.run`INSERT INTO test (data) VALUES (1)`;
116+
});

0 commit comments

Comments
 (0)