WebKit Bugzilla
Attachment 372785 Details for
Bug 198738
: REGRESSION (r244436): IndexedDB Uint8Array returned as ArrayBuffer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-198738-20190624122357.patch (text/plain), 35.68 KB, created by
Sihui Liu
on 2019-06-24 12:23:57 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Sihui Liu
Created:
2019-06-24 12:23:57 PDT
Size:
35.68 KB
patch
obsolete
>Subversion Revision: 246709 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 80896f8e9f86f52bb683773c1f23577bb9458c6b..5db2700ba6f3b28106a61d2f872e008e55bc29e2 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,54 @@ >+2019-06-24 Sihui Liu <sihui_liu@apple.com> >+ >+ REGRESSION (r244436): IndexedDB Uint8Array returned as ArrayBuffer >+ https://bugs.webkit.org/show_bug.cgi?id=198738 >+ <rdar://problem/51614053> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We didn't store typed array type in IDBKey. When we created IDBKey from JSArrayBufferView, stored it, and then >+ converted it to JSArrayBufferView, the array type information was lost. r244436 revealed the bug as it >+ introduced a new behavior that inserted key into retrieved value when retried value did not have a property >+ identical to stored key. >+ >+ Modified tests: storage/indexeddb/key-type-binary.html >+ storage/indexeddb/key-type-binary-private.html >+ >+ * Modules/indexeddb/IDBKey.cpp: >+ (WebCore::IDBKey::createBinary): >+ (WebCore::IDBKey::IDBKey): >+ (WebCore::IDBKey::compare const): >+ * Modules/indexeddb/IDBKey.h: >+ (WebCore::IDBKey::binaryType const): >+ (WebCore::IDBKey::binary const): >+ * Modules/indexeddb/IDBKeyData.cpp: >+ (WebCore::IDBKeyData::IDBKeyData): >+ (WebCore::IDBKeyData::maybeCreateIDBKey const): >+ (WebCore::IDBKeyData::isolatedCopy): >+ (WebCore::IDBKeyData::encode const): >+ (WebCore::IDBKeyData::decode): >+ (WebCore::IDBKeyData::compare const): >+ (WebCore::IDBKeyData::loggingString const): >+ (WebCore::IDBKeyData::setBinaryValue): >+ (WebCore::IDBKeyData::operator== const): >+ * Modules/indexeddb/IDBKeyData.h: >+ (WebCore::IDBKeyData::binaryType const): >+ (WebCore::IDBKeyData::hash const): >+ (WebCore::IDBKeyData::binary const): >+ (WebCore::IDBKeyData::encode const): >+ (WebCore::IDBKeyData::decode): >+ * Modules/indexeddb/IndexedDB.h: >+ * Modules/indexeddb/server/IDBSerialization.cpp: >+ (WebCore::serializedTypeForKeyType): >+ (WebCore::encodeKey): >+ (WebCore::decodeKey): >+ * bindings/js/IDBBindingUtilities.cpp: >+ (WebCore::binaryTypeElementSize): >+ (WebCore::toJS): >+ (WebCore::createIDBKeyFromValue): >+ * bindings/js/SerializedScriptValue.cpp: >+ (WebCore::CloneDeserializer::readArrayBufferView): >+ > 2019-06-21 Sihui Liu <sihui_liu@apple.com> > > openDatabase should return an empty object when WebSQL is disabled >diff --git a/Source/WebCore/Modules/indexeddb/IDBKey.cpp b/Source/WebCore/Modules/indexeddb/IDBKey.cpp >index 2a98499c2cfa8af2c59d6225a60bd58ccbe2a3f7..743dbf3ee960d65985a8088606a8ab280bf5e4d9 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBKey.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBKey.cpp >@@ -38,9 +38,9 @@ namespace WebCore { > > using IDBKeyVector = Vector<RefPtr<IDBKey>>; > >-Ref<IDBKey> IDBKey::createBinary(const ThreadSafeDataBuffer& buffer) >+Ref<IDBKey> IDBKey::createBinary(const ThreadSafeDataBuffer& buffer, IndexedDB::KeyBinaryType binaryType) > { >- return adoptRef(*new IDBKey(buffer)); >+ return adoptRef(*new IDBKey(buffer, binaryType)); > } > > Ref<IDBKey> IDBKey::createBinary(JSC::JSArrayBuffer& arrayBuffer) >@@ -49,10 +49,10 @@ Ref<IDBKey> IDBKey::createBinary(JSC::JSArrayBuffer& arrayBuffer) > return adoptRef(*new IDBKey(ThreadSafeDataBuffer::copyData(buffer->data(), buffer->byteLength()))); > } > >-Ref<IDBKey> IDBKey::createBinary(JSC::JSArrayBufferView& arrayBufferView) >+Ref<IDBKey> IDBKey::createBinary(JSC::JSArrayBufferView& arrayBufferView, IndexedDB::KeyBinaryType binaryType) > { > auto bufferView = arrayBufferView.possiblySharedImpl(); >- return adoptRef(*new IDBKey(ThreadSafeDataBuffer::copyData(bufferView->data(), bufferView->byteLength()))); >+ return adoptRef(*new IDBKey(ThreadSafeDataBuffer::copyData(bufferView->data(), bufferView->byteLength()), binaryType)); > } > > IDBKey::IDBKey(IndexedDB::KeyType type, double number) >@@ -76,8 +76,9 @@ IDBKey::IDBKey(const IDBKeyVector& keyArray, size_t arraySize) > { > } > >-IDBKey::IDBKey(const ThreadSafeDataBuffer& buffer) >- : m_type(IndexedDB::KeyType::Binary) >+IDBKey::IDBKey(const ThreadSafeDataBuffer& buffer, IndexedDB::KeyBinaryType binaryType) >+ : m_type(binaryType == IndexedDB::KeyBinaryType::NotTyped ? IndexedDB::KeyType::Binary : IndexedDB::KeyType::BinaryTyped) >+ , m_binaryType(binaryType) > , m_value(buffer) > , m_sizeEstimate(OverheadSize + buffer.size()) > { >@@ -105,6 +106,9 @@ int IDBKey::compare(const IDBKey& other) const > if (m_type != other.m_type) > return m_type > other.m_type ? -1 : 1; > >+ if (m_binaryType != other.m_binaryType) >+ return m_binaryType > other.m_binaryType ? -1 : 1; >+ > switch (m_type) { > case IndexedDB::KeyType::Array: { > auto& array = WTF::get<IDBKeyVector>(m_value); >@@ -119,6 +123,7 @@ int IDBKey::compare(const IDBKey& other) const > return 1; > return 0; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > return compareBinaryKeyData(WTF::get<ThreadSafeDataBuffer>(m_value), WTF::get<ThreadSafeDataBuffer>(other.m_value)); > case IndexedDB::KeyType::String: >diff --git a/Source/WebCore/Modules/indexeddb/IDBKey.h b/Source/WebCore/Modules/indexeddb/IDBKey.h >index 642c18e2ef619647814de24dced67978b617516b..93da44318444727fe2659131b0b77b1bc8a19e67 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBKey.h >+++ b/Source/WebCore/Modules/indexeddb/IDBKey.h >@@ -99,13 +99,14 @@ public: > return adoptRef(*new IDBKey(array, sizeEstimate)); > } > >- static Ref<IDBKey> createBinary(const ThreadSafeDataBuffer&); >+ static Ref<IDBKey> createBinary(const ThreadSafeDataBuffer&, IndexedDB::KeyBinaryType); > static Ref<IDBKey> createBinary(JSC::JSArrayBuffer&); >- static Ref<IDBKey> createBinary(JSC::JSArrayBufferView&); >+ static Ref<IDBKey> createBinary(JSC::JSArrayBufferView&, IndexedDB::KeyBinaryType); > > WEBCORE_EXPORT ~IDBKey(); > > IndexedDB::KeyType type() const { return m_type; } >+ IndexedDB::KeyBinaryType binaryType() const { return m_binaryType; } > WEBCORE_EXPORT bool isValid() const; > > const Vector<RefPtr<IDBKey>>& array() const >@@ -134,7 +135,7 @@ public: > > const ThreadSafeDataBuffer& binary() const > { >- ASSERT(m_type == IndexedDB::KeyType::Binary); >+ ASSERT(m_type == IndexedDB::KeyType::Binary || m_type == IndexedDB::KeyType::BinaryTyped); > return WTF::get<ThreadSafeDataBuffer>(m_value); > } > >@@ -166,9 +167,10 @@ private: > IDBKey(IndexedDB::KeyType, double number); > explicit IDBKey(const String& value); > IDBKey(const Vector<RefPtr<IDBKey>>& keyArray, size_t arraySize); >- explicit IDBKey(const ThreadSafeDataBuffer&); >+ explicit IDBKey(const ThreadSafeDataBuffer&, IndexedDB::KeyBinaryType binarTyoe = IndexedDB::KeyBinaryType::NotTyped); > > const IndexedDB::KeyType m_type; >+ IndexedDB::KeyBinaryType m_binaryType { IndexedDB::KeyBinaryType::NotTyped }; > Variant<Vector<RefPtr<IDBKey>>, String, double, ThreadSafeDataBuffer> m_value; > > const size_t m_sizeEstimate; >diff --git a/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp b/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp >index 45c189d95211e93155f85c3f544d37a017ab835c..f848713f5eea471f3cbafadb379587c22ffefb2e 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp >+++ b/Source/WebCore/Modules/indexeddb/IDBKeyData.cpp >@@ -43,6 +43,7 @@ IDBKeyData::IDBKeyData(const IDBKey* key) > } > > m_type = key->type(); >+ m_binaryType = key->binaryType(); > > switch (m_type) { > case IndexedDB::KeyType::Invalid: >@@ -54,6 +55,7 @@ IDBKeyData::IDBKeyData(const IDBKey* key) > array.append(IDBKeyData(key2.get())); > break; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > m_value = key->binary(); > break; >@@ -88,8 +90,9 @@ RefPtr<IDBKey> IDBKeyData::maybeCreateIDBKey() const > } > return IDBKey::createArray(array); > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: >- return IDBKey::createBinary(WTF::get<ThreadSafeDataBuffer>(m_value)); >+ return IDBKey::createBinary(WTF::get<ThreadSafeDataBuffer>(m_value), m_binaryType); > case IndexedDB::KeyType::String: > return IDBKey::createString(WTF::get<String>(m_value)); > case IndexedDB::KeyType::Date: >@@ -119,6 +122,7 @@ IDBKeyData IDBKeyData::isolatedCopy() const > void IDBKeyData::isolatedCopy(const IDBKeyData& source, IDBKeyData& destination) > { > destination.m_type = source.m_type; >+ destination.m_binaryType = source.m_binaryType; > destination.m_isNull = source.m_isNull; > > switch (source.m_type) { >@@ -131,6 +135,7 @@ void IDBKeyData::isolatedCopy(const IDBKeyData& source, IDBKeyData& destination) > destinationArray.append(key.isolatedCopy()); > return; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > destination.m_value = WTF::get<ThreadSafeDataBuffer>(source.m_value); > return; >@@ -156,6 +161,7 @@ void IDBKeyData::encode(KeyedEncoder& encoder) const > return; > > encoder.encodeEnum("type", m_type); >+ encoder.encodeEnum("binaryType", m_binaryType); > > switch (m_type) { > case IndexedDB::KeyType::Invalid: >@@ -167,6 +173,7 @@ void IDBKeyData::encode(KeyedEncoder& encoder) const > }); > return; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: { > auto* data = WTF::get<ThreadSafeDataBuffer>(m_value).data(); > encoder.encodeBool("hasBinary", !!data); >@@ -210,6 +217,9 @@ bool IDBKeyData::decode(KeyedDecoder& decoder, IDBKeyData& result) > if (!decoder.decodeEnum("type", result.m_type, enumFunction)) > return false; > >+ if (!decoder.decodeEnum("binaryType", result.m_binaryType, enumFunction)) >+ return false; >+ > if (result.m_type == IndexedDB::KeyType::Invalid) > return true; > >@@ -271,6 +281,9 @@ int IDBKeyData::compare(const IDBKeyData& other) const > if (m_type != other.m_type) > return m_type < other.m_type ? 1 : -1; > >+ if (m_binaryType != other.m_binaryType) >+ return m_binaryType < other.m_binaryType ? 1 : -1; >+ > // The types are the same, so handle actual value comparison. > switch (m_type) { > case IndexedDB::KeyType::Invalid: >@@ -290,6 +303,7 @@ int IDBKeyData::compare(const IDBKeyData& other) const > return 1; > return 0; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > return compareBinaryKeyData(WTF::get<ThreadSafeDataBuffer>(m_value), WTF::get<ThreadSafeDataBuffer>(other.m_value)); > case IndexedDB::KeyType::String: >@@ -336,6 +350,7 @@ String IDBKeyData::loggingString() const > result = builder.toString(); > break; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: { > StringBuilder builder; > builder.appendLiteral("<binary> - "); >@@ -390,11 +405,12 @@ void IDBKeyData::setArrayValue(const Vector<IDBKeyData>& value) > m_isNull = false; > } > >-void IDBKeyData::setBinaryValue(const ThreadSafeDataBuffer& value) >+void IDBKeyData::setBinaryValue(const ThreadSafeDataBuffer& value, IndexedDB::KeyBinaryType binaryType) > { > *this = IDBKeyData(); > m_value = value; >- m_type = IndexedDB::KeyType::Binary; >+ m_binaryType = binaryType; >+ m_type = m_binaryType == IndexedDB::KeyBinaryType::NotTyped ? IndexedDB::KeyType::Binary : IndexedDB::KeyType::BinaryTyped; > m_isNull = false; > } > >@@ -452,7 +468,7 @@ bool IDBKeyData::operator<(const IDBKeyData& rhs) const > > bool IDBKeyData::operator==(const IDBKeyData& other) const > { >- if (m_type != other.m_type || m_isNull != other.m_isNull || m_isDeletedValue != other.m_isDeletedValue) >+ if (m_type != other.m_type || m_binaryType != other.m_binaryType || m_isNull != other.m_isNull || m_isDeletedValue != other.m_isDeletedValue) > return false; > switch (m_type) { > case IndexedDB::KeyType::Invalid: >@@ -464,6 +480,7 @@ bool IDBKeyData::operator==(const IDBKeyData& other) const > return WTF::get<double>(m_value) == WTF::get<double>(other.m_value); > case IndexedDB::KeyType::String: > return WTF::get<String>(m_value) == WTF::get<String>(other.m_value); >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > return WTF::get<ThreadSafeDataBuffer>(m_value) == WTF::get<ThreadSafeDataBuffer>(other.m_value); > case IndexedDB::KeyType::Array: >diff --git a/Source/WebCore/Modules/indexeddb/IDBKeyData.h b/Source/WebCore/Modules/indexeddb/IDBKeyData.h >index e666794da6812379c5b7961343a3357273099a8c..18fafba1249e9dab16f13421565c5ae141614ac6 100644 >--- a/Source/WebCore/Modules/indexeddb/IDBKeyData.h >+++ b/Source/WebCore/Modules/indexeddb/IDBKeyData.h >@@ -81,7 +81,7 @@ public: > WEBCORE_EXPORT int compare(const IDBKeyData& other) const; > > void setArrayValue(const Vector<IDBKeyData>&); >- void setBinaryValue(const ThreadSafeDataBuffer&); >+ void setBinaryValue(const ThreadSafeDataBuffer&, IndexedDB::KeyBinaryType); > void setStringValue(const String&); > void setDateValue(double); > WEBCORE_EXPORT void setNumberValue(double); >@@ -96,6 +96,7 @@ public: > bool isNull() const { return m_isNull; } > bool isValid() const; > IndexedDB::KeyType type() const { return m_type; } >+ IndexedDB::KeyBinaryType binaryType() const { return m_binaryType; } > > bool operator<(const IDBKeyData&) const; > bool operator>(const IDBKeyData& other) const >@@ -123,6 +124,7 @@ public: > { > Vector<unsigned> hashCodes; > hashCodes.append(static_cast<unsigned>(m_type)); >+ hashCodes.append(static_cast<unsigned>(m_binaryType)); > hashCodes.append(m_isNull ? 1 : 0); > hashCodes.append(m_isDeletedValue ? 1 : 0); > switch (m_type) { >@@ -137,6 +139,7 @@ public: > case IndexedDB::KeyType::String: > hashCodes.append(StringHash::hash(WTF::get<String>(m_value))); > break; >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: { > auto* data = WTF::get<ThreadSafeDataBuffer>(m_value).data(); > if (!data) >@@ -177,7 +180,7 @@ public: > > const ThreadSafeDataBuffer& binary() const > { >- ASSERT(m_type == IndexedDB::KeyType::Binary); >+ ASSERT(m_type == IndexedDB::KeyType::Binary || m_type == IndexedDB::KeyType::BinaryTyped); > return WTF::get<ThreadSafeDataBuffer>(m_value); > } > >@@ -191,6 +194,7 @@ private: > static void isolatedCopy(const IDBKeyData& source, IDBKeyData& destination); > > IndexedDB::KeyType m_type; >+ IndexedDB::KeyBinaryType m_binaryType; > Variant<Vector<IDBKeyData>, String, double, ThreadSafeDataBuffer> m_value; > > bool m_isNull { false }; >@@ -237,6 +241,7 @@ void IDBKeyData::encode(Encoder& encoder) const > return; > > encoder.encodeEnum(m_type); >+ encoder.encodeEnum(m_binaryType); > > switch (m_type) { > case IndexedDB::KeyType::Invalid: >@@ -246,6 +251,7 @@ void IDBKeyData::encode(Encoder& encoder) const > case IndexedDB::KeyType::Array: > encoder << WTF::get<Vector<IDBKeyData>>(m_value); > break; >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > encoder << WTF::get<ThreadSafeDataBuffer>(m_value); > break; >@@ -272,6 +278,9 @@ Optional<IDBKeyData> IDBKeyData::decode(Decoder& decoder) > if (!decoder.decodeEnum(keyData.m_type)) > return WTF::nullopt; > >+ if (!decoder.decodeEnum(keyData.m_binaryType)) >+ return WTF::nullopt; >+ > switch (keyData.m_type) { > case IndexedDB::KeyType::Invalid: > case IndexedDB::KeyType::Max: >@@ -282,6 +291,7 @@ Optional<IDBKeyData> IDBKeyData::decode(Decoder& decoder) > if (!decoder.decode(WTF::get<Vector<IDBKeyData>>(keyData.m_value))) > return WTF::nullopt; > break; >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: > keyData.m_value = ThreadSafeDataBuffer(); > if (!decoder.decode(WTF::get<ThreadSafeDataBuffer>(keyData.m_value))) >diff --git a/Source/WebCore/Modules/indexeddb/IndexedDB.h b/Source/WebCore/Modules/indexeddb/IndexedDB.h >index 6af93c4a9f0e75239403d8c4314bef840fa2899a..6506ceda6496fee0f67b7e030e30ccc22425d367 100644 >--- a/Source/WebCore/Modules/indexeddb/IndexedDB.h >+++ b/Source/WebCore/Modules/indexeddb/IndexedDB.h >@@ -87,12 +87,27 @@ enum KeyType { > Invalid = 0, > Array, > Binary, >+ BinaryTyped, > String, > Date, > Number, > Min, > }; > >+enum KeyBinaryType { >+ NotTyped, >+ DataView, >+ Uint8Clamped, >+ Uint8, >+ Int8, >+ Uint16, >+ Int16, >+ Uint32, >+ Int32, >+ Float32, >+ Float64, >+}; >+ > enum class RequestType { > Open, > Delete, >diff --git a/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp b/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp >index cd995e69c5980e2ba21cafbf3663ceae320ea485..a2879b1299354e96f50799b5a5fa42008f86170e 100644 >--- a/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp >+++ b/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp >@@ -127,7 +127,7 @@ The IDBKeyData serialization format is as follows: > [1 byte version header][Key Buffer] > > The Key Buffer serialization format is as follows: >-[1 byte key type][Type specific data] >+[1 byte key type][ optional 1 byte key binary type][Type specific data] > > Type specific serialization formats are as follows for each of the types: > Min: >@@ -159,6 +159,7 @@ enum class SIDBKeyType : uint8_t { > Date = 0x40, > String = 0x60, > Binary = 0x80, >+ BinaryTyped = 0x81, > Array = 0xA0, > Max = 0xFF, > }; >@@ -176,6 +177,8 @@ static SIDBKeyType serializedTypeForKeyType(IndexedDB::KeyType type) > return SIDBKeyType::String; > case IndexedDB::KeyType::Binary: > return SIDBKeyType::Binary; >+ case IndexedDB::KeyType::BinaryTyped: >+ return SIDBKeyType::BinaryTyped; > case IndexedDB::KeyType::Array: > return SIDBKeyType::Array; > case IndexedDB::KeyType::Max: >@@ -256,7 +259,10 @@ static void encodeKey(Vector<char>& data, const IDBKeyData& key) > > break; > } >- case SIDBKeyType::Binary: { >+ case SIDBKeyType::Binary: >+ case SIDBKeyType::BinaryTyped: { >+ if (type == SIDBKeyType::BinaryTyped) >+ data.append(static_cast<char>(key.binaryType())); > auto& buffer = key.binary(); > uint64_t size = buffer.size(); > writeLittleEndian(data, size); >@@ -342,7 +348,12 @@ static bool decodeKey(const uint8_t*& data, const uint8_t* end, IDBKeyData& resu > > return true; > } >- case SIDBKeyType::Binary: { >+ case SIDBKeyType::Binary: >+ case SIDBKeyType::BinaryTyped: { >+ auto binaryType = IndexedDB::KeyBinaryType::NotTyped; >+ if (type == SIDBKeyType::BinaryTyped) >+ binaryType = static_cast<IndexedDB::KeyBinaryType>(data++[0]); >+ > uint64_t size64; > if (!readLittleEndian(data, end, size64)) > return false; >@@ -359,7 +370,7 @@ static bool decodeKey(const uint8_t*& data, const uint8_t* end, IDBKeyData& resu > dataVector.append(data, size); > data += size; > >- result.setBinaryValue(ThreadSafeDataBuffer::create(WTFMove(dataVector))); >+ result.setBinaryValue(ThreadSafeDataBuffer::create(WTFMove(dataVector)), binaryType); > return true; > } > case SIDBKeyType::Array: { >diff --git a/Source/WebCore/bindings/js/IDBBindingUtilities.cpp b/Source/WebCore/bindings/js/IDBBindingUtilities.cpp >index ad9234c7cd9e2458f6764cc90c439db17f24da23..d62637224d9a0aa0c13b8275c3649845be28d06f 100644 >--- a/Source/WebCore/bindings/js/IDBBindingUtilities.cpp >+++ b/Source/WebCore/bindings/js/IDBBindingUtilities.cpp >@@ -123,6 +123,27 @@ static bool set(ExecState& exec, JSValue& object, const String& keyPathElement, > return true; > } > >+static unsigned binaryTypeElementSize(IndexedDB::KeyBinaryType binaryType) >+{ >+ switch (binaryType) { >+ case IndexedDB::KeyBinaryType::NotTyped: >+ case IndexedDB::KeyBinaryType::DataView: >+ case IndexedDB::KeyBinaryType::Uint8Clamped: >+ case IndexedDB::KeyBinaryType::Uint8: >+ case IndexedDB::KeyBinaryType::Int8: >+ return 1; >+ case IndexedDB::KeyBinaryType::Uint16: >+ case IndexedDB::KeyBinaryType::Int16: >+ return 2; >+ case IndexedDB::KeyBinaryType::Uint32: >+ case IndexedDB::KeyBinaryType::Int32: >+ case IndexedDB::KeyBinaryType::Float32: >+ return 4; >+ case IndexedDB::KeyBinaryType::Float64: >+ return 8; >+ } >+} >+ > JSValue toJS(ExecState& state, JSGlobalObject& globalObject, IDBKey* key) > { > if (!key) { >@@ -147,6 +168,7 @@ JSValue toJS(ExecState& state, JSGlobalObject& globalObject, IDBKey* key) > } > return outArray; > } >+ case IndexedDB::KeyType::BinaryTyped: > case IndexedDB::KeyType::Binary: { > auto* data = key->binary().data(); > if (!data) { >@@ -155,11 +177,53 @@ JSValue toJS(ExecState& state, JSGlobalObject& globalObject, IDBKey* key) > } > > auto arrayBuffer = ArrayBuffer::create(data->data(), data->size()); >- Structure* structure = globalObject.arrayBufferStructure(arrayBuffer->sharingMode()); >- if (!structure) >- return jsNull(); >- >- return JSArrayBuffer::create(state.vm(), structure, WTFMove(arrayBuffer)); >+ unsigned length = arrayBuffer->byteLength() / binaryTypeElementSize(key->binaryType()); >+ switch (key->binaryType()) { >+ case IndexedDB::KeyBinaryType::NotTyped: >+ if (Structure* structure = globalObject.arrayBufferStructure(arrayBuffer->sharingMode())) >+ return JSArrayBuffer::create(state.vm(), structure, WTFMove(arrayBuffer)); >+ break; >+ case IndexedDB::KeyBinaryType::DataView: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeDataView)) >+ return JSDataView::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Uint8Clamped: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeUint8Clamped)) >+ return JSUint8ClampedArray::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Uint8: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeUint8)) >+ return JSUint8Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Int8: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeInt8)) >+ return JSInt8Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Uint16: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeUint16)) >+ return JSUint16Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Int16: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeInt16)) >+ return JSInt16Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Uint32: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeUint32)) >+ return JSUint32Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Int32: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeInt32)) >+ return JSInt32Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Float32: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeFloat32)) >+ return JSFloat32Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ break; >+ case IndexedDB::KeyBinaryType::Float64: >+ if (Structure* structure = globalObject.typedArrayStructure(TypeFloat64)) >+ return JSFloat64Array::create(&state, structure, arrayBuffer.ptr(), 0, length); >+ } >+ return jsUndefined(); > } > case IndexedDB::KeyType::String: > return jsStringWithCache(&state, key->string()); >@@ -227,8 +291,30 @@ static RefPtr<IDBKey> createIDBKeyFromValue(ExecState& exec, JSValue value, Vect > if (auto* arrayBuffer = jsDynamicCast<JSArrayBuffer*>(vm, value)) > return IDBKey::createBinary(*arrayBuffer); > >- if (auto* arrayBufferView = jsDynamicCast<JSArrayBufferView*>(vm, value)) >- return IDBKey::createBinary(*arrayBufferView); >+ if (auto* arrayBufferView = jsDynamicCast<JSArrayBufferView*>(vm, value)) { >+ IndexedDB::KeyBinaryType binaryType = IndexedDB::KeyBinaryType::NotTyped; >+ if (object->inherits<JSDataView>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::DataView; >+ else if (object->inherits<JSUint8ClampedArray>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Uint8Clamped; >+ else if (object->inherits<JSUint8Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Uint8; >+ else if (object->inherits<JSInt8Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Int8; >+ else if (object->inherits<JSUint16Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Uint16; >+ else if (object->inherits<JSInt16Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Int16; >+ else if (object->inherits<JSUint32Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Uint32; >+ else if (object->inherits<JSInt32Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Int32; >+ else if (object->inherits<JSFloat32Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Float32; >+ else if (object->inherits<JSFloat64Array>(vm)) >+ binaryType = IndexedDB::KeyBinaryType::Float64; >+ return IDBKey::createBinary(*arrayBufferView, binaryType); >+ } > } > return nullptr; > } >diff --git a/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/Source/WebCore/bindings/js/SerializedScriptValue.cpp >index c4600f859d28e3635c98e5124075493a54602db5..965ece394b9832604a343bb2863b14be74fb87b4 100644 >--- a/Source/WebCore/bindings/js/SerializedScriptValue.cpp >+++ b/Source/WebCore/bindings/js/SerializedScriptValue.cpp >@@ -2136,7 +2136,7 @@ private: > RefPtr<ArrayBuffer> arrayBuffer = toPossiblySharedArrayBuffer(vm, arrayBufferObj); > switch (arrayBufferViewSubtag) { > case DataViewTag: >- arrayBufferView = getJSValue(DataView::create(WTFMove(arrayBuffer), byteOffset, length).get()); >+ arrayBufferView = toJS(m_exec, m_globalObject, DataView::create(WTFMove(arrayBuffer), byteOffset, length).get()); > return true; > case Int8ArrayTag: > arrayBufferView = toJS(m_exec, m_globalObject, Int8Array::tryCreate(WTFMove(arrayBuffer), byteOffset, length).get()); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index f7d9b7b635fcfca2a09b7d4f87a2c41cc00baf0d..527c4f36263f3979594219b661494adc91d211d3 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2019-06-24 Sihui Liu <sihui_liu@apple.com> >+ >+ REGRESSION (r244436): IndexedDB Uint8Array returned as ArrayBuffer >+ https://bugs.webkit.org/show_bug.cgi?id=198738 >+ <rdar://problem/51614053> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * storage/indexeddb/key-type-binary-expected.txt: >+ * storage/indexeddb/key-type-binary-private-expected.txt: >+ * storage/indexeddb/resources/key-type-binary.js: >+ (prepareDatabase): >+ (testBinaryKeys2): >+ (runTest): >+ (testBinaryKeys3): >+ > 2019-06-21 Sihui Liu <sihui_liu@apple.com> > > openDatabase should return an empty object when WebSQL is disabled >diff --git a/LayoutTests/storage/indexeddb/key-type-binary-expected.txt b/LayoutTests/storage/indexeddb/key-type-binary-expected.txt >index ee0e3e44aa10228c92b3bbb702f0d2d3ba65a5e3..2c22cf4d8818058385b42a3e79b112ecc37cd2f8 100644 >--- a/LayoutTests/storage/indexeddb/key-type-binary-expected.txt >+++ b/LayoutTests/storage/indexeddb/key-type-binary-expected.txt >@@ -8,6 +8,7 @@ indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self. > indexedDB.deleteDatabase(dbname) > indexedDB.open(dbname) > db.createObjectStore('store'); >+db.createObjectStore('storeWithKeyPath', {keyPath: 'binary'}); > > > testBinaryKeys1(): >@@ -53,6 +54,60 @@ store.put('value', new Float64Array([1,2,3])) > store.put('value', new Uint8Array([1,2,3]).buffer) > > store.put('value', new DataView(new Uint8Array([1,2,3]).buffer)) >+ >+testBinaryKeys3(): >+trans = db.transaction('storeWithKeyPath', 'readwrite') >+store = trans.objectStore('storeWithKeyPath') >+ >+binary = new Uint8ClampedArray([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Uint16Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Uint32Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Int8Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Int16Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Int32Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Float32Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Float64Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Uint8Array([1,2,3]).buffer >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new DataView(new Uint8Array([1,2,3]).buffer) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true > PASS successfullyParsed is true > > TEST COMPLETE >diff --git a/LayoutTests/storage/indexeddb/key-type-binary-private-expected.txt b/LayoutTests/storage/indexeddb/key-type-binary-private-expected.txt >index ee0e3e44aa10228c92b3bbb702f0d2d3ba65a5e3..2c22cf4d8818058385b42a3e79b112ecc37cd2f8 100644 >--- a/LayoutTests/storage/indexeddb/key-type-binary-private-expected.txt >+++ b/LayoutTests/storage/indexeddb/key-type-binary-private-expected.txt >@@ -8,6 +8,7 @@ indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self. > indexedDB.deleteDatabase(dbname) > indexedDB.open(dbname) > db.createObjectStore('store'); >+db.createObjectStore('storeWithKeyPath', {keyPath: 'binary'}); > > > testBinaryKeys1(): >@@ -53,6 +54,60 @@ store.put('value', new Float64Array([1,2,3])) > store.put('value', new Uint8Array([1,2,3]).buffer) > > store.put('value', new DataView(new Uint8Array([1,2,3]).buffer)) >+ >+testBinaryKeys3(): >+trans = db.transaction('storeWithKeyPath', 'readwrite') >+store = trans.objectStore('storeWithKeyPath') >+ >+binary = new Uint8ClampedArray([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Uint16Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Uint32Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Int8Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Int16Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Int32Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Float32Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Float64Array([1,2,3]) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new Uint8Array([1,2,3]).buffer >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true >+ >+binary = new DataView(new Uint8Array([1,2,3]).buffer) >+store.put({ binary }) >+request = store.get(binary) >+PASS binary.constructor === request.result.binary.constructor is true > PASS successfullyParsed is true > > TEST COMPLETE >diff --git a/LayoutTests/storage/indexeddb/resources/key-type-binary.js b/LayoutTests/storage/indexeddb/resources/key-type-binary.js >index c3f23f5118952ef100f8ca8764adb3c57bbb6f72..63318edd1131e6fdb048e30497f00955aa2c39ee 100644 >--- a/LayoutTests/storage/indexeddb/resources/key-type-binary.js >+++ b/LayoutTests/storage/indexeddb/resources/key-type-binary.js >@@ -11,6 +11,7 @@ function prepareDatabase() > db = event.target.result; > event.target.transaction.onabort = unexpectedAbortCallback; > objectStore = evalAndLog("db.createObjectStore('store');"); >+ objectStoreWithKeyPath = evalAndLog("db.createObjectStore('storeWithKeyPath', {keyPath: 'binary'});"); > debug(""); > } > >@@ -46,29 +47,54 @@ function testBinaryKeys1() > trans.oncomplete = testBinaryKeys2; > } > >+const cases = [ >+ "new Uint8ClampedArray([1,2,3])", >+ "new Uint16Array([1,2,3])", >+ "new Uint32Array([1,2,3])", >+ "new Int8Array([1,2,3])", >+ "new Int16Array([1,2,3])", >+ "new Int32Array([1,2,3])", >+ "new Float32Array([1,2,3])", >+ "new Float64Array([1,2,3])", >+ "new Uint8Array([1,2,3]).buffer", >+ "new DataView(new Uint8Array([1,2,3]).buffer)" >+]; >+ > function testBinaryKeys2() > { > preamble(); > evalAndLog("trans = db.transaction('store', 'readwrite')"); > evalAndLog("store = trans.objectStore('store')"); > >- var cases = [ >- "new Uint8ClampedArray([1,2,3])", >- "new Uint16Array([1,2,3])", >- "new Uint32Array([1,2,3])", >- "new Int8Array([1,2,3])", >- "new Int16Array([1,2,3])", >- "new Int32Array([1,2,3])", >- "new Float32Array([1,2,3])", >- "new Float64Array([1,2,3])", >- "new Uint8Array([1,2,3]).buffer", >- "new DataView(new Uint8Array([1,2,3]).buffer)" >- ]; >- > cases.forEach(function(testCase) { > debug(""); > evalAndLog("store.put('value', " + testCase + ")"); > }); > >- finishJSTest(); >+ trans.oncomplete = testBinaryKeys3; > } >+ >+function runTest(testNumber) { >+ debug(""); >+ evalAndLog("binary = " + cases[testNumber]); >+ evalAndLog("store.put({ binary })"); >+ evalAndLog("request = store.get(binary)"); >+ request.onsuccess = ()=>{ >+ shouldBeTrue("binary.constructor === request.result.binary.constructor"); >+ >+ if (++testNumber == cases.length) >+ finishJSTest(); >+ else >+ runTest(testNumber); >+ } >+ request.onerror = unexpectedErrorCallback; >+} >+ >+function testBinaryKeys3() >+{ >+ preamble(); >+ evalAndLog("trans = db.transaction('storeWithKeyPath', 'readwrite')"); >+ evalAndLog("store = trans.objectStore('storeWithKeyPath')"); >+ >+ runTest(0); >+} >\ No newline at end of file
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198738
:
371805
|
371806
|
372785
|
372792
|
372796
|
372798
|
372800
|
372803