1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-03-24 06:50:08 +03:00

parser: Fix combination of hash values

This bug resulted in a stuck bit in hash values which can have a severe
performance impact.
This commit is contained in:
Nick Wellnhofer 2023-11-04 23:47:33 +01:00
parent a31e1b0665
commit 5859849454
3 changed files with 25 additions and 10 deletions

19
dict.c
View File

@ -501,6 +501,10 @@ xmlDictHashQName(unsigned seed, const xmlChar *prefix, const xmlChar *name,
HASH_FINISH(h1, h2);
/*
* Always set the upper bit of hash values since 0 means an unoccupied
* bucket.
*/
return(h2 | MAX_HASH_SIZE);
}
@ -510,6 +514,21 @@ xmlDictComputeHash(const xmlDict *dict, const xmlChar *string) {
return(xmlDictHashName(dict->seed, string, SIZE_MAX, &len));
}
#define HASH_ROL31(x,n) ((x) << (n) | ((x) & 0x7FFFFFFF) >> (31 - (n)))
ATTRIBUTE_NO_SANITIZE_INTEGER
unsigned
xmlDictCombineHash(unsigned v1, unsigned v2) {
/*
* The upper bit of hash values is always set, so we have to operate on
* 31-bit hashes here.
*/
v1 ^= v2;
v1 += HASH_ROL31(v2, 5);
return((v1 & 0xFFFFFFFF) | 0x80000000);
}
/**
* xmlDictFindEntry:
* @dict: dict

View File

@ -55,9 +55,11 @@ xmlInitDictInternal(void);
XML_HIDDEN void
xmlCleanupDictInternal(void);
unsigned
XML_HIDDEN unsigned
xmlDictComputeHash(const xmlDict *dict, const xmlChar *string);
xmlHashedString
XML_HIDDEN unsigned
xmlDictCombineHash(unsigned v1, unsigned v2);
XML_HIDDEN xmlHashedString
xmlDictLookupHashed(xmlDictPtr dict, const xmlChar *name, int len);
XML_HIDDEN void

View File

@ -9390,12 +9390,6 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
return (hname);
}
ATTRIBUTE_NO_SANITIZE_INTEGER
static unsigned
xmlCombineHash(unsigned v1, unsigned v2) {
return(HASH_ROL(v1, 15) ^ v2);
}
/**
* xmlAttrHashInsert:
* @ctxt: parser context
@ -9913,7 +9907,7 @@ next_attr:
uriHashValue = ctxt->nsdb->extra[nsIndex].uriHashValue;
}
hashValue = xmlCombineHash(nameHashValue, uriHashValue);
hashValue = xmlDictCombineHash(nameHashValue, uriHashValue);
res = xmlAttrHashInsert(ctxt, i, &attrHashSize, attname, nsuri,
hashValue);
if (res < 0)
@ -9985,7 +9979,7 @@ next_attr:
/*
* Check whether the attribute exists
*/
hashValue = xmlCombineHash(attr->name.hashValue, uriHashValue);
hashValue = xmlDictCombineHash(attr->name.hashValue, uriHashValue);
res = xmlAttrHashInsert(ctxt, nbatts, &attrHashSize, attname,
nsuri, hashValue);
if (res < 0)