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.

(Hidden by Administrator)
```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 {
	...
  }
}
```

Back to Bug 1577107 Comment 0