taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 7ee997799c07abc3fe30a75a08b6c51d177089ff
parent 086341c341a466b12909ed2f55a3f5bd7db0c761
Author: Florian Dold <dold@taler.net>
Date:   Mon, 20 Jul 2026 02:26:44 +0200

db: reject cross-backend dumps on import

The two dump formats are structurally distinct.  Importing one into the
other backend imported nothing while reporting success.

Diffstat:
Mpackages/taler-wallet-core/src/dbtx-handle-impl.ts | 23++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/packages/taler-wallet-core/src/dbtx-handle-impl.ts b/packages/taler-wallet-core/src/dbtx-handle-impl.ts @@ -158,6 +158,17 @@ export class IdbWalletDbHandle implements WalletDbHandle { } async importDatabase(dump: any): Promise<void> { + // A native-backend dump has {schemaVersion, tables}; this backend's dumps + // have {databases}. Importing across backends is a format conversion, + // not a copy, and silently accepting the wrong shape would import + // nothing while reporting success. + if (dump != null && typeof dump === "object" && "tables" in dump) { + throw Error( + "this dump is from the native sqlite backend and cannot be" + + " imported into the IndexedDB backend; convert the database" + + " instead", + ); + } await this.ensureOpen(); if (!this.idbHandle) { throw Error("wallet database is not open"); @@ -246,7 +257,9 @@ export class SqliteWalletDbHandle implements WalletDbHandle { } const path = `${directory}/${stem}.sqlite3`; await this.ndb.lock.run(async () => { - await (await this.ndb.db.prepare("VACUUM INTO $filename")).run({ + await ( + await this.ndb.db.prepare("VACUUM INTO $filename") + ).run({ filename: path, }); }); @@ -272,6 +285,14 @@ export class SqliteWalletDbHandle implements WalletDbHandle { } async importDatabase(dump: any): Promise<void> { + // See the IndexedDB counterpart: a dump from the other backend is a + // conversion job, and must not be half-imported here. + if (dump != null && typeof dump === "object" && "databases" in dump) { + throw Error( + "this dump is from the IndexedDB backend and cannot be imported" + + " into the native sqlite backend; convert the database instead", + ); + } await importNativeSqliteDb(this.ndb, dump); }