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