Fix key path extraction code in IndexedDB to check own property
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2019 00:03:31 +0000 (00:03 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2019 00:03:31 +0000 (00:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196099

Reviewed by Ryosuke Niwa.

LayoutTests/imported/w3c:

Updated test expectations to PASS.

* web-platform-tests/IndexedDB/key-conversion-exceptions-expected.txt:
* web-platform-tests/IndexedDB/keygenerator-inject-expected.txt:
* web-platform-tests/IndexedDB/keypath-exceptions-expected.txt: Added.
* web-platform-tests/IndexedDB/wasm-module-value-expected.txt:

Source/WebCore:

Covered by existing tests.

* Modules/indexeddb/IDBFactory.cpp:
(WebCore::IDBFactory::cmp):
We don't need to check the second parameters if the first is already invalid.

* Modules/indexeddb/IDBKeyRange.cpp:
(WebCore::IDBKeyRange::bound):
Ditto.

* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::putOrAdd):
we should not clear the exception during serialization because the execeptions may be explicitly thrown by parameters.

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::get):
Fix implementation according to https://www.w3.org/TR/IndexedDB-2/#extract-key-from-value.

(WebCore::canInjectNthValueOnKeyPath):
Check the last identifier.

LayoutTests:

Rebaseline the tests because we will have same exception but different exception messages after the patch.

* storage/indexeddb/clone-exception-expected.txt:
* storage/indexeddb/clone-exception-private-expected.txt:
* storage/indexeddb/exceptions-expected.txt:
* storage/indexeddb/exceptions-private-expected.txt:
* storage/indexeddb/objectstore-basics-expected.txt:
* storage/indexeddb/objectstore-basics-private-expected.txt:
* storage/indexeddb/objectstore-basics-workers-expected.txt:
* storage/indexeddb/structured-clone-expected.txt:
* storage/indexeddb/structured-clone-private-expected.txt:
* storage/indexeddb/wasm-exceptions-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243348 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/IndexedDB/key-conversion-exceptions-expected.txt
LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keygenerator-inject-expected.txt
LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keypath-exceptions-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/IndexedDB/wasm-module-value-expected.txt
LayoutTests/storage/indexeddb/clone-exception-expected.txt
LayoutTests/storage/indexeddb/clone-exception-private-expected.txt
LayoutTests/storage/indexeddb/exceptions-expected.txt
LayoutTests/storage/indexeddb/exceptions-private-expected.txt
LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
LayoutTests/storage/indexeddb/objectstore-basics-private-expected.txt
LayoutTests/storage/indexeddb/objectstore-basics-workers-expected.txt
LayoutTests/storage/indexeddb/structured-clone-expected.txt
LayoutTests/storage/indexeddb/structured-clone-private-expected.txt
LayoutTests/storage/indexeddb/wasm-exceptions-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBFactory.cpp
Source/WebCore/Modules/indexeddb/IDBKeyRange.cpp
Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
Source/WebCore/bindings/js/IDBBindingUtilities.cpp

index ef157f9..c146b02 100644 (file)
@@ -1,3 +1,23 @@
+2019-03-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Fix key path extraction code in IndexedDB to check own property
+        https://bugs.webkit.org/show_bug.cgi?id=196099
+
+        Reviewed by Ryosuke Niwa.
+
+        Rebaseline the tests because we will have same exception but different exception messages after the patch.
+
+        * storage/indexeddb/clone-exception-expected.txt:
+        * storage/indexeddb/clone-exception-private-expected.txt:
+        * storage/indexeddb/exceptions-expected.txt:
+        * storage/indexeddb/exceptions-private-expected.txt:
+        * storage/indexeddb/objectstore-basics-expected.txt:
+        * storage/indexeddb/objectstore-basics-private-expected.txt:
+        * storage/indexeddb/objectstore-basics-workers-expected.txt:
+        * storage/indexeddb/structured-clone-expected.txt:
+        * storage/indexeddb/structured-clone-private-expected.txt:
+        * storage/indexeddb/wasm-exceptions-expected.txt:
+
 2019-03-21  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] Turn on async overflow scrolling by default
index 3dd9a2b..44aab83 100644 (file)
@@ -1,3 +1,30 @@
+2019-03-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Fix key path extraction code in IndexedDB to check own property
+        https://bugs.webkit.org/show_bug.cgi?id=196099
+
+        Reviewed by Ryosuke Niwa.
+
+        Updated test expectations to PASS.
+
+        * web-platform-tests/IndexedDB/key-conversion-exceptions-expected.txt:
+        * web-platform-tests/IndexedDB/keygenerator-inject-expected.txt:
+        * web-platform-tests/IndexedDB/keypath-exceptions-expected.txt: Added.
+        * web-platform-tests/IndexedDB/wasm-module-value-expected.txt:
+
+2019-03-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Fix three IDB WPT tests
+        https://bugs.webkit.org/show_bug.cgi?id=196099
+
+        Reviewed by Ryosuke Niwa.
+
+        Updated test expectations to PASS.
+
+        * web-platform-tests/IndexedDB/key-conversion-exceptions-expected.txt:
+        * web-platform-tests/IndexedDB/keygenerator-inject-expected.txt:
+        * web-platform-tests/IndexedDB/keypath-exceptions-expected.txt: Added.
+
 2019-03-21  Youenn Fablet  <youenn@apple.com>
 
         Fix one of RTCRtpTransceiver-stop.html test title
index e6c6717..fb47087 100644 (file)
@@ -1,22 +1,14 @@
 
-FAIL IDBFactory cmp() static with throwing/invalid keys assert_throws: first key conversion with invalid key should throw DataError function "() => {
-            receiver[method](invalid_key, throwing_key('getter 2'));
-        }" threw object "getter 2: throwing from getter" that is not a DOMException DataError: property "code" is equal to undefined, expected 0
+PASS IDBFactory cmp() static with throwing/invalid keys 
 PASS IDBCursor continue() method with throwing/invalid keys 
 PASS IndexedDB: Exceptions thrown during key conversion 
 PASS IDBCursor update() method with throwing/invalid keys 
 PASS IDBKeyRange only() static with throwing/invalid keys 
 PASS IDBKeyRange lowerBound() static with throwing/invalid keys 
 PASS IDBKeyRange upperBound() static with throwing/invalid keys 
-FAIL IDBKeyRange bound() static with throwing/invalid keys assert_throws: first key conversion with invalid key should throw DataError function "() => {
-            receiver[method](invalid_key, throwing_key('getter 2'));
-        }" threw object "getter 2: throwing from getter" that is not a DOMException DataError: property "code" is equal to undefined, expected 0
-FAIL IDBObjectStore add() method with throwing/invalid keys assert_throws: key conversion with throwing getter should rethrow function "() => {
-            out_of_line[method]('value', throwing_key('getter'));
-        }" threw object "DataCloneError: Failed to store record in an IDBObjectStore: An object could not be cloned." ("DataCloneError") expected object "[object Object]" ("getter")
-FAIL IDBObjectStore put() method with throwing/invalid keys assert_throws: key conversion with throwing getter should rethrow function "() => {
-            out_of_line[method]('value', throwing_key('getter'));
-        }" threw object "DataCloneError: Failed to store record in an IDBObjectStore: An object could not be cloned." ("DataCloneError") expected object "[object Object]" ("getter")
+PASS IDBKeyRange bound() static with throwing/invalid keys 
+PASS IDBObjectStore add() method with throwing/invalid keys 
+PASS IDBObjectStore put() method with throwing/invalid keys 
 PASS IDBObjectStore delete() method with throwing/invalid keys 
 PASS IDBObjectStore get() method with throwing/invalid keys 
 PASS IDBObjectStore getKey() method with throwing/invalid keys 
index 297648b..a169b8f 100644 (file)
@@ -3,7 +3,5 @@ PASS Key is injected into value - single segment path
 PASS Key is injected into value - multi-segment path 
 PASS Key is injected into value - multi-segment path, partially populated 
 PASS put() throws if key cannot be injected - single segment path 
-FAIL put() throws if key cannot be injected - multi-segment path assert_throws: Key path should be checked against value function "() => {
-      store.put({a: {b: 123} });
-    }" did not throw
+PASS put() throws if key cannot be injected - multi-segment path 
 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keypath-exceptions-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/keypath-exceptions-expected.txt
new file mode 100644 (file)
index 0000000..2586652
--- /dev/null
@@ -0,0 +1,8 @@
+
+PASS The last element of keypath is validated 
+PASS Key path evaluation: Exceptions from non-enumerable getters 
+PASS Key path evaluation: Exceptions from enumerable getters 
+PASS Key path evaluation: Exceptions from non-enumerable getters on prototype 
+PASS Key path evaluation: Exceptions from enumerable getters on prototype 
+PASS Array key conversion should not invoke prototype getters 
+
index 3558542..1638e01 100644 (file)
@@ -1,5 +1,5 @@
 
-FAIL WebAssembly module as an IndexedDB value Failed to store record in an IDBObjectStore: An object could not be cloned.
-FAIL WebAssembly module in a JavaScript object IndexedDB value Failed to store record in an IDBObjectStore: An object could not be cloned.
-FAIL WebAssembly module in an IndexedDB value with an inline key Failed to store record in an IDBObjectStore: An object could not be cloned.
+FAIL WebAssembly module as an IndexedDB value The object can not be cloned.
+FAIL WebAssembly module in a JavaScript object IndexedDB value The object can not be cloned.
+FAIL WebAssembly module in an IndexedDB value with an inline key The object can not be cloned.
 
index 737505b..cb3d6a6 100644 (file)
@@ -12,7 +12,7 @@ Expecting exception from db.createObjectStore('store').put(NON_CLONEABLE, 0);
 PASS Exception was thrown.
 PASS code is 25
 PASS ename is 'DataCloneError'
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 doSecondOpen():
 indexedDB.open(dbname + '2')
@@ -22,7 +22,7 @@ Expecting exception from db.createObjectStore('store').put(NON_CLONEABLE, 0);
 PASS Exception was thrown.
 PASS code is 25
 PASS ename is 'DataCloneError'
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 doThirdOpen():
 indexedDB.open(dbname + '3')
@@ -32,7 +32,7 @@ Expecting exception from db.createObjectStore('store').put(NON_CLONEABLE, INVALI
 PASS Exception was thrown.
 PASS code is 25
 PASS ename is 'DataCloneError'
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 737505b..cb3d6a6 100644 (file)
@@ -12,7 +12,7 @@ Expecting exception from db.createObjectStore('store').put(NON_CLONEABLE, 0);
 PASS Exception was thrown.
 PASS code is 25
 PASS ename is 'DataCloneError'
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 doSecondOpen():
 indexedDB.open(dbname + '2')
@@ -22,7 +22,7 @@ Expecting exception from db.createObjectStore('store').put(NON_CLONEABLE, 0);
 PASS Exception was thrown.
 PASS code is 25
 PASS ename is 'DataCloneError'
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 doThirdOpen():
 indexedDB.open(dbname + '3')
@@ -32,7 +32,7 @@ Expecting exception from db.createObjectStore('store').put(NON_CLONEABLE, INVALI
 PASS Exception was thrown.
 PASS code is 25
 PASS ename is 'DataCloneError'
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index c4116a9..1ff6ff9 100644 (file)
@@ -159,7 +159,7 @@ The data being stored could not be cloned by the internal structured cloning alg
 Expecting exception from store.add(self, 0)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 IDBObjectStore.clear()
 This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".
@@ -272,7 +272,7 @@ The data being stored could not be cloned by the internal structured cloning alg
 Expecting exception from store.put(self, 0)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 db.close()
 ro_transaction.oncomplete = transactionComplete
 rw_transaction.oncomplete = transactionComplete
@@ -504,7 +504,7 @@ If the structured clone algorithm throws an exception, that exception is rethrow
 Expecting exception from cursor.update(self)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 The transaction this IDBCursor belongs to is not active.
 Expecting exception from cursorFromInactiveTransaction.update({})
 PASS Exception was thrown.
index c4116a9..1ff6ff9 100644 (file)
@@ -159,7 +159,7 @@ The data being stored could not be cloned by the internal structured cloning alg
 Expecting exception from store.add(self, 0)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 IDBObjectStore.clear()
 This method throws a DOMException of type ReadOnlyError if the transaction which this IDBObjectStore belongs to is has its mode set to "readonly".
@@ -272,7 +272,7 @@ The data being stored could not be cloned by the internal structured cloning alg
 Expecting exception from store.put(self, 0)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 db.close()
 ro_transaction.oncomplete = transactionComplete
 rw_transaction.oncomplete = transactionComplete
@@ -504,7 +504,7 @@ If the structured clone algorithm throws an exception, that exception is rethrow
 Expecting exception from cursor.update(self)
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 The transaction this IDBCursor belongs to is not active.
 Expecting exception from cursorFromInactiveTransaction.update({})
 PASS Exception was thrown.
index dc2983c..24dbd6f 100644 (file)
@@ -94,7 +94,7 @@ Try to insert a value not handled by structured clone:
 Expecting exception from store.add({x: 'bar', y: self}, 'bar')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Try to insert data where key path yields a Date key:
 store.add({x: testDateB, y: 'value'}, 'key')
 addSuccess():
index dc2983c..24dbd6f 100644 (file)
@@ -94,7 +94,7 @@ Try to insert a value not handled by structured clone:
 Expecting exception from store.add({x: 'bar', y: self}, 'bar')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Try to insert data where key path yields a Date key:
 store.add({x: testDateB, y: 'value'}, 'key')
 addSuccess():
index a11859b..4ab6266 100644 (file)
@@ -95,7 +95,7 @@ PASS [Worker] store.indexNames.item(100) is null
 [Worker] Expecting exception from store.add({x: 'bar', y: self}, 'bar')
 PASS [Worker] Exception was thrown.
 PASS [Worker] code is DOMException.DATA_CLONE_ERR
-[Worker] Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+[Worker] Exception message: The object can not be cloned.
 [Worker] Try to insert data where key path yields a Date key:
 [Worker] store.add({x: testDateB, y: 'value'}, 'key')
 [Worker] addSuccess():
index 9728914..0124b9a 100644 (file)
@@ -782,25 +782,25 @@ Other JavaScript object types:
 Expecting exception from store.put(new Error, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Expecting exception from store.put(new Function, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 Other host object types:
 Expecting exception from store.put(self, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Expecting exception from store.put(document, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Expecting exception from store.put(document.body, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 9728914..0124b9a 100644 (file)
@@ -782,25 +782,25 @@ Other JavaScript object types:
 Expecting exception from store.put(new Error, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Expecting exception from store.put(new Function, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 
 Other host object types:
 Expecting exception from store.put(self, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Expecting exception from store.put(document, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 Expecting exception from store.put(document.body, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 2b96b02..8a0d172 100644 (file)
@@ -11,7 +11,7 @@ store = db.createObjectStore('store')
 Expecting exception from store.add(module, 'key')
 PASS Exception was thrown.
 PASS code is DOMException.DATA_CLONE_ERR
-Exception message: Failed to store record in an IDBObjectStore: An object could not be cloned.
+Exception message: The object can not be cloned.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 80773de..b70200e 100644 (file)
@@ -1,3 +1,31 @@
+2019-03-21  Sihui Liu  <sihui_liu@apple.com>
+
+        Fix key path extraction code in IndexedDB to check own property
+        https://bugs.webkit.org/show_bug.cgi?id=196099
+
+        Reviewed by Ryosuke Niwa.
+
+        Covered by existing tests.
+
+        * Modules/indexeddb/IDBFactory.cpp:
+        (WebCore::IDBFactory::cmp):
+        We don't need to check the second parameters if the first is already invalid.
+
+        * Modules/indexeddb/IDBKeyRange.cpp:
+        (WebCore::IDBKeyRange::bound):
+        Ditto.
+
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::putOrAdd):
+        we should not clear the exception during serialization because the execeptions may be explicitly thrown by parameters.
+
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::get):
+        Fix implementation according to https://www.w3.org/TR/IndexedDB-2/#extract-key-from-value.
+
+        (WebCore::canInjectNthValueOnKeyPath):
+        Check the last identifier.
+
 2019-03-21  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] JS wrapper may be deleted while animation is yet to dispatch its finish event
index ea1f849..2da10f2 100644 (file)
@@ -123,9 +123,11 @@ ExceptionOr<Ref<IDBOpenDBRequest>> IDBFactory::deleteDatabase(ScriptExecutionCon
 ExceptionOr<short> IDBFactory::cmp(ExecState& execState, JSValue firstValue, JSValue secondValue)
 {
     auto first = scriptValueToIDBKey(execState, firstValue);
-    auto second = scriptValueToIDBKey(execState, secondValue);
+    if (!first->isValid())
+        return Exception { DataError, "Failed to execute 'cmp' on 'IDBFactory': The parameter is not a valid key."_s };
 
-    if (!first->isValid() || !second->isValid())
+    auto second = scriptValueToIDBKey(execState, secondValue);
+    if (!second->isValid())
         return Exception { DataError, "Failed to execute 'cmp' on 'IDBFactory': The parameter is not a valid key."_s };
 
     return first->compare(second.get());
index 48038bd..a254d01 100644 (file)
@@ -92,9 +92,10 @@ ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::upperBound(ExecState& state, JSValue
 ExceptionOr<Ref<IDBKeyRange>> IDBKeyRange::bound(ExecState& state, JSValue lowerValue, JSValue upperValue, bool lowerOpen, bool upperOpen)
 {
     auto lower = scriptValueToIDBKey(state, lowerValue);
+    if (!lower->isValid())
+        return Exception { DataError };
     auto upper = scriptValueToIDBKey(state, upperValue);
-
-    if (!lower->isValid() || !upper->isValid())
+    if (!upper->isValid())
         return Exception { DataError };
     if (upper->isLessThan(lower.get()))
         return Exception { DataError };
index 1e0e6cd..f43090c 100644 (file)
@@ -340,12 +340,8 @@ ExceptionOr<Ref<IDBRequest>> IDBObjectStore::putOrAdd(ExecState& state, JSValue
         return Exception { ReadonlyError, "Failed to store record in an IDBObjectStore: The transaction is read-only."_s };
 
     auto serializedValue = SerializedScriptValue::create(state, value);
-    if (UNLIKELY(scope.exception())) {
-        // Clear the DOM exception from the serializer so we can give a more targeted exception.
-        scope.clearException();
-
+    if (UNLIKELY(scope.exception()))
         return Exception { DataCloneError, "Failed to store record in an IDBObjectStore: An object could not be cloned."_s };
-    }
 
     bool privateBrowsingEnabled = false;
     if (is<Document>(*context)) {
index 1a9d8df..da106ec 100644 (file)
 #include "IDBKeyPath.h"
 #include "IDBValue.h"
 #include "IndexKey.h"
+#include "JSBlob.h"
 #include "JSDOMBinding.h"
 #include "JSDOMConvertDate.h"
 #include "JSDOMConvertNullable.h"
+#include "JSFile.h"
 #include "Logging.h"
 #include "MessagePort.h"
 #include "ScriptExecutionContext.h"
@@ -61,10 +63,46 @@ static bool get(ExecState& exec, JSValue object, const String& keyPathElement, J
     }
     if (!object.isObject())
         return false;
+
+    auto* obj = asObject(object);
     Identifier identifier = Identifier::fromString(&exec.vm(), keyPathElement);
-    if (!asObject(object)->hasProperty(&exec, identifier))
+    auto& vm = exec.vm();
+    if (obj->inherits<JSArray>(vm) && keyPathElement == "length") {
+        result = obj->get(&exec, identifier);
+        return true;
+    }
+    if (obj->inherits<JSBlob>(vm) && (keyPathElement == "size" || keyPathElement == "type")) {
+        if (keyPathElement == "size") {
+            result = jsNumber(jsCast<JSBlob*>(obj)->wrapped().size());
+            return true;
+        }
+        if (keyPathElement == "type") {
+            result = jsString(&vm, jsCast<JSBlob*>(obj)->wrapped().type());
+            return true;
+        }
+    }
+    if (obj->inherits<JSFile>(vm)) {
+        if (keyPathElement == "name") {
+            result = jsString(&vm, jsCast<JSFile*>(obj)->wrapped().name());
+            return true;
+        }
+        if (keyPathElement == "lastModified") {
+            result = jsNumber(jsCast<JSFile*>(obj)->wrapped().lastModified());
+            return true;
+        }
+        if (keyPathElement == "lastModifiedDate") {
+            result = jsDate(exec, jsCast<JSFile*>(obj)->wrapped().lastModified());
+            return true;
+        }
+    }
+
+    PropertyDescriptor descriptor;
+    if (!obj->getOwnPropertyDescriptor(&exec, identifier, descriptor))
+        return false;
+    if (!descriptor.enumerable())
         return false;
-    result = asObject(object)->get(&exec, identifier);
+
+    result = obj->get(&exec, identifier);
     return true;
 }
 
@@ -255,7 +293,7 @@ static bool canInjectNthValueOnKeyPath(ExecState& exec, JSValue rootValue, const
     JSValue currentValue(rootValue);
 
     ASSERT(index <= keyPathElements.size());
-    for (size_t i = 0; i < index; ++i) {
+    for (size_t i = 0; i <= index; ++i) {
         JSValue parentValue(currentValue);
         const String& keyPathElement = keyPathElements[i];
         if (!get(exec, parentValue, keyPathElement, currentValue))