diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index b2b21ee34ec..441c41b451b 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -107,7 +107,15 @@ AtomTableGetHash(PLDHashTable *table, const void *key) const AtomTableKey *k = static_cast(key); if (k->mUTF8String) { - return nsCRT::HashCodeAsUTF16(k->mUTF8String, k->mLength);; + PRBool err; + PRUint32 hash = nsCRT::HashCodeAsUTF16(k->mUTF8String, k->mLength, &err); + if (err) { + AtomTableKey* mutableKey = const_cast(k); + mutableKey->mUTF8String = nsnull; + mutableKey->mLength = 0; + hash = 0; + } + return hash; } return nsCRT::HashCode(k->mUTF16String, k->mLength); diff --git a/xpcom/ds/nsCRT.cpp b/xpcom/ds/nsCRT.cpp index 06ac61c33d2..ca1f49997b5 100644 --- a/xpcom/ds/nsCRT.cpp +++ b/xpcom/ds/nsCRT.cpp @@ -253,17 +253,19 @@ PRUint32 nsCRT::HashCode(const PRUnichar* start, PRUint32 length) return h; } -PRUint32 nsCRT::HashCodeAsUTF16(const char* start, PRUint32 length) +PRUint32 nsCRT::HashCodeAsUTF16(const char* start, PRUint32 length, + PRBool* err) { PRUint32 h = 0; const char* s = start; const char* end = start + length; + *err = PR_FALSE; + while ( s < end ) { - PRBool err; - PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, &err); - if (err) { + PRUint32 ucs4 = UTF8CharEnumerator::NextChar(&s, end, err); + if (*err) { return 0; } diff --git a/xpcom/ds/nsCRT.h b/xpcom/ds/nsCRT.h index 8901130adff..9096b702485 100644 --- a/xpcom/ds/nsCRT.h +++ b/xpcom/ds/nsCRT.h @@ -242,7 +242,8 @@ public: // Computes a hashcode for a length number of UTF8 // characters. Returns the same hash code as the HashCode method // taking a |PRUnichar*| would if the string were converted to UTF16. - static PRUint32 HashCodeAsUTF16(const char* start, PRUint32 length); + static PRUint32 HashCodeAsUTF16(const char* start, PRUint32 length, + PRBool* err); // String to longlong static PRInt64 atoll(const char *str); diff --git a/xpcom/tests/TestUTF.cpp b/xpcom/tests/TestUTF.cpp index 8dfbbb53595..01d45d4bbc5 100644 --- a/xpcom/tests/TestUTF.cpp +++ b/xpcom/tests/TestUTF.cpp @@ -145,21 +145,27 @@ test_hashas16() { for (unsigned int i = 0; i < NS_ARRAY_LENGTH(ValidStrings); ++i) { nsDependentCString str8(ValidStrings[i].m8); + PRBool err; if (nsCRT::HashCode(ValidStrings[i].m16) != - nsCRT::HashCodeAsUTF16(str8.get(), str8.Length())) + nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) || + err) return PR_FALSE; } for (unsigned int i = 0; i < NS_ARRAY_LENGTH(Invalid8Strings); ++i) { nsDependentCString str8(Invalid8Strings[i].m8); + PRBool err; if (nsCRT::HashCode(Invalid8Strings[i].m16) != - nsCRT::HashCodeAsUTF16(str8.get(), str8.Length())) + nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) || + err) return PR_FALSE; } for (unsigned int i = 0; i < NS_ARRAY_LENGTH(Malformed8Strings); ++i) { nsDependentCString str8(Malformed8Strings[i]); - if (nsCRT::HashCodeAsUTF16(str8.get(), str8.Length()) != 0) + PRBool err; + if (nsCRT::HashCodeAsUTF16(str8.get(), str8.Length(), &err) != 0 || + !err) return PR_FALSE; }