Diff for /embedaddon/libxml2/dict.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2012/02/21 23:37:58 version 1.1.1.3, 2014/06/15 19:53:29
Line 2 Line 2
  * dict.c: dictionary of reusable strings, just used to avoid allocation   * dict.c: dictionary of reusable strings, just used to avoid allocation
  *         and freeing operations.   *         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   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 19 Line 19
 #define IN_LIBXML  #define IN_LIBXML
 #include "libxml.h"  #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>  #include <string.h>
 #ifdef HAVE_STDINT_H  #ifdef HAVE_STDINT_H
 #include <stdint.h>  #include <stdint.h>
Line 44  typedef unsigned __int32 uint32_t; Line 67  typedef unsigned __int32 uint32_t;
 #define WITH_BIG_KEY  #define WITH_BIG_KEY
   
 #ifdef WITH_BIG_KEY  #ifdef WITH_BIG_KEY
#define xmlDictComputeKey(dict, name, len)                      \#define xmlDictComputeKey(dict, name, len)                              \
    (((dict)->size == MIN_DICT_SIZE) ?                          \    (((dict)->size == MIN_DICT_SIZE) ?                                  \
     xmlDictComputeFastKey(name, len) :                                \     xmlDictComputeFastKey(name, len, (dict)->seed) :                   \
     xmlDictComputeBigKey(name, len))     xmlDictComputeBigKey(name, len, (dict)->seed))
   
#define xmlDictComputeQKey(dict, prefix, plen, name, len)       \#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
    (((prefix) == NULL) ?                                       \    (((prefix) == NULL) ?                                               \
      (xmlDictComputeKey(dict, name, len)) :                    \      (xmlDictComputeKey(dict, name, len)) :                             \
      (((dict)->size == MIN_DICT_SIZE) ?                        \      (((dict)->size == MIN_DICT_SIZE) ?                                \
       xmlDictComputeFastQKey(prefix, plen, name, len) :     \       xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) :     \
       xmlDictComputeBigQKey(prefix, plen, name, len)))       xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
   
 #else /* !WITH_BIG_KEY */  #else /* !WITH_BIG_KEY */
#define xmlDictComputeKey(dict, name, len)                      \#define xmlDictComputeKey(dict, name, len)                              \
        xmlDictComputeFastKey(name, len)        xmlDictComputeFastKey(name, len, (dict)->seed)
#define xmlDictComputeQKey(dict, prefix, plen, name, len)       \#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
        xmlDictComputeFastQKey(prefix, plen, name, len)        xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
 #endif /* WITH_BIG_KEY */  #endif /* WITH_BIG_KEY */
   
 /*  /*
Line 71  typedef xmlDictEntry *xmlDictEntryPtr; Line 94  typedef xmlDictEntry *xmlDictEntryPtr;
 struct _xmlDictEntry {  struct _xmlDictEntry {
     struct _xmlDictEntry *next;      struct _xmlDictEntry *next;
     const xmlChar *name;      const xmlChar *name;
    int len;    unsigned int len;
     int valid;      int valid;
     unsigned long okey;      unsigned long okey;
 };  };
Line 82  struct _xmlDictStrings { Line 105  struct _xmlDictStrings {
     xmlDictStringsPtr next;      xmlDictStringsPtr next;
     xmlChar *free;      xmlChar *free;
     xmlChar *end;      xmlChar *end;
    int size;    size_t size;
    int nbStrings;    size_t nbStrings;
     xmlChar array[1];      xmlChar array[1];
 };  };
 /*  /*
Line 93  struct _xmlDict { Line 116  struct _xmlDict {
     int ref_counter;      int ref_counter;
   
     struct _xmlDictEntry *dict;      struct _xmlDictEntry *dict;
    int size;    size_t size;
    int nbElems;    unsigned int nbElems;
     xmlDictStringsPtr strings;      xmlDictStringsPtr strings;
   
     struct _xmlDict *subdict;      struct _xmlDict *subdict;
       /* used for randomization */
       int seed;
       /* used to impose a limit on size */
       size_t limit;
 };  };
   
 /*  /*
Line 111  static xmlRMutexPtr xmlDictMutex = NULL; Line 138  static xmlRMutexPtr xmlDictMutex = NULL;
  */   */
 static int xmlDictInitialized = 0;  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:   * xmlInitializeDict:
  *   *
  * Do the dictionary mutex initialization.   * 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   * 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)      if (xmlDictInitialized)
         return(1);          return(1);
   
     if ((xmlDictMutex = xmlNewRMutex()) == NULL)      if ((xmlDictMutex = xmlNewRMutex()) == NULL)
         return(0);          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;      xmlDictInitialized = 1;
       xmlRMutexUnlock(xmlDictMutex);
     return(1);      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:   * xmlDictCleanup:
  *   *
 * Free the dictionary mutex. * Free the dictionary mutex. Do not call unless sure the library
  * is not in use anymore !
  */   */
 void  void
 xmlDictCleanup(void) {  xmlDictCleanup(void) {
Line 148  xmlDictCleanup(void) { Line 231  xmlDictCleanup(void) {
  * xmlDictAddString:   * xmlDictAddString:
  * @dict: the dictionnary   * @dict: the dictionnary
  * @name: the name of the userdata   * @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]   * Add the string to the array[s]
  *   *
  * Returns the pointer of the local string, or NULL in case of error.   * Returns the pointer of the local string, or NULL in case of error.
  */   */
 static const xmlChar *  static const xmlChar *
xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
     xmlDictStringsPtr pool;      xmlDictStringsPtr pool;
     const xmlChar *ret;      const xmlChar *ret;
    int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */    size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
     size_t limit = 0;
   
 #ifdef DICT_DEBUG_PATTERNS  #ifdef DICT_DEBUG_PATTERNS
     fprintf(stderr, "-");      fprintf(stderr, "-");
Line 168  xmlDictAddString(xmlDictPtr dict, const xmlChar *name, Line 252  xmlDictAddString(xmlDictPtr dict, const xmlChar *name,
         if (pool->end - pool->free > namelen)          if (pool->end - pool->free > namelen)
             goto found_pool;              goto found_pool;
         if (pool->size > size) size = pool->size;          if (pool->size > size) size = pool->size;
           limit += pool->size;
         pool = pool->next;          pool = pool->next;
     }      }
     /*      /*
      * Not found, need to allocate       * Not found, need to allocate
      */       */
     if (pool == NULL) {      if (pool == NULL) {
           if ((dict->limit > 0) && (limit > dict->limit)) {
               return(NULL);
           }
   
         if (size == 0) size = 1000;          if (size == 0) size = 1000;
         else size *= 4; /* exponential growth */          else size *= 4; /* exponential growth */
        if (size < 4 * namelen)         if (size < 4 * namelen)
             size = 4 * namelen; /* just in case ! */              size = 4 * namelen; /* just in case ! */
         pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);          pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
         if (pool == NULL)          if (pool == NULL)
Line 206  found_pool: Line 295  found_pool:
  * @prefix: the prefix of the userdata   * @prefix: the prefix of the userdata
  * @plen: the prefix length   * @plen: the prefix length
  * @name: the name of the userdata   * @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]   * Add the QName to the array[s]
  *   *
  * Returns the pointer of the local string, or NULL in case of error.   * Returns the pointer of the local string, or NULL in case of error.
  */   */
 static const xmlChar *  static const xmlChar *
xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
                 const xmlChar *name, int namelen)                 const xmlChar *name, unsigned int namelen)
 {  {
     xmlDictStringsPtr pool;      xmlDictStringsPtr pool;
     const xmlChar *ret;      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));      if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
   
Line 230  xmlDictAddQString(xmlDictPtr dict, const xmlChar *pref Line 320  xmlDictAddQString(xmlDictPtr dict, const xmlChar *pref
         if (pool->end - pool->free > namelen + plen + 1)          if (pool->end - pool->free > namelen + plen + 1)
             goto found_pool;              goto found_pool;
         if (pool->size > size) size = pool->size;          if (pool->size > size) size = pool->size;
           limit += pool->size;
         pool = pool->next;          pool = pool->next;
     }      }
     /*      /*
      * Not found, need to allocate       * Not found, need to allocate
      */       */
     if (pool == NULL) {      if (pool == NULL) {
           if ((dict->limit > 0) && (limit > dict->limit)) {
               return(NULL);
           }
   
         if (size == 0) size = 1000;          if (size == 0) size = 1000;
         else size *= 4; /* exponential growth */          else size *= 4; /* exponential growth */
         if (size < 4 * (namelen + plen + 1))          if (size < 4 * (namelen + plen + 1))
Line 277  found_pool: Line 372  found_pool:
  */   */
   
 static uint32_t  static uint32_t
xmlDictComputeBigKey(const xmlChar* data, int namelen) {xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
     uint32_t hash;      uint32_t hash;
     int i;      int i;
   
     if (namelen <= 0 || data == NULL) return(0);      if (namelen <= 0 || data == NULL) return(0);
   
    hash = 0;    hash = seed;
   
     for (i = 0;i < namelen; i++) {      for (i = 0;i < namelen; i++) {
         hash += data[i];          hash += data[i];
Line 310  xmlDictComputeBigKey(const xmlChar* data, int namelen) Line 405  xmlDictComputeBigKey(const xmlChar* data, int namelen)
  */   */
 static unsigned long  static unsigned long
 xmlDictComputeBigQKey(const xmlChar *prefix, int plen,  xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
                      const xmlChar *name, int len)                      const xmlChar *name, int len, int seed)
 {  {
     uint32_t hash;      uint32_t hash;
     int i;      int i;
   
    hash = 0;    hash = seed;
   
     for (i = 0;i < plen; i++) {      for (i = 0;i < plen; i++) {
         hash += prefix[i];          hash += prefix[i];
Line 346  xmlDictComputeBigQKey(const xmlChar *prefix, int plen, Line 441  xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
  * for low hash table fill.   * for low hash table fill.
  */   */
 static unsigned long  static unsigned long
xmlDictComputeFastKey(const xmlChar *name, int namelen) {xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
    unsigned long value = 0L;    unsigned long value = seed;
   
     if (name == NULL) return(0);      if (name == NULL) return(0);
     value = *name;      value = *name;
Line 381  xmlDictComputeFastKey(const xmlChar *name, int namelen Line 476  xmlDictComputeFastKey(const xmlChar *name, int namelen
  */   */
 static unsigned long  static unsigned long
 xmlDictComputeFastQKey(const xmlChar *prefix, int plen,  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)      if (plen == 0)
         value += 30 * (unsigned long) ':';          value += 30 * (unsigned long) ':';
Line 442  xmlDictCreate(void) { Line 537  xmlDictCreate(void) {
     xmlDictPtr dict;      xmlDictPtr dict;
   
     if (!xmlDictInitialized)      if (!xmlDictInitialized)
        if (!xmlInitializeDict())        if (!__xmlInitializeDict())
             return(NULL);              return(NULL);
   
 #ifdef DICT_DEBUG_PATTERNS  #ifdef DICT_DEBUG_PATTERNS
Line 452  xmlDictCreate(void) { Line 547  xmlDictCreate(void) {
     dict = xmlMalloc(sizeof(xmlDict));      dict = xmlMalloc(sizeof(xmlDict));
     if (dict) {      if (dict) {
         dict->ref_counter = 1;          dict->ref_counter = 1;
           dict->limit = 0;
   
         dict->size = MIN_DICT_SIZE;          dict->size = MIN_DICT_SIZE;
         dict->nbElems = 0;          dict->nbElems = 0;
Line 460  xmlDictCreate(void) { Line 556  xmlDictCreate(void) {
         dict->subdict = NULL;          dict->subdict = NULL;
         if (dict->dict) {          if (dict->dict) {
             memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));              memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
   #ifdef DICT_RANDOMIZATION
               dict->seed = __xmlRandom();
   #else
               dict->seed = 0;
   #endif
             return(dict);              return(dict);
         }          }
         xmlFree(dict);          xmlFree(dict);
Line 486  xmlDictCreateSub(xmlDictPtr sub) { Line 587  xmlDictCreateSub(xmlDictPtr sub) {
 #ifdef DICT_DEBUG_PATTERNS  #ifdef DICT_DEBUG_PATTERNS
         fprintf(stderr, "R");          fprintf(stderr, "R");
 #endif  #endif
           dict->seed = sub->seed;
         dict->subdict = sub;          dict->subdict = sub;
         xmlDictReference(dict->subdict);          xmlDictReference(dict->subdict);
     }      }
Line 503  xmlDictCreateSub(xmlDictPtr sub) { Line 605  xmlDictCreateSub(xmlDictPtr sub) {
 int  int
 xmlDictReference(xmlDictPtr dict) {  xmlDictReference(xmlDictPtr dict) {
     if (!xmlDictInitialized)      if (!xmlDictInitialized)
        if (!xmlInitializeDict())        if (!__xmlInitializeDict())
             return(-1);              return(-1);
   
     if (dict == NULL) return -1;      if (dict == NULL) return -1;
Line 523  xmlDictReference(xmlDictPtr dict) { Line 625  xmlDictReference(xmlDictPtr dict) {
  * Returns 0 in case of success, -1 in case of failure   * Returns 0 in case of success, -1 in case of failure
  */   */
 static int  static int
xmlDictGrow(xmlDictPtr dict, int size) {xmlDictGrow(xmlDictPtr dict, size_t size) {
     unsigned long key, okey;      unsigned long key, okey;
    int oldsize, i;    size_t oldsize, i;
     xmlDictEntryPtr iter, next;      xmlDictEntryPtr iter, next;
     struct _xmlDictEntry *olddict;      struct _xmlDictEntry *olddict;
 #ifdef DEBUG_GROW  #ifdef DEBUG_GROW
Line 642  xmlDictGrow(xmlDictPtr dict, int size) { Line 744  xmlDictGrow(xmlDictPtr dict, int size) {
   
 #ifdef DEBUG_GROW  #ifdef DEBUG_GROW
     xmlGenericError(xmlGenericErrorContext,      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  #endif
   
     return(ret);      return(ret);
Line 657  xmlDictGrow(xmlDictPtr dict, int size) { Line 759  xmlDictGrow(xmlDictPtr dict, int size) {
  */   */
 void  void
 xmlDictFree(xmlDictPtr dict) {  xmlDictFree(xmlDictPtr dict) {
    int i;    size_t i;
     xmlDictEntryPtr iter;      xmlDictEntryPtr iter;
     xmlDictEntryPtr next;      xmlDictEntryPtr next;
     int inside_dict = 0;      int inside_dict = 0;
Line 667  xmlDictFree(xmlDictPtr dict) { Line 769  xmlDictFree(xmlDictPtr dict) {
         return;          return;
   
     if (!xmlDictInitialized)      if (!xmlDictInitialized)
        if (!xmlInitializeDict())        if (!__xmlInitializeDict())
             return;              return;
   
     /* decrement the counter, it may be shared by a parser and docs */      /* decrement the counter, it may be shared by a parser and docs */
Line 726  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in Line 828  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in
     xmlDictEntryPtr entry;      xmlDictEntryPtr entry;
     xmlDictEntryPtr insert;      xmlDictEntryPtr insert;
     const xmlChar *ret;      const xmlChar *ret;
       unsigned int l;
   
     if ((dict == NULL) || (name == NULL))      if ((dict == NULL) || (name == NULL))
         return(NULL);          return(NULL);
   
     if (len < 0)      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.       * Check for duplicate and insertion location.
      */       */
    okey = xmlDictComputeKey(dict, name, len);    okey = xmlDictComputeKey(dict, name, l);
     key = okey % dict->size;      key = okey % dict->size;
     if (dict->dict[key].valid == 0) {      if (dict->dict[key].valid == 0) {
         insert = NULL;          insert = NULL;
Line 744  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in Line 853  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in
         for (insert = &(dict->dict[key]); insert->next != NULL;          for (insert = &(dict->dict[key]); insert->next != NULL;
              insert = insert->next) {               insert = insert->next) {
 #ifdef __GNUC__  #ifdef __GNUC__
            if ((insert->okey == okey) && (insert->len == len)) {            if ((insert->okey == okey) && (insert->len == l)) {
                if (!memcmp(insert->name, name, len))                if (!memcmp(insert->name, name, l))
                     return(insert->name);                      return(insert->name);
             }              }
 #else  #else
            if ((insert->okey == okey) && (insert->len == len) &&            if ((insert->okey == okey) && (insert->len == l) &&
                (!xmlStrncmp(insert->name, name, len)))                (!xmlStrncmp(insert->name, name, l)))
                 return(insert->name);                  return(insert->name);
 #endif  #endif
             nbi++;              nbi++;
         }          }
 #ifdef __GNUC__  #ifdef __GNUC__
        if ((insert->okey == okey) && (insert->len == len)) {        if ((insert->okey == okey) && (insert->len == l)) {
            if (!memcmp(insert->name, name, len))            if (!memcmp(insert->name, name, l))
                 return(insert->name);                  return(insert->name);
         }          }
 #else  #else
        if ((insert->okey == okey) && (insert->len == len) &&        if ((insert->okey == okey) && (insert->len == l) &&
            (!xmlStrncmp(insert->name, name, len)))            (!xmlStrncmp(insert->name, name, l)))
             return(insert->name);              return(insert->name);
 #endif  #endif
     }      }
Line 775  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in Line 884  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in
              (dict->subdict->size != MIN_DICT_SIZE)) ||               (dict->subdict->size != MIN_DICT_SIZE)) ||
             ((dict->size != MIN_DICT_SIZE) &&              ((dict->size != MIN_DICT_SIZE) &&
              (dict->subdict->size == MIN_DICT_SIZE)))               (dict->subdict->size == MIN_DICT_SIZE)))
            skey = xmlDictComputeKey(dict->subdict, name, len);            skey = xmlDictComputeKey(dict->subdict, name, l);
         else          else
             skey = okey;              skey = okey;
   
Line 786  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in Line 895  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in
             for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;              for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
                  tmp = tmp->next) {                   tmp = tmp->next) {
 #ifdef __GNUC__  #ifdef __GNUC__
                if ((tmp->okey == skey) && (tmp->len == len)) {                if ((tmp->okey == skey) && (tmp->len == l)) {
                    if (!memcmp(tmp->name, name, len))                    if (!memcmp(tmp->name, name, l))
                         return(tmp->name);                          return(tmp->name);
                 }                  }
 #else  #else
                if ((tmp->okey == skey) && (tmp->len == len) &&                if ((tmp->okey == skey) && (tmp->len == l) &&
                    (!xmlStrncmp(tmp->name, name, len)))                    (!xmlStrncmp(tmp->name, name, l)))
                     return(tmp->name);                      return(tmp->name);
 #endif  #endif
                 nbi++;                  nbi++;
             }              }
 #ifdef __GNUC__  #ifdef __GNUC__
            if ((tmp->okey == skey) && (tmp->len == len)) {            if ((tmp->okey == skey) && (tmp->len == l)) {
                if (!memcmp(tmp->name, name, len))                if (!memcmp(tmp->name, name, l))
                     return(tmp->name);                      return(tmp->name);
             }              }
 #else  #else
            if ((tmp->okey == skey) && (tmp->len == len) &&            if ((tmp->okey == skey) && (tmp->len == l) &&
                (!xmlStrncmp(tmp->name, name, len)))                (!xmlStrncmp(tmp->name, name, l)))
                 return(tmp->name);                  return(tmp->name);
 #endif  #endif
         }          }
         key = okey % dict->size;          key = okey % dict->size;
     }      }
   
    ret = xmlDictAddString(dict, name, len);    ret = xmlDictAddString(dict, name, l);
     if (ret == NULL)      if (ret == NULL)
         return(NULL);          return(NULL);
     if (insert == NULL) {      if (insert == NULL) {
Line 822  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in Line 931  xmlDictLookup(xmlDictPtr dict, const xmlChar *name, in
              return(NULL);               return(NULL);
     }      }
     entry->name = ret;      entry->name = ret;
    entry->len = len;    entry->len = l;
     entry->next = NULL;      entry->next = NULL;
     entry->valid = 1;      entry->valid = 1;
     entry->okey = okey;      entry->okey = okey;
   
   
    if (insert != NULL)     if (insert != NULL)
         insert->next = entry;          insert->next = entry;
   
     dict->nbElems++;      dict->nbElems++;
Line 857  const xmlChar * Line 966  const xmlChar *
 xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {  xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
     unsigned long key, okey, nbi = 0;      unsigned long key, okey, nbi = 0;
     xmlDictEntryPtr insert;      xmlDictEntryPtr insert;
       unsigned int l;
   
     if ((dict == NULL) || (name == NULL))      if ((dict == NULL) || (name == NULL))
         return(NULL);          return(NULL);
   
     if (len < 0)      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.       * Check for duplicate and insertion location.
      */       */
    okey = xmlDictComputeKey(dict, name, len);    okey = xmlDictComputeKey(dict, name, l);
     key = okey % dict->size;      key = okey % dict->size;
     if (dict->dict[key].valid == 0) {      if (dict->dict[key].valid == 0) {
         insert = NULL;          insert = NULL;
Line 875  xmlDictExists(xmlDictPtr dict, const xmlChar *name, in Line 990  xmlDictExists(xmlDictPtr dict, const xmlChar *name, in
         for (insert = &(dict->dict[key]); insert->next != NULL;          for (insert = &(dict->dict[key]); insert->next != NULL;
              insert = insert->next) {               insert = insert->next) {
 #ifdef __GNUC__  #ifdef __GNUC__
            if ((insert->okey == okey) && (insert->len == len)) {            if ((insert->okey == okey) && (insert->len == l)) {
                if (!memcmp(insert->name, name, len))                if (!memcmp(insert->name, name, l))
                     return(insert->name);                      return(insert->name);
             }              }
 #else  #else
            if ((insert->okey == okey) && (insert->len == len) &&            if ((insert->okey == okey) && (insert->len == l) &&
                (!xmlStrncmp(insert->name, name, len)))                (!xmlStrncmp(insert->name, name, l)))
                 return(insert->name);                  return(insert->name);
 #endif  #endif
             nbi++;              nbi++;
         }          }
 #ifdef __GNUC__  #ifdef __GNUC__
        if ((insert->okey == okey) && (insert->len == len)) {        if ((insert->okey == okey) && (insert->len == l)) {
            if (!memcmp(insert->name, name, len))            if (!memcmp(insert->name, name, l))
                 return(insert->name);                  return(insert->name);
         }          }
 #else  #else
        if ((insert->okey == okey) && (insert->len == len) &&        if ((insert->okey == okey) && (insert->len == l) &&
            (!xmlStrncmp(insert->name, name, len)))            (!xmlStrncmp(insert->name, name, l)))
             return(insert->name);              return(insert->name);
 #endif  #endif
     }      }
Line 906  xmlDictExists(xmlDictPtr dict, const xmlChar *name, in Line 1021  xmlDictExists(xmlDictPtr dict, const xmlChar *name, in
              (dict->subdict->size != MIN_DICT_SIZE)) ||               (dict->subdict->size != MIN_DICT_SIZE)) ||
             ((dict->size != MIN_DICT_SIZE) &&              ((dict->size != MIN_DICT_SIZE) &&
              (dict->subdict->size == MIN_DICT_SIZE)))               (dict->subdict->size == MIN_DICT_SIZE)))
            skey = xmlDictComputeKey(dict->subdict, name, len);            skey = xmlDictComputeKey(dict->subdict, name, l);
         else          else
             skey = okey;              skey = okey;
   
Line 917  xmlDictExists(xmlDictPtr dict, const xmlChar *name, in Line 1032  xmlDictExists(xmlDictPtr dict, const xmlChar *name, in
             for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;              for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
                  tmp = tmp->next) {                   tmp = tmp->next) {
 #ifdef __GNUC__  #ifdef __GNUC__
                if ((tmp->okey == skey) && (tmp->len == len)) {                if ((tmp->okey == skey) && (tmp->len == l)) {
                    if (!memcmp(tmp->name, name, len))                    if (!memcmp(tmp->name, name, l))
                         return(tmp->name);                          return(tmp->name);
                 }                  }
 #else  #else
                if ((tmp->okey == skey) && (tmp->len == len) &&                if ((tmp->okey == skey) && (tmp->len == l) &&
                    (!xmlStrncmp(tmp->name, name, len)))                    (!xmlStrncmp(tmp->name, name, l)))
                     return(tmp->name);                      return(tmp->name);
 #endif  #endif
                 nbi++;                  nbi++;
             }              }
 #ifdef __GNUC__  #ifdef __GNUC__
            if ((tmp->okey == skey) && (tmp->len == len)) {            if ((tmp->okey == skey) && (tmp->len == l)) {
                if (!memcmp(tmp->name, name, len))                if (!memcmp(tmp->name, name, l))
                     return(tmp->name);                      return(tmp->name);
             }              }
 #else  #else
            if ((tmp->okey == skey) && (tmp->len == len) &&            if ((tmp->okey == skey) && (tmp->len == l) &&
                (!xmlStrncmp(tmp->name, name, len)))                (!xmlStrncmp(tmp->name, name, l)))
                 return(tmp->name);                  return(tmp->name);
 #endif  #endif
         }          }
Line 961  xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, Line 1076  xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix,
     xmlDictEntryPtr entry;      xmlDictEntryPtr entry;
     xmlDictEntryPtr insert;      xmlDictEntryPtr insert;
     const xmlChar *ret;      const xmlChar *ret;
    int len, plen, l;    unsigned int len, plen, l;
   
     if ((dict == NULL) || (name == NULL))      if ((dict == NULL) || (name == NULL))
         return(NULL);          return(NULL);
Line 1037  xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, Line 1152  xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix,
     entry->valid = 1;      entry->valid = 1;
     entry->okey = okey;      entry->okey = okey;
   
    if (insert != NULL)     if (insert != NULL)
         insert->next = entry;          insert->next = entry;
   
     dict->nbElems++;      dict->nbElems++;
Line 1095  xmlDictSize(xmlDictPtr dict) { Line 1210  xmlDictSize(xmlDictPtr dict) {
     return(dict->nbElems);      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  #define bottom_dict
 #include "elfgcchack.h"  #include "elfgcchack.h"

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>