Commit c0daf393e41 for nodejs
commit c0daf393e412aa98cf88793f0470bfaf250a7778
Author: Guilherme Araújo <arauujogui@gmail.com>
Date: Fri Oct 9 12:53:53 2026 -0300
sqlite: validate aggregate() name and options
`Database.prototype.aggregate()` cast its arguments without checking
their types, so a missing `options` leaked a raw V8 TypeError and a
non-string `name` was silently coerced. Throw `ERR_INVALID_ARG_TYPE`
like the other sqlite bindings do.
Assisted-by: Claude Code
Signed-off-by: Guilherme Araújo <arauujogui@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66463
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc
index 6aae7e60cfc..4f98c6224c7 100644
--- a/src/node_sqlite.cc
+++ b/src/node_sqlite.cc
@@ -2703,6 +2703,19 @@ void Database::AggregateFunction(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_ON_BAD_STATE(env, !db->IsOpen(), "database is not open");
THROW_AND_RETURN_IF_IN_AUTHORIZER(env, db);
+
+ if (!args[0]->IsString()) {
+ THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
+ "The \"name\" argument must be a string.");
+ return;
+ }
+
+ if (!args[1]->IsObject()) {
+ THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
+ "The \"options\" argument must be an object.");
+ return;
+ }
+
Utf8Value name(env->isolate(), args[0].As<String>());
Local<Object> options = args[1].As<Object>();
Local<Value> start_v;
diff --git a/test/parallel/test-sqlite-aggregate-function.mjs b/test/parallel/test-sqlite-aggregate-function.mjs
index f588cc3ee68..83f7833cb3f 100644
--- a/test/parallel/test-sqlite-aggregate-function.mjs
+++ b/test/parallel/test-sqlite-aggregate-function.mjs
@@ -20,6 +20,24 @@ describe('Database.prototype.aggregate()', () => {
return fn;
}
+ test('throws if name is not a string', (t) => {
+ t.assert.throws(() => {
+ db.aggregate(123, { start: 0, step: () => {} });
+ }, {
+ code: 'ERR_INVALID_ARG_TYPE',
+ message: 'The "name" argument must be a string.'
+ });
+ });
+
+ test('throws if options is not an object', (t) => {
+ t.assert.throws(() => {
+ db.aggregate('sum');
+ }, {
+ code: 'ERR_INVALID_ARG_TYPE',
+ message: 'The "options" argument must be an object.'
+ });
+ });
+
test('throws if options.start is not provided', (t) => {
t.assert.throws(() => {
db.aggregate('sum', {