libxml2 r3767 - trunk
- From: veillard svn gnome org
- To: svn-commits-list gnome org
- Subject: libxml2 r3767 - trunk
- Date: Thu, 7 Aug 2008 16:33:49 +0000 (UTC)
Author: veillard
Date: Thu Aug 7 16:33:49 2008
New Revision: 3767
URL: http://svn.gnome.org/viewvc/libxml2?rev=3767&view=rev
Log:
* dict.c: chased and found a couple of nasty issues
Daniel
Modified:
trunk/ChangeLog
trunk/dict.c
Modified: trunk/dict.c
==============================================================================
--- trunk/dict.c (original)
+++ trunk/dict.c Thu Aug 7 16:33:49 2008
@@ -46,18 +46,18 @@
xmlDictComputeFastKey(name, len) : \
xmlDictComputeBigKey(name, len))
-#define xmlDictComputeQKey(dict, prefix, name, len) \
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
(((prefix) == NULL) ? \
(xmlDictComputeKey(dict, name, len)) : \
(((dict)->size == MIN_DICT_SIZE) ? \
- xmlDictComputeFastQKey(prefix, name, len) : \
- xmlDictComputeBigQKey(prefix, name, len)))
+ xmlDictComputeFastQKey(prefix, plen, name, len) : \
+ xmlDictComputeBigQKey(prefix, plen, name, len)))
#else /* !WITH_BIG_KEY */
#define xmlDictComputeKey(dict, name, len) \
xmlDictComputeFastKey(name, len)
-#define xmlDictComputeQKey(dict, prefix, name, len) \
- xmlDictComputeFastQKey(prefix, name, len)
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
+ xmlDictComputeFastQKey(prefix, plen, name, len)
#endif /* WITH_BIG_KEY */
/*
@@ -200,6 +200,7 @@
* xmlDictAddQString:
* @dict: the dictionnary
* @prefix: the prefix of the userdata
+ * @plen: the prefix length
* @name: the name of the userdata
* @len: the length of the name, if -1 it is recomputed
*
@@ -208,23 +209,21 @@
* Returns the pointer of the local string, or NULL in case of error.
*/
static const xmlChar *
-xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix,
+xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
const xmlChar *name, int namelen)
{
xmlDictStringsPtr pool;
const xmlChar *ret;
int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
- int plen;
if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
- plen = xmlStrlen(prefix);
#ifdef DICT_DEBUG_PATTERNS
fprintf(stderr, "=");
#endif
pool = dict->strings;
while (pool != NULL) {
- if (pool->end - pool->free > namelen)
+ if (pool->end - pool->free > namelen + plen + 1)
goto found_pool;
if (pool->size > size) size = pool->size;
pool = pool->next;
@@ -235,8 +234,8 @@
if (pool == NULL) {
if (size == 0) size = 1000;
else size *= 4; /* exponential growth */
- if (size < 4 * (namelen + plen))
- size = 4 * (namelen + plen); /* just in case ! */
+ if (size < 4 * (namelen + plen + 1))
+ size = 4 * (namelen + plen + 1); /* just in case ! */
pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
if (pool == NULL)
return(NULL);
@@ -255,7 +254,6 @@
memcpy(pool->free, prefix, plen);
pool->free += plen;
*(pool->free++) = ':';
- namelen -= plen + 1;
memcpy(pool->free, name, namelen);
pool->free += namelen;
*(pool->free++) = 0;
@@ -307,13 +305,11 @@
* Neither of the two strings must be NULL.
*/
static unsigned long
-xmlDictComputeBigQKey(const xmlChar *prefix, const xmlChar *name, int len)
+xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
+ const xmlChar *name, int len)
{
uint32_t hash;
int i;
- int plen;
-
- plen = xmlStrlen(prefix);
hash = 0;
@@ -380,12 +376,11 @@
* Neither of the two strings must be NULL.
*/
static unsigned long
-xmlDictComputeFastQKey(const xmlChar *prefix, const xmlChar *name, int len)
+xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
+ const xmlChar *name, int len)
{
unsigned long value = 0L;
- int plen;
- plen = xmlStrlen(prefix);
if (plen == 0)
value += 30 * (unsigned long) ':';
else
@@ -532,6 +527,7 @@
#ifdef DEBUG_GROW
unsigned long nbElem = 0;
#endif
+ int ret = 0;
if (dict == NULL)
return(-1);
@@ -559,16 +555,32 @@
/* If the two loops are merged, there would be situations where
a new entry needs to allocated and data copied into it from
- the main dict. So instead, we run through the array twice, first
- copying all the elements in the main array (where we can't get
- conflicts) and then the rest, so we only free (and don't allocate)
+ the main dict. It is nicer to run through the array twice, first
+ copying all the elements in the main array (less probability of
+ allocate) and then the rest, so we only free in the second loop.
*/
for (i = 0; i < oldsize; i++) {
if (olddict[i].valid == 0)
continue;
key = xmlDictComputeKey(dict, olddict[i].name, olddict[i].len) % dict->size;
- memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
- dict->dict[key].next = NULL;
+ if (dict->dict[key].valid == 0) {
+ memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
+ dict->dict[key].next = NULL;
+ } else {
+ xmlDictEntryPtr entry;
+
+ entry = xmlMalloc(sizeof(xmlDictEntry));
+ if (entry != NULL) {
+ entry->name = olddict[i].name;
+ entry->len = olddict[i].len;
+ entry->next = dict->dict[key].next;
+ entry->valid = 1;
+ dict->dict[key].next = entry;
+ } else {
+ /* we don't have much ways to alert from here */
+ ret = -1;
+ }
+ }
#ifdef DEBUG_GROW
nbElem++;
#endif
@@ -609,7 +621,7 @@
"xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
#endif
- return(0);
+ return(ret);
}
/**
@@ -696,7 +708,7 @@
return(NULL);
if (len < 0)
- len = xmlStrlen(name);
+ len = strlen((const char *) name);
/*
* Check for duplicate and insertion location.
@@ -798,8 +810,10 @@
dict->nbElems++;
if ((nbi > MAX_HASH_LEN) &&
- (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN)))
- xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size);
+ (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) {
+ if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0)
+ return(NULL);
+ }
/* Note that entry may have been freed at this point by xmlDictGrow */
return(ret);
@@ -824,7 +838,7 @@
return(NULL);
if (len < 0)
- len = xmlStrlen(name);
+ len = strlen((const char *) name);
/*
* Check for duplicate and insertion location.
@@ -923,19 +937,21 @@
xmlDictEntryPtr entry;
xmlDictEntryPtr insert;
const xmlChar *ret;
- int len;
+ int len, plen, l;
if ((dict == NULL) || (name == NULL))
return(NULL);
+ if (prefix == NULL)
+ return(xmlDictLookup(dict, name, -1));
- len = xmlStrlen(name);
- if (prefix != NULL)
- len += 1 + xmlStrlen(prefix);
+ l = len = strlen((const char *) name);
+ plen = strlen((const char *) prefix);
+ len += 1 + plen;
/*
* Check for duplicate and insertion location.
*/
- okey = xmlDictComputeQKey(dict, prefix, name, len);
+ okey = xmlDictComputeQKey(dict, prefix, plen, name, l);
key = okey % dict->size;
if (dict->dict[key].valid == 0) {
insert = NULL;
@@ -960,7 +976,7 @@
(dict->subdict->size != MIN_DICT_SIZE)) ||
((dict->size != MIN_DICT_SIZE) &&
(dict->subdict->size == MIN_DICT_SIZE)))
- skey = xmlDictComputeQKey(dict->subdict, prefix, name, len);
+ skey = xmlDictComputeQKey(dict->subdict, prefix, plen, name, l);
else
skey = okey;
@@ -981,7 +997,7 @@
key = okey % dict->size;
}
- ret = xmlDictAddQString(dict, prefix, name, len);
+ ret = xmlDictAddQString(dict, prefix, plen, name, l);
if (ret == NULL)
return(NULL);
if (insert == NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]