Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Unified Diff: third_party/libxml/src/dict.c

Issue 1193533007: Upgrade to libxml 2.9.2 and libxslt 1.1.28 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: no iconv Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/libxml/src/depcomp ('k') | third_party/libxml/src/elfgcchack.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/libxml/src/dict.c
diff --git a/third_party/libxml/src/dict.c b/third_party/libxml/src/dict.c
index 3eff2315e94112089cf487707a02f409740031fe..5f71d55d736f7d752c71ae720e5d3d6e487b493b 100644
--- a/third_party/libxml/src/dict.c
+++ b/third_party/libxml/src/dict.c
@@ -2,7 +2,7 @@
* dict.c: dictionary of reusable strings, just used to avoid allocation
* and freeing operations.
*
- * Copyright (C) 2003 Daniel Veillard.
+ * Copyright (C) 2003-2012 Daniel Veillard.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,29 @@
#define IN_LIBXML
#include "libxml.h"
+#include <limits.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+/*
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
+ * it seems that having hash randomization might be a good idea
+ * when using XML with untrusted data
+ * Note1: that it works correctly only if compiled with WITH_BIG_KEY
+ * which is the default.
+ * Note2: the fast function used for a small dict won't protect very
+ * well but since the attack is based on growing a very big hash
+ * list we will use the BigKey algo as soon as the hash size grows
+ * over MIN_DICT_SIZE so this actually works
+ */
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#define DICT_RANDOMIZATION
+#endif
+
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
@@ -44,23 +67,23 @@ typedef unsigned __int32 uint32_t;
#define WITH_BIG_KEY
#ifdef WITH_BIG_KEY
-#define xmlDictComputeKey(dict, name, len) \
- (((dict)->size == MIN_DICT_SIZE) ? \
- xmlDictComputeFastKey(name, len) : \
- xmlDictComputeBigKey(name, len))
-
-#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
- (((prefix) == NULL) ? \
- (xmlDictComputeKey(dict, name, len)) : \
- (((dict)->size == MIN_DICT_SIZE) ? \
- xmlDictComputeFastQKey(prefix, plen, name, len) : \
- xmlDictComputeBigQKey(prefix, plen, name, len)))
+#define xmlDictComputeKey(dict, name, len) \
+ (((dict)->size == MIN_DICT_SIZE) ? \
+ xmlDictComputeFastKey(name, len, (dict)->seed) : \
+ xmlDictComputeBigKey(name, len, (dict)->seed))
+
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
+ (((prefix) == NULL) ? \
+ (xmlDictComputeKey(dict, name, len)) : \
+ (((dict)->size == MIN_DICT_SIZE) ? \
+ xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) : \
+ xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
#else /* !WITH_BIG_KEY */
-#define xmlDictComputeKey(dict, name, len) \
- xmlDictComputeFastKey(name, len)
-#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
- xmlDictComputeFastQKey(prefix, plen, name, len)
+#define xmlDictComputeKey(dict, name, len) \
+ xmlDictComputeFastKey(name, len, (dict)->seed)
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
+ xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
#endif /* WITH_BIG_KEY */
/*
@@ -71,7 +94,7 @@ typedef xmlDictEntry *xmlDictEntryPtr;
struct _xmlDictEntry {
struct _xmlDictEntry *next;
const xmlChar *name;
- int len;
+ unsigned int len;
int valid;
unsigned long okey;
};
@@ -82,8 +105,8 @@ struct _xmlDictStrings {
xmlDictStringsPtr next;
xmlChar *free;
xmlChar *end;
- int size;
- int nbStrings;
+ size_t size;
+ size_t nbStrings;
xmlChar array[1];
};
/*
@@ -93,11 +116,15 @@ struct _xmlDict {
int ref_counter;
struct _xmlDictEntry *dict;
- int size;
- int nbElems;
+ size_t size;
+ unsigned int nbElems;
xmlDictStringsPtr strings;
struct _xmlDict *subdict;
+ /* used for randomization */
+ int seed;
+ /* used to impose a limit on size */
+ size_t limit;
};
/*
@@ -111,28 +138,84 @@ static xmlRMutexPtr xmlDictMutex = NULL;
*/
static int xmlDictInitialized = 0;
+#ifdef DICT_RANDOMIZATION
+#ifdef HAVE_RAND_R
+/*
+ * Internal data for random function, protected by xmlDictMutex
+ */
+static unsigned int rand_seed = 0;
+#endif
+#endif
+
/**
* xmlInitializeDict:
*
* Do the dictionary mutex initialization.
+ * this function is deprecated
+ *
+ * Returns 0 if initialization was already done, and 1 if that
+ * call led to the initialization
+ */
+int xmlInitializeDict(void) {
+ return(0);
+}
+
+/**
+ * __xmlInitializeDict:
+ *
+ * This function is not public
+ * Do the dictionary mutex initialization.
* this function is not thread safe, initialization should
- * preferably be done once at startup
+ * normally be done once at setup when called from xmlOnceInit()
+ * we may also land in this code if thread support is not compiled in
+ *
+ * Returns 0 if initialization was already done, and 1 if that
+ * call led to the initialization
*/
-static int xmlInitializeDict(void) {
+int __xmlInitializeDict(void) {
if (xmlDictInitialized)
return(1);
if ((xmlDictMutex = xmlNewRMutex()) == NULL)
return(0);
+ xmlRMutexLock(xmlDictMutex);
+#ifdef DICT_RANDOMIZATION
+#ifdef HAVE_RAND_R
+ rand_seed = time(NULL);
+ rand_r(& rand_seed);
+#else
+ srand(time(NULL));
+#endif
+#endif
xmlDictInitialized = 1;
+ xmlRMutexUnlock(xmlDictMutex);
return(1);
}
+#ifdef DICT_RANDOMIZATION
+int __xmlRandom(void) {
+ int ret;
+
+ if (xmlDictInitialized == 0)
+ __xmlInitializeDict();
+
+ xmlRMutexLock(xmlDictMutex);
+#ifdef HAVE_RAND_R
+ ret = rand_r(& rand_seed);
+#else
+ ret = rand();
+#endif
+ xmlRMutexUnlock(xmlDictMutex);
+ return(ret);
+}
+#endif
+
/**
* xmlDictCleanup:
*
- * Free the dictionary mutex.
+ * Free the dictionary mutex. Do not call unless sure the library
+ * is not in use anymore !
*/
void
xmlDictCleanup(void) {
@@ -148,17 +231,18 @@ xmlDictCleanup(void) {
* xmlDictAddString:
* @dict: the dictionnary
* @name: the name of the userdata
- * @len: the length of the name, if -1 it is recomputed
+ * @len: the length of the name
*
* Add the string to the array[s]
*
* Returns the pointer of the local string, or NULL in case of error.
*/
static const xmlChar *
-xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
+xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
xmlDictStringsPtr pool;
const xmlChar *ret;
- int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
+ size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
+ size_t limit = 0;
#ifdef DICT_DEBUG_PATTERNS
fprintf(stderr, "-");
@@ -168,15 +252,20 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
if (pool->end - pool->free > namelen)
goto found_pool;
if (pool->size > size) size = pool->size;
+ limit += pool->size;
pool = pool->next;
}
/*
* Not found, need to allocate
*/
if (pool == NULL) {
+ if ((dict->limit > 0) && (limit > dict->limit)) {
+ return(NULL);
+ }
+
if (size == 0) size = 1000;
else size *= 4; /* exponential growth */
- if (size < 4 * namelen)
+ if (size < 4 * namelen)
size = 4 * namelen; /* just in case ! */
pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
if (pool == NULL)
@@ -206,19 +295,20 @@ found_pool:
* @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
+ * @len: the length of the name
*
* Add the QName to the array[s]
*
* Returns the pointer of the local string, or NULL in case of error.
*/
static const xmlChar *
-xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
- const xmlChar *name, int namelen)
+xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
+ const xmlChar *name, unsigned int namelen)
{
xmlDictStringsPtr pool;
const xmlChar *ret;
- int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
+ size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
+ size_t limit = 0;
if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
@@ -230,12 +320,17 @@ xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
if (pool->end - pool->free > namelen + plen + 1)
goto found_pool;
if (pool->size > size) size = pool->size;
+ limit += pool->size;
pool = pool->next;
}
/*
* Not found, need to allocate
*/
if (pool == NULL) {
+ if ((dict->limit > 0) && (limit > dict->limit)) {
+ return(NULL);
+ }
+
if (size == 0) size = 1000;
else size *= 4; /* exponential growth */
if (size < 4 * (namelen + plen + 1))
@@ -277,13 +372,13 @@ found_pool:
*/
static uint32_t
-xmlDictComputeBigKey(const xmlChar* data, int namelen) {
+xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
uint32_t hash;
int i;
if (namelen <= 0 || data == NULL) return(0);
- hash = 0;
+ hash = seed;
for (i = 0;i < namelen; i++) {
hash += data[i];
@@ -310,12 +405,12 @@ xmlDictComputeBigKey(const xmlChar* data, int namelen) {
*/
static unsigned long
xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
- const xmlChar *name, int len)
+ const xmlChar *name, int len, int seed)
{
uint32_t hash;
int i;
- hash = 0;
+ hash = seed;
for (i = 0;i < plen; i++) {
hash += prefix[i];
@@ -346,8 +441,8 @@ xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
* for low hash table fill.
*/
static unsigned long
-xmlDictComputeFastKey(const xmlChar *name, int namelen) {
- unsigned long value = 0L;
+xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
+ unsigned long value = seed;
if (name == NULL) return(0);
value = *name;
@@ -381,9 +476,9 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen) {
*/
static unsigned long
xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
- const xmlChar *name, int len)
+ const xmlChar *name, int len, int seed)
{
- unsigned long value = 0L;
+ unsigned long value = (unsigned long) seed;
if (plen == 0)
value += 30 * (unsigned long) ':';
@@ -442,7 +537,7 @@ xmlDictCreate(void) {
xmlDictPtr dict;
if (!xmlDictInitialized)
- if (!xmlInitializeDict())
+ if (!__xmlInitializeDict())
return(NULL);
#ifdef DICT_DEBUG_PATTERNS
@@ -452,6 +547,7 @@ xmlDictCreate(void) {
dict = xmlMalloc(sizeof(xmlDict));
if (dict) {
dict->ref_counter = 1;
+ dict->limit = 0;
dict->size = MIN_DICT_SIZE;
dict->nbElems = 0;
@@ -460,6 +556,11 @@ xmlDictCreate(void) {
dict->subdict = NULL;
if (dict->dict) {
memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
+#ifdef DICT_RANDOMIZATION
+ dict->seed = __xmlRandom();
+#else
+ dict->seed = 0;
+#endif
return(dict);
}
xmlFree(dict);
@@ -486,6 +587,7 @@ xmlDictCreateSub(xmlDictPtr sub) {
#ifdef DICT_DEBUG_PATTERNS
fprintf(stderr, "R");
#endif
+ dict->seed = sub->seed;
dict->subdict = sub;
xmlDictReference(dict->subdict);
}
@@ -503,7 +605,7 @@ xmlDictCreateSub(xmlDictPtr sub) {
int
xmlDictReference(xmlDictPtr dict) {
if (!xmlDictInitialized)
- if (!xmlInitializeDict())
+ if (!__xmlInitializeDict())
return(-1);
if (dict == NULL) return -1;
@@ -523,9 +625,9 @@ xmlDictReference(xmlDictPtr dict) {
* Returns 0 in case of success, -1 in case of failure
*/
static int
-xmlDictGrow(xmlDictPtr dict, int size) {
+xmlDictGrow(xmlDictPtr dict, size_t size) {
unsigned long key, okey;
- int oldsize, i;
+ size_t oldsize, i;
xmlDictEntryPtr iter, next;
struct _xmlDictEntry *olddict;
#ifdef DEBUG_GROW
@@ -642,7 +744,7 @@ xmlDictGrow(xmlDictPtr dict, int size) {
#ifdef DEBUG_GROW
xmlGenericError(xmlGenericErrorContext,
- "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
+ "xmlDictGrow : from %lu to %lu, %u elems\n", oldsize, size, nbElem);
#endif
return(ret);
@@ -657,7 +759,7 @@ xmlDictGrow(xmlDictPtr dict, int size) {
*/
void
xmlDictFree(xmlDictPtr dict) {
- int i;
+ size_t i;
xmlDictEntryPtr iter;
xmlDictEntryPtr next;
int inside_dict = 0;
@@ -667,7 +769,7 @@ xmlDictFree(xmlDictPtr dict) {
return;
if (!xmlDictInitialized)
- if (!xmlInitializeDict())
+ if (!__xmlInitializeDict())
return;
/* decrement the counter, it may be shared by a parser and docs */
@@ -726,17 +828,24 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
xmlDictEntryPtr entry;
xmlDictEntryPtr insert;
const xmlChar *ret;
+ unsigned int l;
if ((dict == NULL) || (name == NULL))
return(NULL);
if (len < 0)
- len = strlen((const char *) name);
+ l = strlen((const char *) name);
+ else
+ l = len;
+
+ if (((dict->limit > 0) && (l >= dict->limit)) ||
+ (l > INT_MAX / 2))
+ return(NULL);
/*
* Check for duplicate and insertion location.
*/
- okey = xmlDictComputeKey(dict, name, len);
+ okey = xmlDictComputeKey(dict, name, l);
key = okey % dict->size;
if (dict->dict[key].valid == 0) {
insert = NULL;
@@ -744,25 +853,25 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
for (insert = &(dict->dict[key]); insert->next != NULL;
insert = insert->next) {
#ifdef __GNUC__
- if ((insert->okey == okey) && (insert->len == len)) {
- if (!memcmp(insert->name, name, len))
+ if ((insert->okey == okey) && (insert->len == l)) {
+ if (!memcmp(insert->name, name, l))
return(insert->name);
}
#else
- if ((insert->okey == okey) && (insert->len == len) &&
- (!xmlStrncmp(insert->name, name, len)))
+ if ((insert->okey == okey) && (insert->len == l) &&
+ (!xmlStrncmp(insert->name, name, l)))
return(insert->name);
#endif
nbi++;
}
#ifdef __GNUC__
- if ((insert->okey == okey) && (insert->len == len)) {
- if (!memcmp(insert->name, name, len))
+ if ((insert->okey == okey) && (insert->len == l)) {
+ if (!memcmp(insert->name, name, l))
return(insert->name);
}
#else
- if ((insert->okey == okey) && (insert->len == len) &&
- (!xmlStrncmp(insert->name, name, len)))
+ if ((insert->okey == okey) && (insert->len == l) &&
+ (!xmlStrncmp(insert->name, name, l)))
return(insert->name);
#endif
}
@@ -775,7 +884,7 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
(dict->subdict->size != MIN_DICT_SIZE)) ||
((dict->size != MIN_DICT_SIZE) &&
(dict->subdict->size == MIN_DICT_SIZE)))
- skey = xmlDictComputeKey(dict->subdict, name, len);
+ skey = xmlDictComputeKey(dict->subdict, name, l);
else
skey = okey;
@@ -786,32 +895,32 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
tmp = tmp->next) {
#ifdef __GNUC__
- if ((tmp->okey == skey) && (tmp->len == len)) {
- if (!memcmp(tmp->name, name, len))
+ if ((tmp->okey == skey) && (tmp->len == l)) {
+ if (!memcmp(tmp->name, name, l))
return(tmp->name);
}
#else
- if ((tmp->okey == skey) && (tmp->len == len) &&
- (!xmlStrncmp(tmp->name, name, len)))
+ if ((tmp->okey == skey) && (tmp->len == l) &&
+ (!xmlStrncmp(tmp->name, name, l)))
return(tmp->name);
#endif
nbi++;
}
#ifdef __GNUC__
- if ((tmp->okey == skey) && (tmp->len == len)) {
- if (!memcmp(tmp->name, name, len))
+ if ((tmp->okey == skey) && (tmp->len == l)) {
+ if (!memcmp(tmp->name, name, l))
return(tmp->name);
}
#else
- if ((tmp->okey == skey) && (tmp->len == len) &&
- (!xmlStrncmp(tmp->name, name, len)))
+ if ((tmp->okey == skey) && (tmp->len == l) &&
+ (!xmlStrncmp(tmp->name, name, l)))
return(tmp->name);
#endif
}
key = okey % dict->size;
}
- ret = xmlDictAddString(dict, name, len);
+ ret = xmlDictAddString(dict, name, l);
if (ret == NULL)
return(NULL);
if (insert == NULL) {
@@ -822,13 +931,13 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
return(NULL);
}
entry->name = ret;
- entry->len = len;
+ entry->len = l;
entry->next = NULL;
entry->valid = 1;
entry->okey = okey;
- if (insert != NULL)
+ if (insert != NULL)
insert->next = entry;
dict->nbElems++;
@@ -857,17 +966,23 @@ const xmlChar *
xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
unsigned long key, okey, nbi = 0;
xmlDictEntryPtr insert;
+ unsigned int l;
if ((dict == NULL) || (name == NULL))
return(NULL);
if (len < 0)
- len = strlen((const char *) name);
+ l = strlen((const char *) name);
+ else
+ l = len;
+ if (((dict->limit > 0) && (l >= dict->limit)) ||
+ (l > INT_MAX / 2))
+ return(NULL);
/*
* Check for duplicate and insertion location.
*/
- okey = xmlDictComputeKey(dict, name, len);
+ okey = xmlDictComputeKey(dict, name, l);
key = okey % dict->size;
if (dict->dict[key].valid == 0) {
insert = NULL;
@@ -875,25 +990,25 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
for (insert = &(dict->dict[key]); insert->next != NULL;
insert = insert->next) {
#ifdef __GNUC__
- if ((insert->okey == okey) && (insert->len == len)) {
- if (!memcmp(insert->name, name, len))
+ if ((insert->okey == okey) && (insert->len == l)) {
+ if (!memcmp(insert->name, name, l))
return(insert->name);
}
#else
- if ((insert->okey == okey) && (insert->len == len) &&
- (!xmlStrncmp(insert->name, name, len)))
+ if ((insert->okey == okey) && (insert->len == l) &&
+ (!xmlStrncmp(insert->name, name, l)))
return(insert->name);
#endif
nbi++;
}
#ifdef __GNUC__
- if ((insert->okey == okey) && (insert->len == len)) {
- if (!memcmp(insert->name, name, len))
+ if ((insert->okey == okey) && (insert->len == l)) {
+ if (!memcmp(insert->name, name, l))
return(insert->name);
}
#else
- if ((insert->okey == okey) && (insert->len == len) &&
- (!xmlStrncmp(insert->name, name, len)))
+ if ((insert->okey == okey) && (insert->len == l) &&
+ (!xmlStrncmp(insert->name, name, l)))
return(insert->name);
#endif
}
@@ -906,7 +1021,7 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
(dict->subdict->size != MIN_DICT_SIZE)) ||
((dict->size != MIN_DICT_SIZE) &&
(dict->subdict->size == MIN_DICT_SIZE)))
- skey = xmlDictComputeKey(dict->subdict, name, len);
+ skey = xmlDictComputeKey(dict->subdict, name, l);
else
skey = okey;
@@ -917,25 +1032,25 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
tmp = tmp->next) {
#ifdef __GNUC__
- if ((tmp->okey == skey) && (tmp->len == len)) {
- if (!memcmp(tmp->name, name, len))
+ if ((tmp->okey == skey) && (tmp->len == l)) {
+ if (!memcmp(tmp->name, name, l))
return(tmp->name);
}
#else
- if ((tmp->okey == skey) && (tmp->len == len) &&
- (!xmlStrncmp(tmp->name, name, len)))
+ if ((tmp->okey == skey) && (tmp->len == l) &&
+ (!xmlStrncmp(tmp->name, name, l)))
return(tmp->name);
#endif
nbi++;
}
#ifdef __GNUC__
- if ((tmp->okey == skey) && (tmp->len == len)) {
- if (!memcmp(tmp->name, name, len))
+ if ((tmp->okey == skey) && (tmp->len == l)) {
+ if (!memcmp(tmp->name, name, l))
return(tmp->name);
}
#else
- if ((tmp->okey == skey) && (tmp->len == len) &&
- (!xmlStrncmp(tmp->name, name, len)))
+ if ((tmp->okey == skey) && (tmp->len == l) &&
+ (!xmlStrncmp(tmp->name, name, l)))
return(tmp->name);
#endif
}
@@ -961,7 +1076,7 @@ xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
xmlDictEntryPtr entry;
xmlDictEntryPtr insert;
const xmlChar *ret;
- int len, plen, l;
+ unsigned int len, plen, l;
if ((dict == NULL) || (name == NULL))
return(NULL);
@@ -1037,7 +1152,7 @@ xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
entry->valid = 1;
entry->okey = okey;
- if (insert != NULL)
+ if (insert != NULL)
insert->next = entry;
dict->nbElems++;
@@ -1095,6 +1210,50 @@ xmlDictSize(xmlDictPtr dict) {
return(dict->nbElems);
}
+/**
+ * xmlDictSetLimit:
+ * @dict: the dictionnary
+ * @limit: the limit in bytes
+ *
+ * Set a size limit for the dictionary
+ * Added in 2.9.0
+ *
+ * Returns the previous limit of the dictionary or 0
+ */
+size_t
+xmlDictSetLimit(xmlDictPtr dict, size_t limit) {
+ size_t ret;
+
+ if (dict == NULL)
+ return(0);
+ ret = dict->limit;
+ dict->limit = limit;
+ return(ret);
+}
+
+/**
+ * xmlDictGetUsage:
+ * @dict: the dictionnary
+ *
+ * Get how much memory is used by a dictionary for strings
+ * Added in 2.9.0
+ *
+ * Returns the amount of strings allocated
+ */
+size_t
+xmlDictGetUsage(xmlDictPtr dict) {
+ xmlDictStringsPtr pool;
+ size_t limit = 0;
+
+ if (dict == NULL)
+ return(0);
+ pool = dict->strings;
+ while (pool != NULL) {
+ limit += pool->size;
+ pool = pool->next;
+ }
+ return(limit);
+}
#define bottom_dict
#include "elfgcchack.h"
« no previous file with comments | « third_party/libxml/src/depcomp ('k') | third_party/libxml/src/elfgcchack.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698