153aa9179Sopenharmony_ciFrom 6ef16dee7ac8af32b8a0dd793445b1148e240364 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: David Kilzer <ddkilzer@apple.com>
353aa9179Sopenharmony_ciDate: Fri, 13 May 2022 14:43:33 -0700
453aa9179Sopenharmony_ciSubject: [PATCH 300/300] Reserve byte for NUL terminator and report errors
553aa9179Sopenharmony_ci consistently in xmlBuf and xmlBuffer
653aa9179Sopenharmony_ci
753aa9179Sopenharmony_ciThis is a follow-up to commit 6c283d83.
853aa9179Sopenharmony_ci
953aa9179Sopenharmony_ci* buf.c:
1053aa9179Sopenharmony_ci(xmlBufGrowInternal):
1153aa9179Sopenharmony_ci- Call xmlBufMemoryError() when the buffer size would overflow.
1253aa9179Sopenharmony_ci- Account for NUL terminator byte when using XML_MAX_TEXT_LENGTH.
1353aa9179Sopenharmony_ci- Do not include NUL terminator byte when returning length.
1453aa9179Sopenharmony_ci(xmlBufAdd):
1553aa9179Sopenharmony_ci- Call xmlBufMemoryError() when the buffer size would overflow.
1653aa9179Sopenharmony_ci
1753aa9179Sopenharmony_ci* tree.c:
1853aa9179Sopenharmony_ci(xmlBufferGrow):
1953aa9179Sopenharmony_ci- Call xmlTreeErrMemory() when the buffer size would overflow.
2053aa9179Sopenharmony_ci- Do not include NUL terminator byte when returning length.
2153aa9179Sopenharmony_ci(xmlBufferResize):
2253aa9179Sopenharmony_ci- Update error message in xmlTreeErrMemory() to be consistent
2353aa9179Sopenharmony_ci  with other similar messages.
2453aa9179Sopenharmony_ci(xmlBufferAdd):
2553aa9179Sopenharmony_ci- Call xmlTreeErrMemory() when the buffer size would overflow.
2653aa9179Sopenharmony_ci(xmlBufferAddHead):
2753aa9179Sopenharmony_ci- Add overflow checks similar to those in xmlBufferAdd().
2853aa9179Sopenharmony_ci
2953aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/6ef16dee7ac8af32b8a0dd793445b1148e240364
3053aa9179Sopenharmony_ciConflict:NA
3153aa9179Sopenharmony_ci
3253aa9179Sopenharmony_ci---
3353aa9179Sopenharmony_ci buf.c  | 15 ++++++++++-----
3453aa9179Sopenharmony_ci tree.c | 22 ++++++++++++++++------
3553aa9179Sopenharmony_ci 2 files changed, 26 insertions(+), 11 deletions(-)
3653aa9179Sopenharmony_ci
3753aa9179Sopenharmony_cidiff --git a/buf.c b/buf.c
3853aa9179Sopenharmony_ciindex da765f6..e851364 100644
3953aa9179Sopenharmony_ci--- a/buf.c
4053aa9179Sopenharmony_ci+++ b/buf.c
4153aa9179Sopenharmony_ci@@ -440,9 +440,11 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
4253aa9179Sopenharmony_ci 
4353aa9179Sopenharmony_ci     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
4453aa9179Sopenharmony_ci     if (len < buf->size - buf->use)
4553aa9179Sopenharmony_ci-        return(buf->size - buf->use);
4653aa9179Sopenharmony_ci-    if (len > SIZE_MAX - buf->use)
4753aa9179Sopenharmony_ci+        return(buf->size - buf->use - 1);
4853aa9179Sopenharmony_ci+    if (len >= SIZE_MAX - buf->use) {
4953aa9179Sopenharmony_ci+        xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
5053aa9179Sopenharmony_ci         return(0);
5153aa9179Sopenharmony_ci+    }
5253aa9179Sopenharmony_ci 
5353aa9179Sopenharmony_ci     if (buf->size > (size_t) len) {
5453aa9179Sopenharmony_ci         size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2;
5553aa9179Sopenharmony_ci@@ -455,7 +457,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
5653aa9179Sopenharmony_ci         /*
5753aa9179Sopenharmony_ci 	 * Used to provide parsing limits
5853aa9179Sopenharmony_ci 	 */
5953aa9179Sopenharmony_ci-        if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
6053aa9179Sopenharmony_ci+        if ((buf->use + len + 1 >= XML_MAX_TEXT_LENGTH) ||
6153aa9179Sopenharmony_ci 	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
6253aa9179Sopenharmony_ci 	    xmlBufMemoryError(buf, "buffer error: text too long\n");
6353aa9179Sopenharmony_ci 	    return(0);
6453aa9179Sopenharmony_ci@@ -483,7 +485,7 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
6553aa9179Sopenharmony_ci     }
6653aa9179Sopenharmony_ci     buf->size = size;
6753aa9179Sopenharmony_ci     UPDATE_COMPAT(buf)
6853aa9179Sopenharmony_ci-    return(buf->size - buf->use);
6953aa9179Sopenharmony_ci+    return(buf->size - buf->use - 1);
7053aa9179Sopenharmony_ci }
7153aa9179Sopenharmony_ci 
7253aa9179Sopenharmony_ci /**
7353aa9179Sopenharmony_ci@@ -883,9 +885,12 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
7453aa9179Sopenharmony_ci     if (len < 0) return -1;
7553aa9179Sopenharmony_ci     if (len == 0) return 0;
7653aa9179Sopenharmony_ci 
7753aa9179Sopenharmony_ci+    /* Note that both buf->size and buf->use can be zero here. */
7853aa9179Sopenharmony_ci     if ((size_t) len >= buf->size - buf->use) {
7953aa9179Sopenharmony_ci-        if ((size_t) len >= SIZE_MAX - buf->use)
8053aa9179Sopenharmony_ci+        if ((size_t) len >= SIZE_MAX - buf->use) {
8153aa9179Sopenharmony_ci+            xmlBufMemoryError(buf, "growing buffer past SIZE_MAX");
8253aa9179Sopenharmony_ci             return(-1);
8353aa9179Sopenharmony_ci+        }
8453aa9179Sopenharmony_ci         needSize = buf->use + len + 1;
8553aa9179Sopenharmony_ci 	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
8653aa9179Sopenharmony_ci 	    /*
8753aa9179Sopenharmony_cidiff --git a/tree.c b/tree.c
8853aa9179Sopenharmony_ciindex e275671..ed0a838 100644
8953aa9179Sopenharmony_ci--- a/tree.c
9053aa9179Sopenharmony_ci+++ b/tree.c
9153aa9179Sopenharmony_ci@@ -7338,8 +7338,10 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
9253aa9179Sopenharmony_ci     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
9353aa9179Sopenharmony_ci     if (len < buf->size - buf->use)
9453aa9179Sopenharmony_ci         return(0);
9553aa9179Sopenharmony_ci-    if (len > UINT_MAX - buf->use)
9653aa9179Sopenharmony_ci+    if (len >= UINT_MAX - buf->use) {
9753aa9179Sopenharmony_ci+        xmlTreeErrMemory("growing buffer past UINT_MAX");
9853aa9179Sopenharmony_ci         return(-1);
9953aa9179Sopenharmony_ci+    }
10053aa9179Sopenharmony_ci 
10153aa9179Sopenharmony_ci     if (buf->size > (size_t) len) {
10253aa9179Sopenharmony_ci         size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2;
10353aa9179Sopenharmony_ci@@ -7367,7 +7369,7 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
10453aa9179Sopenharmony_ci 	buf->content = newbuf;
10553aa9179Sopenharmony_ci     }
10653aa9179Sopenharmony_ci     buf->size = size;
10753aa9179Sopenharmony_ci-    return(buf->size - buf->use);
10853aa9179Sopenharmony_ci+    return(buf->size - buf->use - 1);
10953aa9179Sopenharmony_ci }
11053aa9179Sopenharmony_ci 
11153aa9179Sopenharmony_ci /**
11253aa9179Sopenharmony_ci@@ -7464,7 +7466,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
11353aa9179Sopenharmony_ci         return 1;
11453aa9179Sopenharmony_ci 
11553aa9179Sopenharmony_ci     if (size > UINT_MAX - 10) {
11653aa9179Sopenharmony_ci-        xmlTreeErrMemory("growing buffer");
11753aa9179Sopenharmony_ci+        xmlTreeErrMemory("growing buffer past UINT_MAX");
11853aa9179Sopenharmony_ci         return 0;
11953aa9179Sopenharmony_ci     }
12053aa9179Sopenharmony_ci 
12153aa9179Sopenharmony_ci@@ -7592,9 +7594,12 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
12253aa9179Sopenharmony_ci     if (len < 0) return -1;
12353aa9179Sopenharmony_ci     if (len == 0) return 0;
12453aa9179Sopenharmony_ci 
12553aa9179Sopenharmony_ci+    /* Note that both buf->size and buf->use can be zero here. */
12653aa9179Sopenharmony_ci     if ((unsigned) len >= buf->size - buf->use) {
12753aa9179Sopenharmony_ci-        if ((unsigned) len >= UINT_MAX - buf->use)
12853aa9179Sopenharmony_ci+        if ((unsigned) len >= UINT_MAX - buf->use) {
12953aa9179Sopenharmony_ci+            xmlTreeErrMemory("growing buffer past UINT_MAX");
13053aa9179Sopenharmony_ci             return XML_ERR_NO_MEMORY;
13153aa9179Sopenharmony_ci+        }
13253aa9179Sopenharmony_ci         needSize = buf->use + len + 1;
13353aa9179Sopenharmony_ci         if (!xmlBufferResize(buf, needSize)){
13453aa9179Sopenharmony_ci 	    xmlTreeErrMemory("growing buffer");
13553aa9179Sopenharmony_ci@@ -7663,8 +7668,13 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
13653aa9179Sopenharmony_ci 	    return(0);
13753aa9179Sopenharmony_ci 	}
13853aa9179Sopenharmony_ci     }
13953aa9179Sopenharmony_ci-    needSize = buf->use + len + 2;
14053aa9179Sopenharmony_ci-    if (needSize > buf->size){
14153aa9179Sopenharmony_ci+    /* Note that both buf->size and buf->use can be zero here. */
14253aa9179Sopenharmony_ci+    if ((unsigned) len >= buf->size - buf->use) {
14353aa9179Sopenharmony_ci+        if ((unsigned) len >= UINT_MAX - buf->use) {
14453aa9179Sopenharmony_ci+            xmlTreeErrMemory("growing buffer past UINT_MAX");
14553aa9179Sopenharmony_ci+            return(-1);
14653aa9179Sopenharmony_ci+        }
14753aa9179Sopenharmony_ci+        needSize = buf->use + len + 1;
14853aa9179Sopenharmony_ci         if (!xmlBufferResize(buf, needSize)){
14953aa9179Sopenharmony_ci 	    xmlTreeErrMemory("growing buffer");
15053aa9179Sopenharmony_ci             return XML_ERR_NO_MEMORY;
15153aa9179Sopenharmony_ci-- 
15253aa9179Sopenharmony_ci2.27.0
15353aa9179Sopenharmony_ci
154