Skip to content

Commit 66f69bb

Browse files
committed
sqlite: validate backup() source is a DatabaseSync
backup() only checked that the source argument was a BaseObject before casting it to Database, so passing a Statement or Session caused a type confusion. Check against the DatabaseSync constructor template instead. Signed-off-by: Guilherme Araújo <arauujogui@gmail.com>
1 parent e39f2e8 commit 66f69bb

3 files changed

Lines changed: 24 additions & 4 deletions

File tree

‎src/env_properties.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@
451451
V(socketaddress_constructor_template, v8::FunctionTemplate) \
452452
V(space_stats_template, v8::DictionaryTemplate) \
453453
V(sqlite_column_template, v8::DictionaryTemplate) \
454+
V(sqlite_database_constructor_template, v8::FunctionTemplate) \
454455
V(sqlite_limits_template, v8::ObjectTemplate) \
455456
V(sqlite_run_result_template, v8::DictionaryTemplate) \
456457
V(sqlite_statement_sync_constructor_template, v8::FunctionTemplate) \

‎src/node_sqlite.cc‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3208,9 +3208,11 @@ void Database::CreateSession(const FunctionCallbackInfo<Value>& args) {
32083208

32093209
void Backup(const FunctionCallbackInfo<Value>& args) {
32103210
Environment* env = Environment::GetCurrent(args);
3211-
if (args.Length() < 1 || !args[0]->IsObject()) {
3212-
THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
3213-
"The \"sourceDb\" argument must be an object.");
3211+
if (!args[0]->IsObject() ||
3212+
!env->sqlite_database_constructor_template()->HasInstance(args[0])) {
3213+
THROW_ERR_INVALID_ARG_TYPE(
3214+
env->isolate(),
3215+
"The \"sourceDb\" argument must be a DatabaseSync instance.");
32143216
return;
32153217
}
32163218

@@ -5425,6 +5427,7 @@ static void Initialize(Local<Object> target,
54255427
FIXED_ONE_BYTE_STRING(isolate, "node:sqlite");
54265428
db_tmpl->InstanceTemplate()->Set(sqlite_type_symbol, database_sync_string);
54275429

5430+
env->set_sqlite_database_constructor_template(db_tmpl);
54285431
SetConstructorFunction(context, target, "Database", db_tmpl);
54295432
SetConstructorFunction(context,
54305433
target,

‎test/parallel/test-sqlite-backup.mjs‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,26 @@ describe('backup()', () => {
4848
backup();
4949
}, {
5050
code: 'ERR_INVALID_ARG_TYPE',
51-
message: 'The "sourceDb" argument must be an object.'
51+
message: 'The "sourceDb" argument must be a DatabaseSync instance.'
5252
});
5353
});
5454

55+
test('throws if the source is not a DatabaseSync', (t) => {
56+
const database = makeSourceDb();
57+
for (const source of [
58+
{},
59+
database.prepare('SELECT 1'),
60+
database.createSession(),
61+
]) {
62+
t.assert.throws(() => {
63+
backup(source, 'out.db');
64+
}, {
65+
code: 'ERR_INVALID_ARG_TYPE',
66+
message: 'The "sourceDb" argument must be a DatabaseSync instance.'
67+
});
68+
}
69+
});
70+
5571
test('throws if path is not a string, URL, or Buffer', (t) => {
5672
const database = makeSourceDb();
5773

0 commit comments

Comments
 (0)