Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions doc/api/sqlite.md
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,10 @@ added:
Loads a serialized database into this connection, replacing the current
database. The deserialized database is writable. Existing prepared statements
are finalized before deserialization is attempted, even if the operation
subsequently fails. This method is a wrapper around
[`sqlite3_deserialize()`][].
subsequently fails. An [`ERR_INVALID_STATE`][] error is thrown if the method is
called while a database callback is on the stack, for example a user-defined
function, an aggregate function, an authorizer, or a changeset filter or conflict
handler. This method is a wrapper around [`sqlite3_deserialize()`][].

```mjs
import { DatabaseSync } from 'node:sqlite';
Expand Down Expand Up @@ -1796,6 +1798,7 @@ callback function to indicate what type of operation is being authorized.
[SQL injection]: https://en.wikipedia.org/wiki/SQL_injection
[Type conversion between JavaScript and SQLite]: #type-conversion-between-javascript-and-sqlite
[`ATTACH DATABASE`]: https://www.sqlite.org/lang_attach.html
[`ERR_INVALID_STATE`]: errors.md#err_invalid_state
[`PRAGMA foreign_keys`]: https://www.sqlite.org/pragma.html#pragma_foreign_keys
[`SQLITE_DBCONFIG_DEFENSIVE`]: https://www.sqlite.org/c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive
[`SQLITE_DETERMINISTIC`]: https://www.sqlite.org/c3ref/c_deterministic.html
Expand Down
4 changes: 4 additions & 0 deletions src/node_sqlite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1858,6 +1858,10 @@ void DatabaseSync::Deserialize(const FunctionCallbackInfo<Value>& args) {
ASSIGN_OR_RETURN_UNWRAP(&db, args.This());
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_ON_BAD_STATE(env, !db->IsOpen(), "database is not open");
THROW_AND_RETURN_ON_BAD_STATE(
Comment thread
trivikr marked this conversation as resolved.
Comment thread
trivikr marked this conversation as resolved.
env,
db->IsInCallback(),
"database cannot be deserialized while in a callback");

if (!args[0]->IsUint8Array()) {
THROW_ERR_INVALID_ARG_TYPE(env->isolate(),
Expand Down
17 changes: 17 additions & 0 deletions test/parallel/test-sqlite-serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ suite('DatabaseSync.prototype.deserialize()', () => {
});
});

test('throws if called while in a callback', (t) => {
const source = new DatabaseSync(':memory:');
const serialized = source.serialize();
source.close();

const db = new DatabaseSync(':memory:');
t.after(() => db.close());
db.function('deserialize_database', () => db.deserialize(serialized));
const stmt = db.prepare('SELECT deserialize_database()');

t.assert.throws(() => stmt.get(), {
code: 'ERR_INVALID_STATE',
message: 'database cannot be deserialized while in a callback',
});
t.assert.strictEqual(db.isOpen, true);
});

test('throws if buffer argument is not a Uint8Array', (t) => {
const db = new DatabaseSync(':memory:');
t.assert.throws(() => {
Expand Down
Loading