1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-12 09:17:37 +03:00

Reserve byte for NUL terminator and report errors consistently in xmlBuf and xmlBuffer

This is a follow-up to commit 6c283d83.

* buf.c:
(xmlBufGrowInternal):
- Call xmlBufMemoryError() when the buffer size would overflow.
- Account for NUL terminator byte when using XML_MAX_TEXT_LENGTH.
- Do not include NUL terminator byte when returning length.
(xmlBufAdd):
- Call xmlBufMemoryError() when the buffer size would overflow.

* tree.c:
(xmlBufferGrow):
- Call xmlTreeErrMemory() when the buffer size would overflow.
- Do not include NUL terminator byte when returning length.
(xmlBufferResize):
- Update error message in xmlTreeErrMemory() to be consistent
  with other similar messages.
(xmlBufferAdd):
- Call xmlTreeErrMemory() when the buffer size would overflow.
(xmlBufferAddHead):
- Add overflow checks similar to those in xmlBufferAdd().
This commit is contained in:
David Kilzer 2022-05-13 14:43:33 -07:00 committed by Nick Wellnhofer
parent 4ce2abf6f6
commit 6ef16dee7a
2 changed files with 26 additions and 11 deletions

15
buf.c
View File

@ -436,9 +436,11 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
if (len < buf->size - buf->use) if (len < buf->size - buf->use)
return(buf->size - buf->use); return(buf->size - buf->use - 1);
if (len > SIZE_MAX - buf->use) if (len >= SIZE_MAX - buf->use) {
xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
return(0); return(0);
}
if (buf->size > (size_t) len) { if (buf->size > (size_t) len) {
size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2; 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 * 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)) { (buf->size >= XML_MAX_TEXT_LENGTH)) {
xmlBufMemoryError(buf, "buffer error: text too long\n"); xmlBufMemoryError(buf, "buffer error: text too long\n");
return(0); return(0);
@ -479,7 +481,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
} }
buf->size = size; buf->size = size;
UPDATE_COMPAT(buf) 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 -1;
if (len == 0) return 0; 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 >= 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); return(-1);
}
needSize = buf->use + len + 1; needSize = buf->use + len + 1;
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
/* /*

22
tree.c
View File

@ -7371,8 +7371,10 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
if (len < buf->size - buf->use) if (len < buf->size - buf->use)
return(0); return(0);
if (len > UINT_MAX - buf->use) if (len >= UINT_MAX - buf->use) {
xmlTreeErrMemory("growing buffer past UINT_MAX");
return(-1); return(-1);
}
if (buf->size > (size_t) len) { if (buf->size > (size_t) len) {
size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2; 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->content = newbuf;
} }
buf->size = size; 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; return 1;
if (size > UINT_MAX - 10) { if (size > UINT_MAX - 10) {
xmlTreeErrMemory("growing buffer"); xmlTreeErrMemory("growing buffer past UINT_MAX");
return 0; return 0;
} }
@ -7625,9 +7627,12 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
if (len < 0) return -1; if (len < 0) return -1;
if (len == 0) return 0; 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 >= 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; return XML_ERR_NO_MEMORY;
}
needSize = buf->use + len + 1; needSize = buf->use + len + 1;
if (!xmlBufferResize(buf, needSize)){ if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer"); xmlTreeErrMemory("growing buffer");
@ -7696,8 +7701,13 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
return(0); return(0);
} }
} }
needSize = buf->use + len + 2; /* Note that both buf->size and buf->use can be zero here. */
if (needSize > buf->size){ 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)){ if (!xmlBufferResize(buf, needSize)){
xmlTreeErrMemory("growing buffer"); xmlTreeErrMemory("growing buffer");
return XML_ERR_NO_MEMORY; return XML_ERR_NO_MEMORY;