diff options
author | Nick Wellnhofer <wellnhofer@aevum.de> | 2015-06-07 13:41:13 +0200 |
---|---|---|
committer | Nick Wellnhofer <wellnhofer@aevum.de> | 2015-06-07 21:42:15 +0200 |
commit | ea23e2b42f05ac4a04154e572fc5ce8c84c29c10 (patch) | |
tree | af4e9e1bcfbfdecb9855ff36cd4f14a2b42c98dc /src | |
parent | 1a38daeb81db11ef2acd57690aad36b4ce3fe3da (diff) |
Check for overflow in cmark_strbuf_grow
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer.c | 14 |
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 */ |