diff --git a/dom/base/crashtests/601247.html b/dom/base/crashtests/601247.html new file mode 100644 index 000000000000..6eb9f46574e5 --- /dev/null +++ b/dom/base/crashtests/601247.html @@ -0,0 +1,8 @@ + + diff --git a/dom/base/crashtests/crashtests.list b/dom/base/crashtests/crashtests.list index c28df66bd23d..f380031fbd6a 100644 --- a/dom/base/crashtests/crashtests.list +++ b/dom/base/crashtests/crashtests.list @@ -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 diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 3590cec795f0..96f236299b0b 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -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 storage(do_QueryWrappedNative(wrapper)); + + // XXXndeakin need to free the keys afterwards + nsTArray *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 *keys = (nsTArray *)JSVAL_TO_PRIVATE(*statep); - switch (enum_op) { - case JSENUMERATE_INIT: - case JSENUMERATE_INIT_ALL: - { - nsCOMPtr storage(do_QueryWrappedNative(wrapper)); + if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) { + nsString& key = keys->ElementAt(0); + JSString *str = + JS_NewUCStringCopyN(cx, reinterpret_cast + (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 - (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 storage(do_QueryWrappedNative(wrapper)); + + // XXXndeakin need to free the keys afterwards + nsTArray *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 *keys = (nsTArray *)JSVAL_TO_PRIVATE(*statep); - switch (enum_op) { - case JSENUMERATE_INIT: - case JSENUMERATE_INIT_ALL: - { - nsCOMPtr storage(do_QueryWrappedNative(wrapper)); + if (enum_op == JSENUMERATE_NEXT && keys->Length() != 0) { + nsString& key = keys->ElementAt(0); + JSString *str = + JS_NewUCStringCopyN(cx, reinterpret_cast + (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 - (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; }