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) { |