The current code will go into an infinite loop if the printf generated string is >= 1000, AND exactly 1 character smaller than the amount of free space in the buffer. When this happens, we are dropped into the loop body, but nothing will actually change, because count == (buf->size - buf->use - 1), and virBufferGrow returns unchanged if count < (buf->size - buf->use) Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle the NULL byte for us anyways, so we shouldn't need to manually accomodate for it. Here's a bug where we are actually hitting this issue: https://bugzilla.redhat.com/show_bug.cgi?id=602772 Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx> --- src/util/buf.c | 14 ++++++-------- 1 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/util/buf.c b/src/util/buf.c index fc1217b..734b8f6 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -236,11 +236,11 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) virBufferGrow(buf, 100) < 0) return; - size = buf->size - buf->use - 1; + size = buf->size - buf->use; va_start(argptr, format); va_copy(locarg, argptr); while (((count = vsnprintf(&buf->content[buf->use], size, format, - locarg)) < 0) || (count >= size - 1)) { + locarg)) < 0) || (count >= size)) { buf->content[buf->use] = 0; va_end(locarg); @@ -250,13 +250,12 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) return; } - size = buf->size - buf->use - 1; + size = buf->size - buf->use; va_copy(locarg, argptr); } va_end(argptr); va_end(locarg); buf->use += count; - buf->content[buf->use] = '\0'; } /** @@ -340,19 +339,18 @@ virBufferEscapeString(const virBufferPtr buf, const char *format, const char *st return; } - size = buf->size - buf->use - 1; + size = buf->size - buf->use; while (((count = snprintf(&buf->content[buf->use], size, format, - (char *)escaped)) < 0) || (count >= size - 1)) { + (char *)escaped)) < 0) || (count >= size)) { buf->content[buf->use] = 0; grow_size = (count > 1000) ? count : 1000; if (virBufferGrow(buf, grow_size) < 0) { VIR_FREE(escaped); return; } - size = buf->size - buf->use - 1; + size = buf->size - buf->use; } buf->use += count; - buf->content[buf->use] = '\0'; VIR_FREE(escaped); } -- 1.7.2.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list