diff --git a/buf.c b/buf.c index 161160a2..6749d975 100644 --- a/buf.c +++ b/buf.c @@ -436,9 +436,11 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) { if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); if (len < buf->size - buf->use) - return(buf->size - buf->use); - if (len > SIZE_MAX - buf->use) + return(buf->size - buf->use - 1); + if (len >= SIZE_MAX - buf->use) { + xmlBufMemoryError(buf, "growing buffer past SIZE_MAX"); return(0); + } if (buf->size > (size_t) len) { size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2; @@ -451,7 +453,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) { /* * Used to provide parsing limits */ - if ((buf->use + len >= XML_MAX_TEXT_LENGTH) || + if ((buf->use + len + 1 >= XML_MAX_TEXT_LENGTH) || (buf->size >= XML_MAX_TEXT_LENGTH)) { xmlBufMemoryError(buf, "buffer error: text too long\n"); return(0); @@ -479,7 +481,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) { } buf->size = size; UPDATE_COMPAT(buf) - return(buf->size - buf->use); + return(buf->size - buf->use - 1); } /** @@ -839,9 +841,12 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { if (len < 0) return -1; if (len == 0) return 0; + /* Note that both buf->size and buf->use can be zero here. */ if ((size_t) len >= buf->size - buf->use) { - if ((size_t) len >= SIZE_MAX - buf->use) + if ((size_t) len >= SIZE_MAX - buf->use) { + xmlBufMemoryError(buf, "growing buffer past SIZE_MAX"); return(-1); + } needSize = buf->use + len + 1; if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { /* diff --git a/tree.c b/tree.c index 33de5dfb..2392b994 100644 --- a/tree.c +++ b/tree.c @@ -7371,8 +7371,10 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) { if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); if (len < buf->size - buf->use) return(0); - if (len > UINT_MAX - buf->use) + if (len >= UINT_MAX - buf->use) { + xmlTreeErrMemory("growing buffer past UINT_MAX"); return(-1); + } if (buf->size > (size_t) len) { size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2; @@ -7400,7 +7402,7 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) { buf->content = newbuf; } buf->size = size; - return(buf->size - buf->use); + return(buf->size - buf->use - 1); } /** @@ -7497,7 +7499,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) return 1; if (size > UINT_MAX - 10) { - xmlTreeErrMemory("growing buffer"); + xmlTreeErrMemory("growing buffer past UINT_MAX"); return 0; } @@ -7625,9 +7627,12 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) { if (len < 0) return -1; if (len == 0) return 0; + /* Note that both buf->size and buf->use can be zero here. */ if ((unsigned) len >= buf->size - buf->use) { - if ((unsigned) len >= UINT_MAX - buf->use) + if ((unsigned) len >= UINT_MAX - buf->use) { + xmlTreeErrMemory("growing buffer past UINT_MAX"); return XML_ERR_NO_MEMORY; + } needSize = buf->use + len + 1; if (!xmlBufferResize(buf, needSize)){ xmlTreeErrMemory("growing buffer"); @@ -7696,8 +7701,13 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) { return(0); } } - needSize = buf->use + len + 2; - if (needSize > buf->size){ + /* Note that both buf->size and buf->use can be zero here. */ + if ((unsigned) len >= buf->size - buf->use) { + if ((unsigned) len >= UINT_MAX - buf->use) { + xmlTreeErrMemory("growing buffer past UINT_MAX"); + return(-1); + } + needSize = buf->use + len + 1; if (!xmlBufferResize(buf, needSize)){ xmlTreeErrMemory("growing buffer"); return XML_ERR_NO_MEMORY;