#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
#include "buf.h"
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1)
+#endif
+
#define WITH_BUFFER_COMPAT
/**
xmlBufCreateSize(size_t size) {
xmlBufPtr ret;
+ if (size == SIZE_MAX)
+ return(NULL);
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
if (ret == NULL) {
xmlBufMemoryError(NULL, "creating buffer");
ret->error = 0;
ret->buffer = NULL;
ret->alloc = xmlBufferAllocScheme;
- ret->size = (size ? size+2 : 0); /* +1 for ending null */
+ ret->size = (size ? size + 1 : 0); /* +1 for ending null */
ret->compat_size = (int) ret->size;
if (ret->size){
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
CHECK_COMPAT(buf)
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
- if (buf->use + len < buf->size)
+ if (len < buf->size - buf->use)
return(buf->size - buf->use);
+ if (len > SIZE_MAX - buf->use)
+ return(0);
- /*
- * Windows has a BIG problem on realloc timing, so we try to double
- * the buffer size (if that's enough) (bug 146697)
- * Apparently BSD too, and it's probably best for linux too
- * On an embedded system this may be something to change
- */
-#if 1
- if (buf->size > (size_t) len)
- size = buf->size * 2;
- else
- size = buf->use + len + 100;
-#else
- size = buf->use + len + 100;
-#endif
+ if (buf->size > (size_t) len) {
+ size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2;
+ } else {
+ size = buf->use + len;
+ size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100;
+ }
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
/*
int
xmlBufResize(xmlBufPtr buf, size_t size)
{
- unsigned int newSize;
+ size_t newSize;
xmlChar* rebuf = NULL;
size_t start_buf;
case XML_BUFFER_ALLOC_IO:
case XML_BUFFER_ALLOC_DOUBLEIT:
/*take care of empty case*/
- newSize = (buf->size ? buf->size*2 : size + 10);
+ if (buf->size == 0) {
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
+ } else {
+ newSize = buf->size;
+ }
while (size > newSize) {
- if (newSize > UINT_MAX / 2) {
+ if (newSize > SIZE_MAX / 2) {
xmlBufMemoryError(buf, "growing buffer");
return 0;
}
}
break;
case XML_BUFFER_ALLOC_EXACT:
- newSize = size+10;
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
break;
case XML_BUFFER_ALLOC_HYBRID:
if (buf->use < BASE_BUFFER_SIZE)
newSize = size;
else {
- newSize = buf->size * 2;
+ newSize = buf->size;
while (size > newSize) {
- if (newSize > UINT_MAX / 2) {
+ if (newSize > SIZE_MAX / 2) {
xmlBufMemoryError(buf, "growing buffer");
return 0;
}
break;
default:
- newSize = size+10;
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
break;
}
*/
int
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
- unsigned int needSize;
+ size_t needSize;
if ((str == NULL) || (buf == NULL) || (buf->error))
return -1;
if (len < 0) return -1;
if (len == 0) return 0;
- needSize = buf->use + len + 2;
- if (needSize > buf->size){
+ if ((size_t) len >= buf->size - buf->use) {
+ if ((size_t) len >= SIZE_MAX - buf->use)
+ return(-1);
+ needSize = buf->use + len + 1;
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
/*
* Used to provide parsing limits
*/
int
xmlBufCCat(xmlBufPtr buf, const char *str) {
- const char *cur;
-
- if ((buf == NULL) || (buf->error))
- return(-1);
- CHECK_COMPAT(buf)
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
- if (str == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufCCat: str == NULL\n");
-#endif
- return -1;
- }
- for (cur = str;*cur != 0;cur++) {
- if (buf->use + 10 >= buf->size) {
- if (!xmlBufResize(buf, buf->use+10)){
- xmlBufMemoryError(buf, "growing buffer");
- return XML_ERR_NO_MEMORY;
- }
- }
- buf->content[buf->use++] = *cur;
- }
- buf->content[buf->use] = 0;
- UPDATE_COMPAT(buf)
- return 0;
+ return xmlBufCat(buf, (const xmlChar *) str);
}
/**
xmlBufferCreateSize(size_t size) {
xmlBufferPtr ret;
+ if (size >= UINT_MAX)
+ return(NULL);
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
if (ret == NULL) {
xmlTreeErrMemory("creating buffer");
}
ret->use = 0;
ret->alloc = xmlBufferAllocScheme;
- ret->size = (size ? size+2 : 0); /* +1 for ending null */
+ ret->size = (size ? size + 1 : 0); /* +1 for ending null */
if (ret->size){
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
if (ret->content == NULL) {
if ((mem == NULL) || (size == 0))
return(NULL);
+ if (size > UINT_MAX)
+ return(NULL);
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
if (ret == NULL) {
*/
int
xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
- int size;
+ unsigned int size;
xmlChar *newbuf;
if (buf == NULL) return(-1);
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
- if (len + buf->use < buf->size) return(0);
+ if (len < buf->size - buf->use)
+ return(0);
+ if (len > UINT_MAX - buf->use)
+ return(-1);
- /*
- * Windows has a BIG problem on realloc timing, so we try to double
- * the buffer size (if that's enough) (bug 146697)
- * Apparently BSD too, and it's probably best for linux too
- * On an embedded system this may be something to change
- */
-#if 1
- if (buf->size > len)
- size = buf->size * 2;
- else
- size = buf->use + len + 100;
-#else
- size = buf->use + len + 100;
-#endif
+ if (buf->size > (size_t) len) {
+ size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2;
+ } else {
+ size = buf->use + len;
+ size = size > UINT_MAX - 100 ? UINT_MAX : size + 100;
+ }
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
size_t start_buf = buf->content - buf->contentIO;
case XML_BUFFER_ALLOC_IO:
case XML_BUFFER_ALLOC_DOUBLEIT:
/*take care of empty case*/
- newSize = (buf->size ? buf->size*2 : size + 10);
+ if (buf->size == 0)
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);
+ else
+ newSize = buf->size;
while (size > newSize) {
if (newSize > UINT_MAX / 2) {
xmlTreeErrMemory("growing buffer");
}
break;
case XML_BUFFER_ALLOC_EXACT:
- newSize = size+10;
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
break;
case XML_BUFFER_ALLOC_HYBRID:
if (buf->use < BASE_BUFFER_SIZE)
break;
default:
- newSize = size+10;
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
break;
}
if (len < 0) return -1;
if (len == 0) return 0;
- needSize = buf->use + len + 2;
- if (needSize > buf->size){
+ if ((unsigned) len >= buf->size - buf->use) {
+ if ((unsigned) len >= UINT_MAX - buf->use)
+ return XML_ERR_NO_MEMORY;
+ needSize = buf->use + len + 1;
if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer");
return XML_ERR_NO_MEMORY;
*/
int
xmlBufferCCat(xmlBufferPtr buf, const char *str) {
- const char *cur;
-
- if (buf == NULL)
- return(-1);
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
- if (str == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCCat: str == NULL\n");
-#endif
- return -1;
- }
- for (cur = str;*cur != 0;cur++) {
- if (buf->use + 10 >= buf->size) {
- if (!xmlBufferResize(buf, buf->use+10)){
- xmlTreeErrMemory("growing buffer");
- return XML_ERR_NO_MEMORY;
- }
- }
- buf->content[buf->use++] = *cur;
- }
- buf->content[buf->use] = 0;
- return 0;
+ return xmlBufferCat(buf, (const xmlChar *) str);
}
/**