diff --git a/deps/sqlite/sqlite3.c b/deps/sqlite/sqlite3.c index 91db04a9ecdc54..1bbba6de0766ec 100644 --- a/deps/sqlite/sqlite3.c +++ b/deps/sqlite/sqlite3.c @@ -238354,7 +238354,13 @@ static int sessionApplyOneOp( for(i=0; rc==SQLITE_OK && iabPK[i] || (bPatchset==0 && pOld) ){ + if( p->abPK[i] ){ + if( pOld==0 ){ + rc = SQLITE_CORRUPT_BKPT; + break; + } + rc = sessionBindValue(pUp, i*2+2, pOld); + }else if( bPatchset==0 && pOld ){ rc = sessionBindValue(pUp, i*2+2, pOld); } if( rc==SQLITE_OK && pNew ){ diff --git a/test/parallel/test-sqlite-session.js b/test/parallel/test-sqlite-session.js index 934ef576bc93fa..4a1ce89af5126a 100644 --- a/test/parallel/test-sqlite-session.js +++ b/test/parallel/test-sqlite-session.js @@ -6,6 +6,7 @@ const { DatabaseSync, constants, } = require('node:sqlite'); +const { spawnSync } = require('node:child_process'); const { test, suite } = require('node:test'); const { nextDb } = require('../sqlite/next-db.js'); const { Worker } = require('worker_threads'); @@ -94,6 +95,41 @@ test('database.applyChangeset() - closed database results in exception', (t) => }); }); +test('database.applyChangeset() - malformed changeset throws instead of crashing', (t) => { + const script = ` + const { DatabaseSync } = require('node:sqlite'); + const payload = Buffer.from('540401000000743100177e0072286565286565', 'hex'); + + const database = new DatabaseSync(':memory:'); + database.exec('CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d)'); + + try { + database.applyChangeset(payload); + console.log(JSON.stringify({ applied: true })); + } catch (err) { + console.log(JSON.stringify({ + name: err.name, + code: err.code, + errcode: err.errcode, + message: err.message, + })); + } + `; + + const result = spawnSync(process.execPath, ['--experimental-sqlite', '-e', script], { + encoding: 'utf8', + }); + + t.assert.strictEqual(result.signal, null); + t.assert.strictEqual(result.status, 0); + t.assert.deepStrictEqual(JSON.parse(result.stdout), { + name: 'Error', + code: 'ERR_SQLITE_ERROR', + errcode: 11, + message: 'database disk image is malformed', + }); +}); + test('database.createSession() - use table option to track specific table', (t) => { const database1 = new DatabaseSync(':memory:'); const database2 = new DatabaseSync(':memory:');