From 407b393d8023a6f20422fb3bf5806cf15ab750ad Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 15 May 2019 12:47:28 +0200
Subject: [PATCH 32/37] Fix return value of xmlOutputBufferWrite

When using memory buffers, the total size of the buffer was added
again and again, potentially leading to an integer overflow.

Found by OSS-Fuzz.
---
 xmlIO.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/xmlIO.c b/xmlIO.c
index f61dd05..a0b4532 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -3372,20 +3372,26 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
 		out->error = XML_IO_ENCODER;
 		return(-1);
 	    }
-	    nbchars = xmlBufUse(out->conv);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->conv);
+            else
+                nbchars = ret;
 	} else {
 	    ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
 	    if (ret != 0)
 	        return(-1);
-	    nbchars = xmlBufUse(out->buffer);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->buffer);
+            else
+                nbchars = chunk;
 	}
 	buf += chunk;
 	len -= chunk;
 
-	if ((nbchars < MINLEN) && (len <= 0))
-	    goto done;
-
 	if (out->writecallback) {
+            if ((nbchars < MINLEN) && (len <= 0))
+                goto done;
+
 	    /*
 	     * second write the stuff to the I/O channel
 	     */
@@ -3561,21 +3567,27 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
 		out->error = XML_IO_ENCODER;
 		return(-1);
 	    }
-	    nbchars = xmlBufUse(out->conv);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->conv);
+            else
+                nbchars = ret;
 	} else {
 	    ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
 	    if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
 	        return(-1);
             xmlBufAddLen(out->buffer, chunk);
-	    nbchars = xmlBufUse(out->buffer);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->buffer);
+            else
+                nbchars = chunk;
 	}
 	str += cons;
 	len -= cons;
 
-	if ((nbchars < MINLEN) && (len <= 0))
-	    goto done;
-
 	if (out->writecallback) {
+            if ((nbchars < MINLEN) && (len <= 0))
+                goto done;
+
 	    /*
 	     * second write the stuff to the I/O channel
 	     */
-- 
1.8.3.1

