diff options
author | Nick Wellnhofer <wellnhofer@aevum.de> | 2019-05-15 12:47:28 +0200 |
---|---|---|
committer | Nick Wellnhofer <wellnhofer@aevum.de> | 2019-05-15 13:01:52 +0200 |
commit | 407b393d8023a6f20422fb3bf5806cf15ab750ad (patch) | |
tree | bfe20336e0109b376af3c9dd2ddc6cb3e5770b0c /xmlIO.c | |
parent | 3c0d62b4193c5c1fe15a143a138f76ffa1278779 (diff) | |
download | libxml2-407b393d8023a6f20422fb3bf5806cf15ab750ad.tar.gz |
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.
Diffstat (limited to 'xmlIO.c')
-rw-r--r-- | xmlIO.c | 32 |
1 files changed, 22 insertions, 10 deletions
@@ -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 */ |