You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/08/19 16:25:18 UTC

(axis-axis2-c-core) 01/09: Size the grow buffer from capacity, and reject a failed initial read

This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git

commit 078c49d3e983e52fe59da862da12a8684d5c767b
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Wed Aug 19 06:13:08 2026 -1000

    Size the grow buffer from capacity, and reject a failed initial read
    
    The grow path in guththila_next_no_char allocated from data_size, how much
    of the buffer currently holds data, while recording the new capacity as
    buffs_size * 2; the sibling path in guththila_next_char uses buffs_size for
    both. Separately, a reader_read that returns -1 was stored straight into a
    size_t data_size. Allocate from capacity, and return -1 rather than record a
    failed read as a length.
    
    Co-Authored-By: Claude Opus 5 (1M context) <no...@anthropic.com>
---
 guththila/src/guththila_xml_parser.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/guththila/src/guththila_xml_parser.c b/guththila/src/guththila_xml_parser.c
index ead977790..3e55efd42 100644
--- a/guththila/src/guththila_xml_parser.c
+++ b/guththila/src/guththila_xml_parser.c
@@ -1800,7 +1800,15 @@ guththila_next_char(
             m->buffer.cur_buff = 0;
             temp = guththila_reader_read(m->reader, m->buffer.buff[0], 0,
                 GUTHTHILA_BUFFER_DEF_SIZE, env);
-            m->buffer.data_size[0] = temp;
+            /* data_size is size_t, so recording a -1 error return here makes
+             * the buffer appear to hold SIZE_MAX bytes and every later read
+             * trusts that. Nothing was read on 0 either, so there is no byte
+             * to hand back. */
+            if(temp <= 0)
+            {
+                return -1;
+            }
+            m->buffer.data_size[0] = (size_t)temp;
             c = m->buffer.buff[0][m->next++];
             return c;
         }
@@ -1873,8 +1881,15 @@ guththila_next_no_char(
                 m->buffer.data_size = temp3;
                 m->buffer.no_buffers *= 2;
             }
+            /* Size this from buffs_size, the buffer's capacity, not data_size,
+             * which is only how much of it currently holds data. The line below
+             * records the new capacity as buffs_size * 2, so allocating from a
+             * data_size that is smaller -- which it is whenever a read left the
+             * buffer partly filled -- produces a block smaller than the
+             * capacity the next reader_read is allowed to fill. The sibling
+             * grow path in guththila_next_char uses buffs_size for both. */
             m->buffer.buff[m->buffer.cur_buff + 1] = (guththila_char_t *)AXIS2_MALLOC(
-                env->allocator, sizeof(guththila_char_t) * m->buffer.data_size[m->buffer.cur_buff]
+                env->allocator, sizeof(guththila_char_t) * m->buffer.buffs_size[m->buffer.cur_buff]
                     * 2);
             if(!m->buffer.buff[m->buffer.cur_buff + 1])
                 return -1;