ICU-5511 Prevent uhash_equals from crashing by default

X-SVN-Rev: 20657
This commit is contained in:
George Rhoten 2006-11-15 00:13:51 +00:00
parent 648fc2f6ed
commit e5fc505f2e
2 changed files with 42 additions and 6 deletions

View file

@ -877,12 +877,23 @@ uhash_equals(const UHashtable* hash1, const UHashtable* hash2){
return TRUE;
}
if(hash1==NULL || hash2==NULL){
return FALSE;
}
/* make sure that we are comparing 2 hashes of the same type */
if( hash1->keyComparator != hash2->keyComparator ||
hash2->valueComparator != hash2->valueComparator){
/*
* Make sure that we are comparing 2 valid hashes of the same type
* with valid comparison functions.
* Without valid comparison functions, a binary comparison
* of the hash values will yield random results on machines
* with 64-bit pointers and 32-bit integer hashes.
* A valueComparator is normally optional.
*/
if (hash1==NULL || hash2==NULL ||
hash1->keyComparator != hash2->keyComparator ||
hash1->valueComparator != hash2->valueComparator ||
hash1->valueComparator == NULL)
{
/*
Normally we would return an error here about incompatible hash tables,
but we return FALSE instead.
*/
return FALSE;
}

View file

@ -160,6 +160,13 @@ void UVectorTest::UStack_API() {
delete a;
}
U_CDECL_BEGIN
static UBool U_CALLCONV neverTRUE(const UHashTok /*key1*/, const UHashTok /*key2*/) {
return FALSE;
}
U_CDECL_END
void UVectorTest::Hashtable_API() {
UErrorCode status = U_ZERO_ERROR;
Hashtable *a = new Hashtable(status);
@ -170,6 +177,24 @@ void UVectorTest::Hashtable_API() {
TEST_ASSERT((a->find("b") != NULL));
TEST_ASSERT((a->removei("a") == 1));
TEST_ASSERT((a->find("a") == NULL));
/* verify that setValueCompartor works */
Hashtable b(status);
TEST_ASSERT((!a->equals(b)));
TEST_ASSERT((b.puti("b", 2, status) == 0));
TEST_ASSERT((!a->equals(b))); // Without a value comparator, this will be FALSE by default.
b.setValueCompartor(uhash_compareLong);
TEST_ASSERT((!a->equals(b)));
a->setValueCompartor(uhash_compareLong);
TEST_ASSERT((a->equals(b)));
TEST_ASSERT((a->equals(*a))); // This better be reflexive.
/* verify that setKeyCompartor works */
TEST_ASSERT((a->puti("a", 1, status) == 0));
TEST_ASSERT((a->find("a") != NULL));
a->setKeyCompartor(neverTRUE);
TEST_ASSERT((a->find("a") == NULL));
delete a;
}