summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2015-06-07 13:41:13 +0200
committerNick Wellnhofer <wellnhofer@aevum.de>2015-06-07 21:42:15 +0200
commitea23e2b42f05ac4a04154e572fc5ce8c84c29c10 (patch)
treeaf4e9e1bcfbfdecb9855ff36cd4f14a2b42c98dc
parent1a38daeb81db11ef2acd57690aad36b4ce3fe3da (diff)
Check for overflow in cmark_strbuf_grow
-rw-r--r--src/buffer.c14
1 files 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 */