1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-26 10:03:34 +03:00

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.
This commit is contained in:
Nick Wellnhofer 2019-05-15 12:47:28 +02:00
parent 3c0d62b419
commit 407b393d80

32
xmlIO.c
View File

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