From 48acd573b1a470e54831e4388ea0e4fde410de30 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 25 Feb 2021 16:34:55 +0100 Subject: idb: make test cases pass --- packages/idb-bridge/src/bridge-idb.ts | 40 +++++++++++++++++----- packages/idb-bridge/src/util/makeStoreKeyValue.ts | 10 ++++-- .../idb-bridge/src/util/structuredClone.test.ts | 12 +++++++ 3 files changed, 51 insertions(+), 11 deletions(-) (limited to 'packages') diff --git a/packages/idb-bridge/src/bridge-idb.ts b/packages/idb-bridge/src/bridge-idb.ts index 1fa21c7d5..fa2e16e2c 100644 --- a/packages/idb-bridge/src/bridge-idb.ts +++ b/packages/idb-bridge/src/bridge-idb.ts @@ -42,11 +42,13 @@ import { IDBTransactionMode, IDBValidKey, } from "./idbtypes"; +import { canInjectKey } from "./util/canInjectKey"; import { compareKeys } from "./util/cmp"; import { enforceRange } from "./util/enforceRange"; import { AbortError, ConstraintError, + DataCloneError, DataError, InvalidAccessError, InvalidStateError, @@ -62,9 +64,7 @@ import { makeStoreKeyValue } from "./util/makeStoreKeyValue"; import { normalizeKeyPath } from "./util/normalizeKeyPath"; import { openPromise } from "./util/openPromise"; import queueTask from "./util/queueTask"; -import { - structuredClone, -} from "./util/structuredClone"; +import { structuredClone } from "./util/structuredClone"; import { validateKeyPath } from "./util/validateKeyPath"; import { valueToKey } from "./util/valueToKey"; @@ -106,8 +106,9 @@ export class BridgeIDBCursor implements IDBCursor { private _gotValue: boolean = false; private _range: IDBValidKey | IDBKeyRange | undefined | null; - private _indexPosition = undefined; // Key of previously returned record - private _objectStorePosition = undefined; + // Key of previously returned record + private _indexPosition: IDBValidKey | undefined = undefined; + private _objectStorePosition: IDBValidKey | undefined = undefined; private _keyOnly: boolean; private _source: CursorSource; @@ -251,9 +252,9 @@ export class BridgeIDBCursor implements IDBCursor { } this._gotValue = true; - this._objectStorePosition = structuredClone(response.primaryKeys![0]); + this._objectStorePosition = response.primaryKeys![0]; if (response.indexKeys !== undefined && response.indexKeys.length > 0) { - this._indexPosition = structuredClone(response.indexKeys[0]); + this._indexPosition = response.indexKeys![0]; } return this; @@ -290,8 +291,31 @@ export class BridgeIDBCursor implements IDBCursor { throw new InvalidStateError(); } + const key = this._primaryKey; + + // Effective object store + let os: BridgeIDBObjectStore; + if (this.source instanceof BridgeIDBObjectStore) { + os = this.source; + } else { + os = this.source._objectStore; + } + + try { + // Only called for the side effect of throwing an exception + structuredClone(value); + } catch (e) { + throw new DataCloneError(); + } + + if (os.keyPath !== null && os.keyPath !== undefined) { + if (!canInjectKey(os.keyPath, value)) { + throw new DataError(); + } + } + const storeReq: RecordStoreRequest = { - key: this._primaryKey, + key, value, objectStoreName: this._objectStoreName, storeLevel: StoreLevel.UpdateExisting, diff --git a/packages/idb-bridge/src/util/makeStoreKeyValue.ts b/packages/idb-bridge/src/util/makeStoreKeyValue.ts index 243e46e04..c0fdb19a7 100644 --- a/packages/idb-bridge/src/util/makeStoreKeyValue.ts +++ b/packages/idb-bridge/src/util/makeStoreKeyValue.ts @@ -15,7 +15,7 @@ */ import { extractKey } from "./extractKey"; -import { DataError } from "./errors"; +import { DataCloneError, DataError } from "./errors"; import { valueToKey } from "./valueToKey"; import { structuredClone } from "./structuredClone"; import { IDBKeyPath, IDBValidKey } from "../idbtypes"; @@ -26,7 +26,7 @@ export interface StoreKeyResult { value: any; } -export function injectKey( +function injectKey( keyPath: IDBKeyPath | IDBKeyPath[], value: any, key: IDBValidKey, @@ -87,7 +87,11 @@ export function makeStoreKeyValue( // This models a decision table on (haveKey, haveKeyPath, autoIncrement) - value = structuredClone(value); + try { + value = structuredClone(value); + } catch (e) { + throw new DataCloneError(); + } if (haveKey) { if (haveKeyPath) { diff --git a/packages/idb-bridge/src/util/structuredClone.test.ts b/packages/idb-bridge/src/util/structuredClone.test.ts index 58a7f32c1..ed404c6be 100644 --- a/packages/idb-bridge/src/util/structuredClone.test.ts +++ b/packages/idb-bridge/src/util/structuredClone.test.ts @@ -29,6 +29,18 @@ test("structured clone", (t) => { checkClone(t, [new Date()]); checkClone(t, undefined); checkClone(t, [undefined]); + + t.throws(() => { + structuredClone({ foo: () => {} }); + }); + + t.throws(() => { + structuredClone(Promise); + }); + + t.throws(() => { + structuredClone(Promise.resolve()); + }); }); test("structured clone (cycles)", (t) => { -- cgit v1.2.3