Bug 601247. Don't JSVAL_TO_PRIVATE a random jsval. r=jst

This commit is contained in:
Boris Zbarsky 2010-10-15 17:55:53 -04:00
Родитель 7b1f7cd7d1
Коммит 85fcbc7a6d
3 изменённых файлов: 75 добавлений и 82 удалений

Просмотреть файл

@ -0,0 +1,8 @@
<!DOCTYPE html>
<script>
var x = document.createTextNode("x");
x.__proto__ = localStorage;
for (var p in x) {};
</script>

Просмотреть файл

@ -22,3 +22,4 @@ load 499006-1.html
load 499006-2.html
load 502617.html
asserts(1) load 504224.html # bug 564098
load 601247.html

Просмотреть файл

@ -10174,55 +10174,47 @@ nsStorageSH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep,
jsid *idp, PRBool *_retval)
{
if (enum_op == JSENUMERATE_INIT || enum_op == JSENUMERATE_INIT_ALL) {
nsCOMPtr<nsPIDOMStorage> storage(do_QueryWrappedNative(wrapper));
// XXXndeakin need to free the keys afterwards
nsTArray<nsString> *keys = storage->GetKeys();
NS_ENSURE_TRUE(keys, NS_ERROR_OUT_OF_MEMORY);
*statep = PRIVATE_TO_JSVAL(keys);
if (idp) {
*idp = INT_TO_JSID(keys->Length());
}
return NS_OK;
}
nsTArray<nsString> *keys =
(nsTArray<nsString> *)JSVAL_TO_PRIVATE(*statep);
switch (enum_op) {
case JSENUMERATE_INIT:
case JSENUMERATE_INIT_ALL:
{
nsCOMPtr<nsPIDOMStorage> storage(do_QueryWrappedNative(wrapper));
if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) {
nsString& key = keys->ElementAt(0);
JSString *str =
JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar *>
(key.get()),
key.Length());
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
// XXXndeakin need to free the keys afterwards
keys = storage->GetKeys();
NS_ENSURE_TRUE(keys, NS_ERROR_OUT_OF_MEMORY);
JS_ValueToId(cx, STRING_TO_JSVAL(str), idp);
*statep = PRIVATE_TO_JSVAL(keys);
keys->RemoveElementAt(0);
if (idp) {
*idp = INT_TO_JSID(keys->Length());
}
break;
}
case JSENUMERATE_NEXT:
if (keys->Length() != 0) {
nsString& key = keys->ElementAt(0);
JSString *str =
JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar *>
(key.get()),
key.Length());
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
JS_ValueToId(cx, STRING_TO_JSVAL(str), idp);
keys->RemoveElementAt(0);
break;
}
// Fall through
case JSENUMERATE_DESTROY:
delete keys;
*statep = JSVAL_NULL;
break;
default:
NS_NOTREACHED("Bad call from the JS engine");
return NS_ERROR_FAILURE;
return NS_OK;
}
// destroy the keys array if we have no keys or if we're done
NS_ABORT_IF_FALSE(enum_op == JSENUMERATE_DESTROY ||
(enum_op == JSENUMERATE_NEXT && keys->Length() == 0),
"Bad call from the JS engine");
delete keys;
*statep = JSVAL_NULL;
return NS_OK;
}
@ -10376,55 +10368,47 @@ nsStorage2SH::NewEnumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, PRUint32 enum_op, jsval *statep,
jsid *idp, PRBool *_retval)
{
if (enum_op == JSENUMERATE_INIT || enum_op == JSENUMERATE_INIT_ALL) {
nsCOMPtr<nsPIDOMStorage> storage(do_QueryWrappedNative(wrapper));
// XXXndeakin need to free the keys afterwards
nsTArray<nsString> *keys = storage->GetKeys();
NS_ENSURE_TRUE(keys, NS_ERROR_OUT_OF_MEMORY);
*statep = PRIVATE_TO_JSVAL(keys);
if (idp) {
*idp = INT_TO_JSID(keys->Length());
}
return NS_OK;
}
nsTArray<nsString> *keys =
(nsTArray<nsString> *)JSVAL_TO_PRIVATE(*statep);
switch (enum_op) {
case JSENUMERATE_INIT:
case JSENUMERATE_INIT_ALL:
{
nsCOMPtr<nsPIDOMStorage> storage(do_QueryWrappedNative(wrapper));
if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) {
nsString& key = keys->ElementAt(0);
JSString *str =
JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar *>
(key.get()),
key.Length());
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
// XXXndeakin need to free the keys afterwards
keys = storage->GetKeys();
NS_ENSURE_TRUE(keys, NS_ERROR_OUT_OF_MEMORY);
JS_ValueToId(cx, STRING_TO_JSVAL(str), idp);
*statep = PRIVATE_TO_JSVAL(keys);
keys->RemoveElementAt(0);
if (idp) {
*idp = INT_TO_JSID(keys->Length());
}
break;
}
case JSENUMERATE_NEXT:
if (keys->Length() != 0) {
nsString& key = keys->ElementAt(0);
JSString *str =
JS_NewUCStringCopyN(cx, reinterpret_cast<const jschar *>
(key.get()),
key.Length());
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
JS_ValueToId(cx, STRING_TO_JSVAL(str), idp);
keys->RemoveElementAt(0);
break;
}
// Fall through
case JSENUMERATE_DESTROY:
delete keys;
*statep = JSVAL_NULL;
break;
default:
NS_NOTREACHED("Bad call from the JS engine");
return NS_ERROR_FAILURE;
return NS_OK;
}
// destroy the keys array if we have no keys or if we're done
NS_ABORT_IF_FALSE(enum_op == JSENUMERATE_DESTROY ||
(enum_op == JSENUMERATE_NEXT && keys->Length() == 0),
"Bad call from the JS engine");
delete keys;
*statep = JSVAL_NULL;
return NS_OK;
}