(Hidden by Administrator)
Bug 1577107 Comment 0 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
```cpp
void IDBObjectStore::AppendIndexUpdateInfo(
int64_t aIndexID, const KeyPath& aKeyPath, bool aUnique, bool aMultiEntry,
const nsCString& aLocale, JSContext* aCx, JS::Handle<JS::Value> aVal,
nsTArray<IndexUpdateInfo>& aUpdateInfoArray, ErrorResult& aRv) {
const bool localeAware = !aLocale.IsEmpty();
if (!aMultiEntry) {
...
return;
}
JS::Rooted<JS::Value> val(aCx);
if (NS_FAILED(aKeyPath.ExtractKeyAsJSVal(aCx, aVal, val.address()))) {
return;
}
bool isArray;
if (!JS_IsArrayObject(aCx, val, &isArray)) {
IDB_REPORT_INTERNAL_ERR();
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
return;
}
if (isArray) {
JS::Rooted<JSObject*> array(aCx, &val.toObject());
uint32_t arrayLength;
if (NS_WARN_IF(!JS_GetArrayLength(aCx, array, &arrayLength))) {
IDB_REPORT_INTERNAL_ERR();
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
return;
}
for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
JS::Rooted<JS::Value> arrayItem(aCx);
if (NS_WARN_IF(!JS_GetElement(aCx, array, arrayIndex, &arrayItem))) { // JS_GetElement can trigger js getter, call deleteIndex here will free `aLocale`.
IDB_REPORT_INTERNAL_ERR();
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
return;
}
Key value;
auto result = value.SetFromJSVal(aCx, arrayItem, aRv);
if (!result.Is(Ok, aRv) || value.IsUnset()) {
// Not a value we can do anything with, ignore it.
aRv.SuppressException();
continue;
}
IndexUpdateInfo* updateInfo = aUpdateInfoArray.AppendElement();
updateInfo->indexId() = aIndexID;
updateInfo->value() = value;
if (localeAware) {
auto result =
value.ToLocaleBasedKey(updateInfo->localizedValue(), aLocale, aRv);// UAF occurs!
if (NS_WARN_IF(!result.Is(Ok, aRv))) {
if (result.Is(Invalid, aRv)) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
return;
}
}
}
} else {
...
}
}
```