← All issues

IDBIndex::getAllRecords() Implementation

fc3f6a3

Source/WebCore/Modules/indexeddb/IDBRecord.idl

+interface IDBRecord {
+ readonly attribute any key;
+ readonly attribute any primaryKey;
+ readonly attribute any value;
+};

Source/WebCore/bindings/js/JSIDBRecordCustom.cpp

+JSValue JSIDBRecord::value(JSGlobalObject& lexicalGlobalObject) const
+{
+ auto& vm = lexicalGlobalObject.vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ auto* idbRecord = wrapped();
+ auto result = deserializeIDBValueWithKeyInjection(lexicalGlobalObject,
+ idbRecord->value(), idbRecord->primaryKey(), idbRecord->keyPath());
+ RETURN_IF_EXCEPTION(scope, { });
+ return result;
+}

Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

+if (type == IndexedDB::GetAllType::Records) {
+ result.addKey(WTFMove(indexKey));
+ result.addPrimaryKey(WTFMove(primaryKey)); // NEW
+ result.addValue(WTFMove(value));
+}

WebKit의 IndexedDB는 여러 계층에 걸쳐 구현되어 있습니다. JS binding 계층은 내부 IDBKeyData/IDBValue 타입을 JS 값으로 변환하고, 중간 계층인 IDBIndexIDBTransaction은 요청을 관리하며 IDBGetAllResult를 통해 결과를 전달합니다. backing store인 SQLiteIDBBackingStore는 SQL 쿼리를 실행하여 결과를 채우고, IPC serialization이 이를 프로세스 경계 너머로 전달합니다. 이 commit은 W3C 스펙에 따라 IDBIndex::getAllRecords()를 구현했으며, key, primaryKey, value 속성을 가진 IDBRecord 객체 배열을 반환합니다.

의미론적으로 중요한 차이가 있습니다. 기존 Keys/Values case에서 result의 "key"는 실제로 object store record의 primary key를 가리킵니다. 반면 새로 추가된 Records case에서는 "key"가 index key를 의미하고, "primaryKey"는 별도로 object store record의 key를 나타냅니다. 이 미묘한 역전 관계는 모든 계층에서 일관되게 적용되어야 합니다. 한편 JSIDBRecord의 value getter는 property 접근 시점에 deserializeIDBValueWithKeyInjection()을 호출하여 inline-keyed 객체를 재구성합니다. 이 deserialization 경로는 JSIDBRequest에서도 사용되는 것으로, 역사적으로 버그의 원인이 된 지점입니다.

JS caller
  └─► IDBIndex::getAllRecords(IDBGetAllOptions)
            │  doGetAllShared(GetAllType::Records)
            ▼
      IDBTransaction::requestGetAllObjectStoreRecords
            │
            ▼
      SQLiteIDBBackingStore::getAllIndexRecords
            │  key       → index key
            │  primaryKey → object store key     ← NEW semantics
            │  value     → serialized IDBValue
            ▼
      IDBGetAllResult { keys[], primaryKeys[], values[] }
            │
      JSIDBRecord::{key,primaryKey,value} custom getters
            └─ value: deserializeIDBValueWithKeyInjection()

JS binding, IPC serialization, SQLite backend 전 계층에 걸쳐 새롭게 노출된 JS 접근 가능 API surface로, 각 계층마다 신뢰할 수 없는 데이터를 처리하는 새로운 code path가 도입되었습니다.

🔒

New multi-array result type with cross-layer semantic constraints — audit directions cover data alignment, key identity, and deserialization timing.

더 확인하려면 구독해 주세요