Bug 726376: Prevent infinite recursion in indexedDB::cmp. r=sicking

This commit is contained in:
Kyle Huey 2012-05-11 10:47:27 -07:00
parent 683f9c1ac7
commit 74a295727d
5 changed files with 46 additions and 11 deletions

View File

@ -131,15 +131,20 @@ USING_INDEXEDDB_NAMESPACE
const int MaxArrayCollapse = 3;
const int MaxRecursionDepth = 256;
nsresult
Key::EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset)
Key::EncodeJSValInternal(JSContext* aCx, const jsval aVal,
PRUint8 aTypeOffset, PRUint16 aRecursionDepth)
{
NS_ENSURE_TRUE(aRecursionDepth < MaxRecursionDepth, NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
PR_STATIC_ASSERT(eMaxType * MaxArrayCollapse < 256);
if (JSVAL_IS_STRING(aVal)) {
nsDependentJSString str;
if (!str.init(aCx, aVal)) {
return NS_ERROR_OUT_OF_MEMORY;
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
EncodeString(str, aTypeOffset);
return NS_OK;
@ -183,7 +188,8 @@ Key::EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset)
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsresult rv = EncodeJSVal(aCx, val, aTypeOffset);
nsresult rv = EncodeJSValInternal(aCx, val, aTypeOffset,
aRecursionDepth + 1);
NS_ENSURE_SUCCESS(rv, rv);
aTypeOffset = 0;
@ -205,9 +211,12 @@ Key::EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset)
// static
nsresult
Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
JSContext* aCx, PRUint8 aTypeOffset, jsval* aVal)
Key::DecodeJSValInternal(const unsigned char*& aPos, const unsigned char* aEnd,
JSContext* aCx, PRUint8 aTypeOffset, jsval* aVal,
PRUint16 aRecursionDepth)
{
NS_ENSURE_TRUE(aRecursionDepth < MaxRecursionDepth, NS_ERROR_DOM_INDEXEDDB_DATA_ERR);
if (*aPos - aTypeOffset >= eArray) {
JSObject* array = JS_NewArrayObject(aCx, 0, nsnull);
if (!array) {
@ -225,7 +234,8 @@ Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
uint32_t index = 0;
while (aPos < aEnd && *aPos - aTypeOffset != eTerminator) {
jsval val;
nsresult rv = DecodeJSVal(aPos, aEnd, aCx, aTypeOffset, &val);
nsresult rv = DecodeJSValInternal(aPos, aEnd, aCx, aTypeOffset,
&val, aRecursionDepth + 1);
NS_ENSURE_SUCCESS(rv, rv);
aTypeOffset = 0;
@ -269,7 +279,6 @@ Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
return NS_OK;
}
#define ONE_BYTE_LIMIT 0x7E
#define TWO_BYTE_LIMIT (0x3FFF+0x7F)

View File

@ -291,15 +291,23 @@ private:
}
// Encoding functions. These append the encoded value to the end of mBuffer
nsresult EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset);
inline nsresult EncodeJSVal(JSContext* aCx, const jsval aVal,
PRUint8 aTypeOffset)
{
return EncodeJSValInternal(aCx, aVal, aTypeOffset, 0);
}
void EncodeString(const nsAString& aString, PRUint8 aTypeOffset);
void EncodeNumber(double aFloat, PRUint8 aType);
// Decoding functions. aPos points into mBuffer and is adjusted to point
// past the consumed value.
static nsresult DecodeJSVal(const unsigned char*& aPos,
const unsigned char* aEnd, JSContext* aCx,
PRUint8 aTypeOffset, jsval* aVal);
static inline nsresult DecodeJSVal(const unsigned char*& aPos,
const unsigned char* aEnd, JSContext* aCx,
PRUint8 aTypeOffset, jsval* aVal)
{
return DecodeJSValInternal(aPos, aEnd, aCx, aTypeOffset, aVal, 0);
}
static void DecodeString(const unsigned char*& aPos,
const unsigned char* aEnd,
nsString& aString);
@ -307,6 +315,15 @@ private:
const unsigned char* aEnd);
nsCString mBuffer;
private:
nsresult EncodeJSValInternal(JSContext* aCx, const jsval aVal,
PRUint8 aTypeOffset, PRUint16 aRecursionDepth);
static nsresult DecodeJSValInternal(const unsigned char*& aPos,
const unsigned char* aEnd,
JSContext* aCx, PRUint8 aTypeOffset,
jsval* aVal, PRUint16 aRecursionDepth);
};
END_INDEXEDDB_NAMESPACE

View File

@ -0,0 +1,7 @@
<script>
var a = [];
a[0] = a;
mozIndexedDB.cmp.bind(mozIndexedDB)(a, a);
</script>

View File

@ -0,0 +1 @@
load 726376-1.html

View File

@ -23,6 +23,7 @@ include ../../content/media/test/crashtests/crashtests.list
include ../../docshell/base/crashtests/crashtests.list
include ../../dom/base/crashtests/crashtests.list
include ../../dom/indexedDB/crashtests/crashtests.list
include ../../dom/src/offline/crashtests/crashtests.list
include ../../dom/src/jsurl/crashtests/crashtests.list