Diff for /embedaddon/libxml2/parser.c between versions 1.1.1.2 and 1.1.1.2.2.1

version 1.1.1.2, 2013/07/22 01:22:20 version 1.1.1.2.2.1, 2013/07/22 01:28:50
Line 40 Line 40
 #endif  #endif
   
 #include <stdlib.h>  #include <stdlib.h>
   #include <limits.h>
 #include <string.h>  #include <string.h>
 #include <stdarg.h>  #include <stdarg.h>
 #include <libxml/xmlmemory.h>  #include <libxml/xmlmemory.h>
Line 117  xmlCreateEntityParserCtxtInternal(const xmlChar *URL,  Line 118  xmlCreateEntityParserCtxtInternal(const xmlChar *URL, 
  * parser option.   * parser option.
  */   */
 static int  static int
xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
                     xmlEntityPtr ent)                     xmlEntityPtr ent, size_t replacement)
 {  {
    unsigned long consumed = 0;    size_t consumed = 0;
   
     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))      if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
         return (0);          return (0);
     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)      if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
         return (1);          return (1);
    if (size != 0) {    if (replacement != 0) {
         if (replacement < XML_MAX_TEXT_LENGTH)
             return(0);
 
         /*          /*
            * If the volume of entity copy reaches 10 times the
            * amount of parsed data and over the large text threshold
            * then that's very likely to be an abuse.
            */
           if (ctxt->input != NULL) {
               consumed = ctxt->input->consumed +
                          (ctxt->input->cur - ctxt->input->base);
           }
           consumed += ctxt->sizeentities;
   
           if (replacement < XML_PARSER_NON_LINEAR * consumed)
               return(0);
       } else if (size != 0) {
           /*
          * Do the check based on the replacement size of the entity           * Do the check based on the replacement size of the entity
          */           */
         if (size < XML_PARSER_BIG_ENTITY)          if (size < XML_PARSER_BIG_ENTITY)
Line 172  xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned l Line 190  xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned l
          */           */
         return (0);          return (0);
     }      }
   
     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);      xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
     return (1);      return (1);
 }  }
Line 2589  xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) { Line 2606  xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
   
 /*  /*
  * Macro used to grow the current buffer.   * Macro used to grow the current buffer.
    * buffer##_size is expected to be a size_t
    * mem_error: is expected to handle memory allocation failures
  */   */
 #define growBuffer(buffer, n) {                                         \  #define growBuffer(buffer, n) {                                         \
     xmlChar *tmp;                                                       \      xmlChar *tmp;                                                       \
    buffer##_size *= 2;                                                    \    size_t new_size = buffer##_size * 2 + n;                            \
    buffer##_size += n;                                                        \    if (new_size < buffer##_size) goto mem_error;                       \
    tmp = (xmlChar *)                                                   \    tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
                xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));     \ 
     if (tmp == NULL) goto mem_error;                                    \      if (tmp == NULL) goto mem_error;                                    \
     buffer = tmp;                                                       \      buffer = tmp;                                                       \
       buffer##_size = new_size;                                           \
 }  }
   
 /**  /**
Line 2623  xmlChar * Line 2642  xmlChar *
 xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                       int what, xmlChar end, xmlChar  end2, xmlChar end3) {                        int what, xmlChar end, xmlChar  end2, xmlChar end3) {
     xmlChar *buffer = NULL;      xmlChar *buffer = NULL;
    int buffer_size = 0;    size_t buffer_size = 0;
     size_t nbchars = 0;
   
     xmlChar *current = NULL;      xmlChar *current = NULL;
     xmlChar *rep = NULL;      xmlChar *rep = NULL;
     const xmlChar *last;      const xmlChar *last;
     xmlEntityPtr ent;      xmlEntityPtr ent;
     int c,l;      int c,l;
     int nbchars = 0;  
   
     if ((ctxt == NULL) || (str == NULL) || (len < 0))      if ((ctxt == NULL) || (str == NULL) || (len < 0))
         return(NULL);          return(NULL);
Line 2647  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2666  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
      * allocate a translation buffer.       * allocate a translation buffer.
      */       */
     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;      buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));    buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
     if (buffer == NULL) goto mem_error;      if (buffer == NULL) goto mem_error;
   
     /*      /*
Line 2667  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2686  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
             if (val != 0) {              if (val != 0) {
                 COPY_BUF(0,buffer,nbchars,val);                  COPY_BUF(0,buffer,nbchars,val);
             }              }
            if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                 growBuffer(buffer, XML_PARSER_BUFFER_SIZE);                  growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
             }              }
         } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {          } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
Line 2685  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2704  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
                 (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {                  (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                 if (ent->content != NULL) {                  if (ent->content != NULL) {
                     COPY_BUF(0,buffer,nbchars,ent->content[0]);                      COPY_BUF(0,buffer,nbchars,ent->content[0]);
                    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                         growBuffer(buffer, XML_PARSER_BUFFER_SIZE);                          growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                     }                      }
                 } else {                  } else {
Line 2702  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2721  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
                     current = rep;                      current = rep;
                     while (*current != 0) { /* non input consuming loop */                      while (*current != 0) { /* non input consuming loop */
                         buffer[nbchars++] = *current++;                          buffer[nbchars++] = *current++;
                        if (nbchars >                        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                            buffer_size - XML_PARSER_BUFFER_SIZE) {                            if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
                            if (xmlParserEntityCheck(ctxt, nbchars, ent)) 
                                 goto int_error;                                  goto int_error;
                             growBuffer(buffer, XML_PARSER_BUFFER_SIZE);                              growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                         }                          }
Line 2717  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2735  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
                 const xmlChar *cur = ent->name;                  const xmlChar *cur = ent->name;
   
                 buffer[nbchars++] = '&';                  buffer[nbchars++] = '&';
                if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {                if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
                     growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);                      growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
                 }                  }
                 for (;i > 0;i--)                  for (;i > 0;i--)
Line 2745  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2763  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
                     current = rep;                      current = rep;
                     while (*current != 0) { /* non input consuming loop */                      while (*current != 0) { /* non input consuming loop */
                         buffer[nbchars++] = *current++;                          buffer[nbchars++] = *current++;
                        if (nbchars >                        if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                            buffer_size - XML_PARSER_BUFFER_SIZE) {                            if (xmlParserEntityCheck(ctxt, nbchars, ent, 0))
                            if (xmlParserEntityCheck(ctxt, nbchars, ent)) 
                                 goto int_error;                                  goto int_error;
                             growBuffer(buffer, XML_PARSER_BUFFER_SIZE);                              growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                         }                          }
Line 2759  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons Line 2776  xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, cons
         } else {          } else {
             COPY_BUF(l,buffer,nbchars,c);              COPY_BUF(l,buffer,nbchars,c);
             str += l;              str += l;
            if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
              growBuffer(buffer, XML_PARSER_BUFFER_SIZE);                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
             }              }
         }          }
         if (str < last)          if (str < last)
Line 3764  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3781  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
     xmlChar limit = 0;      xmlChar limit = 0;
     xmlChar *buf = NULL;      xmlChar *buf = NULL;
     xmlChar *rep = NULL;      xmlChar *rep = NULL;
    int len = 0;    size_t len = 0;
    int buf_size = 0;    size_t buf_size = 0;
     int c, l, in_space = 0;      int c, l, in_space = 0;
     xmlChar *current = NULL;      xmlChar *current = NULL;
     xmlEntityPtr ent;      xmlEntityPtr ent;
Line 3787  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3804  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
      * allocate a translation buffer.       * allocate a translation buffer.
      */       */
     buf_size = XML_PARSER_BUFFER_SIZE;      buf_size = XML_PARSER_BUFFER_SIZE;
    buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));    buf = (xmlChar *) xmlMallocAtomic(buf_size);
     if (buf == NULL) goto mem_error;      if (buf == NULL) goto mem_error;
   
     /*      /*
Line 3804  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3821  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
   
                 if (val == '&') {                  if (val == '&') {
                     if (ctxt->replaceEntities) {                      if (ctxt->replaceEntities) {
                        if (len > buf_size - 10) {                        if (len + 10 > buf_size) {
                             growBuffer(buf, 10);                              growBuffer(buf, 10);
                         }                          }
                         buf[len++] = '&';                          buf[len++] = '&';
Line 3813  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3830  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                          * The reparsing will be done in xmlStringGetNodeList()                           * The reparsing will be done in xmlStringGetNodeList()
                          * called by the attribute() function in SAX.c                           * called by the attribute() function in SAX.c
                          */                           */
                        if (len > buf_size - 10) {                        if (len + 10 > buf_size) {
                             growBuffer(buf, 10);                              growBuffer(buf, 10);
                         }                          }
                         buf[len++] = '&';                          buf[len++] = '&';
Line 3823  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3840  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                         buf[len++] = ';';                          buf[len++] = ';';
                     }                      }
                 } else if (val != 0) {                  } else if (val != 0) {
                    if (len > buf_size - 10) {                    if (len + 10 > buf_size) {
                         growBuffer(buf, 10);                          growBuffer(buf, 10);
                     }                      }
                     len += xmlCopyChar(0, &buf[len], val);                      len += xmlCopyChar(0, &buf[len], val);
Line 3835  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3852  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                     ctxt->nbentities += ent->owner;                      ctxt->nbentities += ent->owner;
                 if ((ent != NULL) &&                  if ((ent != NULL) &&
                     (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {                      (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                    if (len > buf_size - 10) {                    if (len + 10 > buf_size) {
                         growBuffer(buf, 10);                          growBuffer(buf, 10);
                     }                      }
                     if ((ctxt->replaceEntities == 0) &&                      if ((ctxt->replaceEntities == 0) &&
Line 3863  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3880  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                                     current++;                                      current++;
                                 } else                                  } else
                                     buf[len++] = *current++;                                      buf[len++] = *current++;
                                if (len > buf_size - 10) {                                if (len + 10 > buf_size) {
                                     growBuffer(buf, 10);                                      growBuffer(buf, 10);
                                 }                                  }
                             }                              }
Line 3871  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3888  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                             rep = NULL;                              rep = NULL;
                         }                          }
                     } else {                      } else {
                        if (len > buf_size - 10) {                        if (len + 10 > buf_size) {
                             growBuffer(buf, 10);                              growBuffer(buf, 10);
                         }                          }
                         if (ent->content != NULL)                          if (ent->content != NULL)
Line 3899  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3916  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                      * Just output the reference                       * Just output the reference
                      */                       */
                     buf[len++] = '&';                      buf[len++] = '&';
                    while (len > buf_size - i - 10) {                    while (len + i + 10 > buf_size) {
                         growBuffer(buf, i + 10);                          growBuffer(buf, i + 10);
                     }                      }
                     for (;i > 0;i--)                      for (;i > 0;i--)
Line 3912  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3929  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
                 if ((len != 0) || (!normalize)) {                  if ((len != 0) || (!normalize)) {
                     if ((!normalize) || (!in_space)) {                      if ((!normalize) || (!in_space)) {
                         COPY_BUF(l,buf,len,0x20);                          COPY_BUF(l,buf,len,0x20);
                        while (len > buf_size - 10) {                        while (len + 10 > buf_size) {
                             growBuffer(buf, 10);                              growBuffer(buf, 10);
                         }                          }
                     }                      }
Line 3921  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3938  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
             } else {              } else {
                 in_space = 0;                  in_space = 0;
                 COPY_BUF(l,buf,len,c);                  COPY_BUF(l,buf,len,c);
                if (len > buf_size - 10) {                if (len + 10 > buf_size) {
                     growBuffer(buf, 10);                      growBuffer(buf, 10);
                 }                  }
             }              }
Line 3931  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3948  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
         c = CUR_CHAR(l);          c = CUR_CHAR(l);
     }      }
     if ((in_space) && (normalize)) {      if ((in_space) && (normalize)) {
        while (buf[len - 1] == 0x20) len--;        while ((len > 0) && (buf[len - 1] == 0x20)) len--;
     }      }
     buf[len] = 0;      buf[len] = 0;
     if (RAW == '<') {      if (RAW == '<') {
Line 3946  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at Line 3963  xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *at
         }          }
     } else      } else
         NEXT;          NEXT;
    if (attlen != NULL) *attlen = len;
     /*
      * There we potentially risk an overflow, don't allow attribute value of
      * lenght more than INT_MAX it is a very reasonnable assumption !
      */
     if (len >= INT_MAX) {
         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
                        "AttValue lenght too long\n");
         goto mem_error;
     }
 
     if (attlen != NULL) *attlen = (int) len;
     return(buf);      return(buf);
   
 mem_error:  mem_error:
Line 6964  xmlParseReference(xmlParserCtxtPtr ctxt) { Line 6992  xmlParseReference(xmlParserCtxtPtr ctxt) {
             xmlFreeNodeList(list);              xmlFreeNodeList(list);
             return;              return;
         }          }
        if (xmlParserEntityCheck(ctxt, 0, ent)) {        if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
             xmlFreeNodeList(list);              xmlFreeNodeList(list);
             return;              return;
         }          }
Line 7124  xmlParseReference(xmlParserCtxtPtr ctxt) { Line 7152  xmlParseReference(xmlParserCtxtPtr ctxt) {
                 xmlNodePtr nw = NULL, cur, firstChild = NULL;                  xmlNodePtr nw = NULL, cur, firstChild = NULL;
   
                 /*                  /*
                    * We are copying here, make sure there is no abuse
                    */
                   ctxt->sizeentcopy += ent->length;
                   if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
                       return;
   
                   /*
                  * when operating on a reader, the entities definitions                   * when operating on a reader, the entities definitions
                  * are always owning the entities subtree.                   * are always owning the entities subtree.
                 if (ctxt->parseMode == XML_PARSE_READER)                  if (ctxt->parseMode == XML_PARSE_READER)
Line 7163  xmlParseReference(xmlParserCtxtPtr ctxt) { Line 7198  xmlParseReference(xmlParserCtxtPtr ctxt) {
             } else if (list == NULL) {              } else if (list == NULL) {
                 xmlNodePtr nw = NULL, cur, next, last,                  xmlNodePtr nw = NULL, cur, next, last,
                            firstChild = NULL;                             firstChild = NULL;
   
                 /*                  /*
                    * We are copying here, make sure there is no abuse
                    */
                   ctxt->sizeentcopy += ent->length;
                   if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
                       return;
   
                   /*
                  * Copy the entity child list and make it the new                   * Copy the entity child list and make it the new
                  * entity child list. The goal is to make sure any                   * entity child list. The goal is to make sure any
                  * ID or REF referenced will be the one from the                   * ID or REF referenced will be the one from the
Line 14343  xmlCtxtReset(xmlParserCtxtPtr ctxt) Line 14386  xmlCtxtReset(xmlParserCtxtPtr ctxt)
     ctxt->catalogs = NULL;      ctxt->catalogs = NULL;
     ctxt->nbentities = 0;      ctxt->nbentities = 0;
     ctxt->sizeentities = 0;      ctxt->sizeentities = 0;
       ctxt->sizeentcopy = 0;
     xmlInitNodeInfoSeq(&ctxt->node_seq);      xmlInitNodeInfoSeq(&ctxt->node_seq);
   
     if (ctxt->attsDefault != NULL) {      if (ctxt->attsDefault != NULL) {

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.2.2.1


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