summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-09-04 21:04:07 +0200
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-09-04 21:04:07 +0200
commit4d4924e5105dbdfdcc3ff821671fba0dfeb11b11 (patch)
treebd337bd4c029744be88847e506b7e03da79e7093
parent4266966eeef44dfce422b9703692e519678610c6 (diff)
downloaduxp-4d4924e5105dbdfdcc3ff821671fba0dfeb11b11.tar.gz
Fix a crash in IndexedDB.
-rw-r--r--dom/indexedDB/IDBCursor.cpp8
-rw-r--r--dom/indexedDB/IDBFactory.cpp4
-rw-r--r--dom/indexedDB/IDBKeyRange.cpp2
-rw-r--r--dom/indexedDB/IDBObjectStore.cpp15
-rw-r--r--dom/indexedDB/Key.cpp38
-rw-r--r--dom/indexedDB/Key.h15
-rw-r--r--dom/indexedDB/KeyPath.cpp22
-rw-r--r--dom/indexedDB/KeyPath.h12
-rw-r--r--js/src/jsapi.cpp22
-rw-r--r--js/src/jsapi.h3
10 files changed, 102 insertions, 39 deletions
diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp
index af88742f0d..be0295dc76 100644
--- a/dom/indexedDB/IDBCursor.cpp
+++ b/dom/indexedDB/IDBCursor.cpp
@@ -430,7 +430,7 @@ IDBCursor::Continue(JSContext* aCx,
}
Key key;
- aRv = key.SetFromJSVal(aCx, aKey);
+ aRv = key.SetFromJSVal(aCx, aKey, /* aCallGetters */ true);
if (aRv.Failed()) {
return;
}
@@ -536,7 +536,7 @@ IDBCursor::ContinuePrimaryKey(JSContext* aCx,
}
Key key;
- aRv = key.SetFromJSVal(aCx, aKey);
+ aRv = key.SetFromJSVal(aCx, aKey, /* aCallGetters */ true);
if (aRv.Failed()) {
return;
}
@@ -558,7 +558,7 @@ IDBCursor::ContinuePrimaryKey(JSContext* aCx,
}
Key primaryKey;
- aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey);
+ aRv = primaryKey.SetFromJSVal(aCx, aPrimaryKey, /* aCallGetters */ true);
if (aRv.Failed()) {
return;
}
@@ -718,7 +718,7 @@ IDBCursor::Update(JSContext* aCx, JS::Handle<JS::Value> aValue,
const KeyPath& keyPath = objectStore->GetKeyPath();
Key key;
- aRv = keyPath.ExtractKey(aCx, aValue, key);
+ aRv = keyPath.ExtractKey(aCx, aValue, key, /* aCallGetters */ false);
if (aRv.Failed()) {
return nullptr;
}
diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp
index c1ef6353d4..66471fe24b 100644
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -482,13 +482,13 @@ IDBFactory::Cmp(JSContext* aCx, JS::Handle<JS::Value> aFirst,
JS::Handle<JS::Value> aSecond, ErrorResult& aRv)
{
Key first, second;
- nsresult rv = first.SetFromJSVal(aCx, aFirst);
+ nsresult rv = first.SetFromJSVal(aCx, aFirst, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
}
- rv = second.SetFromJSVal(aCx, aSecond);
+ rv = second.SetFromJSVal(aCx, aSecond, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
diff --git a/dom/indexedDB/IDBKeyRange.cpp b/dom/indexedDB/IDBKeyRange.cpp
index e61c806177..168fb4a5a5 100644
--- a/dom/indexedDB/IDBKeyRange.cpp
+++ b/dom/indexedDB/IDBKeyRange.cpp
@@ -24,7 +24,7 @@ GetKeyFromJSVal(JSContext* aCx,
JS::Handle<JS::Value> aVal,
Key& aKey)
{
- nsresult rv = aKey.SetFromJSVal(aCx, aVal);
+ nsresult rv = aKey.SetFromJSVal(aCx, aVal, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
MOZ_ASSERT(NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_DOM_INDEXEDDB);
return rv;
diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp
index 756792741f..f86c619a72 100644
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1084,7 +1084,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
if (!aMultiEntry) {
Key key;
- rv = aKeyPath.ExtractKey(aCx, aVal, key);
+ rv = aKeyPath.ExtractKey(aCx, aVal, key, /* aCallGetters */ false);
// If an index's keyPath doesn't match an object, we ignore that object.
if (rv == NS_ERROR_DOM_INDEXEDDB_DATA_ERR || key.IsUnset()) {
@@ -1128,13 +1128,13 @@ IDBObjectStore::AppendIndexUpdateInfo(
for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
JS::Rooted<JS::Value> arrayItem(aCx);
- if (NS_WARN_IF(!JS_GetElement(aCx, array, arrayIndex, &arrayItem))) {
+ if (NS_WARN_IF(!JS_GetOwnElement(aCx, array, arrayIndex, &arrayItem))) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
Key value;
- if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem)) ||
+ if (NS_FAILED(value.SetFromJSVal(aCx, arrayItem, /* aCallGetters */ false)) ||
value.IsUnset()) {
// Not a value we can do anything with, ignore it.
continue;
@@ -1153,7 +1153,7 @@ IDBObjectStore::AppendIndexUpdateInfo(
}
else {
Key value;
- if (NS_FAILED(value.SetFromJSVal(aCx, val)) ||
+ if (NS_FAILED(value.SetFromJSVal(aCx, val, /* aCallGetters */ false)) ||
value.IsUnset()) {
// Not a value we can do anything with, ignore it.
return NS_OK;
@@ -1324,12 +1324,12 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
if (!HasValidKeyPath()) {
// Out-of-line keys must be passed in.
- rv = aKey.SetFromJSVal(aCx, aKeyVal);
+ rv = aKey.SetFromJSVal(aCx, aKeyVal, /* aCallGetters */ true);
if (NS_FAILED(rv)) {
return rv;
}
} else if (!isAutoIncrement) {
- rv = GetKeyPath().ExtractKey(aCx, aValue, aKey);
+ rv = GetKeyPath().ExtractKey(aCx, aValue, aKey, /* aCallGetters */ false);
if (NS_FAILED(rv)) {
return rv;
}
@@ -1368,7 +1368,8 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
aValue,
aKey,
&GetAddInfoCallback,
- &data);
+ &data,
+ /* aCallGetters */ false);
} else {
rv = GetAddInfoCallback(aCx, &data);
}
diff --git a/dom/indexedDB/Key.cpp b/dom/indexedDB/Key.cpp
index 0f693b2c61..575734af28 100644
--- a/dom/indexedDB/Key.cpp
+++ b/dom/indexedDB/Key.cpp
@@ -201,8 +201,11 @@ Key::ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const
}
nsresult
-Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
- uint8_t aTypeOffset, uint16_t aRecursionDepth)
+Key::EncodeJSValInternal(JSContext* aCx,
+ JS::Handle<JS::Value> aVal,
+ uint8_t aTypeOffset,
+ uint16_t aRecursionDepth,
+ bool aCallGetters)
{
static_assert(eMaxType * kMaxArrayCollapse < 256,
"Unable to encode jsvals.");
@@ -257,13 +260,18 @@ Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
for (uint32_t index = 0; index < length; index++) {
JS::Rooted<JS::Value> val(aCx);
- if (!JS_GetElement(aCx, obj, index, &val)) {
+ bool ok = aCallGetters ? JS_GetElement(aCx, obj, index, &val)
+ : JS_GetOwnElement(aCx, obj, index, &val);
+ if (!ok) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
- nsresult rv = EncodeJSValInternal(aCx, val, aTypeOffset,
- aRecursionDepth + 1);
+ nsresult rv = EncodeJSValInternal(aCx,
+ val,
+ aTypeOffset,
+ aRecursionDepth + 1,
+ aCallGetters);
if (NS_FAILED(rv)) {
return rv;
}
@@ -406,9 +414,10 @@ Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
nsresult
Key::EncodeJSVal(JSContext* aCx,
JS::Handle<JS::Value> aVal,
- uint8_t aTypeOffset)
+ uint8_t aTypeOffset,
+ bool aCallGetters)
{
- return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0);
+ return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0, aCallGetters);
}
void
@@ -741,7 +750,8 @@ Key::SetFromValueArray(mozIStorageValueArray* aValues,
nsresult
Key::SetFromJSVal(JSContext* aCx,
- JS::Handle<JS::Value> aVal)
+ JS::Handle<JS::Value> aVal,
+ bool aCallGetters)
{
mBuffer.Truncate();
@@ -750,7 +760,7 @@ Key::SetFromJSVal(JSContext* aCx,
return NS_OK;
}
- nsresult rv = EncodeJSVal(aCx, aVal, 0);
+ nsresult rv = EncodeJSVal(aCx, aVal, 0, aCallGetters);
if (NS_FAILED(rv)) {
Unset();
return rv;
@@ -793,9 +803,15 @@ Key::ToJSVal(JSContext* aCx,
}
nsresult
-Key::AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal)
+Key::AppendItem(JSContext* aCx,
+ bool aFirstOfArray,
+ JS::Handle<JS::Value> aVal,
+ bool aCallGetters)
{
- nsresult rv = EncodeJSVal(aCx, aVal, aFirstOfArray ? eMaxType : 0);
+ nsresult rv = EncodeJSVal(aCx,
+ aVal,
+ aFirstOfArray ? eMaxType : 0,
+ aCallGetters);
if (NS_FAILED(rv)) {
Unset();
return rv;
diff --git a/dom/indexedDB/Key.h b/dom/indexedDB/Key.h
index 9d70ce6ad0..a4fb65b484 100644
--- a/dom/indexedDB/Key.h
+++ b/dom/indexedDB/Key.h
@@ -203,7 +203,7 @@ public:
}
nsresult
- SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal);
+ SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, bool aCallGetters);
nsresult
ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const;
@@ -212,7 +212,10 @@ public:
ToJSVal(JSContext* aCx, JS::Heap<JS::Value>& aVal) const;
nsresult
- AppendItem(JSContext* aCx, bool aFirstOfArray, JS::Handle<JS::Value> aVal);
+ AppendItem(JSContext* aCx,
+ bool aFirstOfArray,
+ JS::Handle<JS::Value> aVal,
+ bool aCallGetters);
nsresult
ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const;
@@ -283,7 +286,10 @@ private:
// Encoding functions. These append the encoded value to the end of mBuffer
nsresult
- EncodeJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, uint8_t aTypeOffset);
+ EncodeJSVal(JSContext* aCx,
+ JS::Handle<JS::Value> aVal,
+ uint8_t aTypeOffset,
+ bool aCallGetters);
void
EncodeString(const nsAString& aString, uint8_t aTypeOffset);
@@ -331,7 +337,8 @@ private:
EncodeJSValInternal(JSContext* aCx,
JS::Handle<JS::Value> aVal,
uint8_t aTypeOffset,
- uint16_t aRecursionDepth);
+ uint16_t aRecursionDepth,
+ bool aCallGetters);
static nsresult
DecodeJSValInternal(const unsigned char*& aPos,
diff --git a/dom/indexedDB/KeyPath.cpp b/dom/indexedDB/KeyPath.cpp
index 30edd8cd7a..0221c94500 100644
--- a/dom/indexedDB/KeyPath.cpp
+++ b/dom/indexedDB/KeyPath.cpp
@@ -372,11 +372,13 @@ KeyPath::AppendStringWithValidation(const nsAString& aString)
}
nsresult
-KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const
+KeyPath::ExtractKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
+ bool aCallGetters) const
{
uint32_t len = mStrings.Length();
JS::Rooted<JS::Value> value(aCx);
-
aKey.Unset();
for (uint32_t i = 0; i < len; ++i) {
@@ -388,7 +390,10 @@ KeyPath::ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const
return rv;
}
- if (NS_FAILED(aKey.AppendItem(aCx, IsArray() && i == 0, value))) {
+ if (NS_FAILED(aKey.AppendItem(aCx,
+ IsArray() && i == 0,
+ value,
+ aCallGetters))) {
NS_ASSERTION(aKey.IsUnset(), "Encoding error should unset");
return NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
@@ -437,9 +442,12 @@ KeyPath::ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
}
nsresult
-KeyPath::ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue,
- Key& aKey, ExtractOrCreateKeyCallback aCallback,
- void* aClosure) const
+KeyPath::ExtractOrCreateKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
+ ExtractOrCreateKeyCallback aCallback,
+ void* aClosure,
+ bool aCallGetters) const
{
NS_ASSERTION(IsString(), "This doesn't make sense!");
@@ -455,7 +463,7 @@ KeyPath::ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue,
return rv;
}
- if (NS_FAILED(aKey.AppendItem(aCx, false, value))) {
+ if (NS_FAILED(aKey.AppendItem(aCx, false, value, aCallGetters))) {
NS_ASSERTION(aKey.IsUnset(), "Should be unset");
return value.isUndefined() ? NS_OK : NS_ERROR_DOM_INDEXEDDB_DATA_ERR;
}
diff --git a/dom/indexedDB/KeyPath.h b/dom/indexedDB/KeyPath.h
index c133cdc4a4..e6e5f57d40 100644
--- a/dom/indexedDB/KeyPath.h
+++ b/dom/indexedDB/KeyPath.h
@@ -72,7 +72,10 @@ public:
Parse(const Nullable<OwningStringOrStringSequence>& aValue, KeyPath* aKeyPath);
nsresult
- ExtractKey(JSContext* aCx, const JS::Value& aValue, Key& aKey) const;
+ ExtractKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
+ bool aCallGetters) const;
nsresult
ExtractKeyAsJSVal(JSContext* aCx, const JS::Value& aValue,
@@ -82,9 +85,12 @@ public:
(*ExtractOrCreateKeyCallback)(JSContext* aCx, void* aClosure);
nsresult
- ExtractOrCreateKey(JSContext* aCx, const JS::Value& aValue, Key& aKey,
+ ExtractOrCreateKey(JSContext* aCx,
+ const JS::Value& aValue,
+ Key& aKey,
ExtractOrCreateKeyCallback aCallback,
- void* aClosure) const;
+ void* aClosure,
+ bool aCallGetters) const;
inline bool IsValid() const {
return mType != NONEXISTENT;
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
index 84a3155872..cad0840e03 100644
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2011,6 +2011,28 @@ JS_GetOwnUCPropertyDescriptor(JSContext* cx, HandleObject obj, const char16_t* n
}
JS_PUBLIC_API(bool)
+JS_GetOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp)
+{
+ RootedId id(cx);
+ if (!IndexToId(cx, index, &id)) {
+ return false;
+ }
+
+ Rooted<PropertyDescriptor> desc(cx);
+ if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, &desc)) {
+ return false;
+ }
+
+ if (desc.object() && desc.isDataDescriptor()) {
+ vp.set(desc.value());
+ } else {
+ vp.setUndefined();
+ }
+
+ return true;
+}
+
+JS_PUBLIC_API(bool)
JS_GetPropertyDescriptorById(JSContext* cx, HandleObject obj, HandleId id,
MutableHandle<PropertyDescriptor> desc)
{
diff --git a/js/src/jsapi.h b/js/src/jsapi.h
index 67b3d42670..dc00c650d4 100644
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2922,6 +2922,9 @@ extern JS_PUBLIC_API(bool)
JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
JS::MutableHandle<JS::PropertyDescriptor> desc);
+extern JS_PUBLIC_API(bool)
+JS_GetOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
+
/**
* Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
* if no own property is found directly on obj. The object on which the