From ea23e2b42f05ac4a04154e572fc5ce8c84c29c10 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 7 Jun 2015 13:41:13 +0200
Subject: Check for overflow in cmark_strbuf_grow

---
 src/buffer.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index 8ec38b0..8fb2652 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -36,7 +36,6 @@ void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size)
 void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size)
 {
 	unsigned char *new_ptr;
-	bufsize_t new_size;
 
 	if (target_size <= buf->asize)
 		return;
@@ -49,13 +48,18 @@ void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size)
 
 	/* Oversize the buffer by 50% to guarantee amortized linear time
 	 * complexity on append operations. */
-	// TODO: Check for overflow.
-	new_size = target_size + target_size / 2;
+	size_t new_size = (size_t)target_size + (size_t)target_size / 2;
 
 	/* round allocation up to multiple of 8 */
-	// TODO: Check for overflow.
 	new_size = (new_size + 7) & ~7;
 
+	if (new_size < (size_t)target_size  /* Integer overflow. */
+	    || new_size > BUFSIZE_MAX       /* Truncation overflow. */
+	) {
+		/* Oversize by the maximum possible amount. */
+		new_size = BUFSIZE_MAX;
+	}
+
 	new_ptr = (unsigned char *)realloc(new_ptr, new_size);
 
 	if (!new_ptr) {
@@ -63,7 +67,7 @@ void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size)
 		abort();
 	}
 
-	buf->asize = new_size;
+	buf->asize = (bufsize_t)new_size;
 	buf->ptr   = new_ptr;
 
 	/* truncate the existing buffer size if necessary */
-- 
cgit v1.2.3