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:
parent
a31e1b0665
commit
5859849454
19
dict.c
19
dict.c
@ -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
|
||||
|
@ -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
|
||||
|
10
parser.c
10
parser.c
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user