diff options
-rw-r--r-- | src/buffer.c | 56 | ||||
-rw-r--r-- | src/buffer.h | 26 |
2 files changed, 51 insertions, 31 deletions
diff --git a/src/buffer.c b/src/buffer.c index e2ebc02..78d0a00 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -22,20 +22,21 @@ unsigned char cmark_strbuf__initbuf[1]; #define MIN(x,y) ((x<y) ? x : y) #endif -void cmark_strbuf_init(cmark_strbuf *buf, int initial_size) +void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size) { buf->asize = 0; buf->size = 0; buf->ptr = cmark_strbuf__initbuf; + // TODO: Check for negative initial_size. if (initial_size) cmark_strbuf_grow(buf, initial_size); } -void cmark_strbuf_grow(cmark_strbuf *buf, int target_size) +void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) { unsigned char *new_ptr; - int new_size; + bufsize_t new_size; if (target_size <= buf->asize) return; @@ -51,9 +52,11 @@ void cmark_strbuf_grow(cmark_strbuf *buf, int target_size) /* grow the buffer size by 1.5, until it's big enough * to fit our target size */ while (new_size < target_size) + // TODO: Check for overflow. new_size = (new_size << 1) - (new_size >> 1); /* round allocation up to multiple of 8 */ + // TODO: Check for overflow. new_size = (new_size + 7) & ~7; new_ptr = (unsigned char *)realloc(new_ptr, new_size); @@ -95,12 +98,13 @@ void cmark_strbuf_clear(cmark_strbuf *buf) buf->ptr[0] = '\0'; } -void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, int len) +void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, bufsize_t len) { if (len <= 0 || data == NULL) { cmark_strbuf_clear(buf); } else { if (data != buf->ptr) { + // TODO: Check for overflow. ENSURE_SIZE(buf, len + 1); memmove(buf->ptr, data, len); } @@ -117,16 +121,18 @@ void cmark_strbuf_sets(cmark_strbuf *buf, const char *string) void cmark_strbuf_putc(cmark_strbuf *buf, int c) { + // TODO: Check for overflow. ENSURE_SIZE(buf, buf->size + 2); buf->ptr[buf->size++] = c; buf->ptr[buf->size] = '\0'; } -void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, int len) +void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, bufsize_t len) { if (len <= 0) return; + // TODO: Check for overflow. ENSURE_SIZE(buf, buf->size + len + 1); memmove(buf->ptr + buf->size, data, len); buf->size += len; @@ -140,8 +146,8 @@ void cmark_strbuf_puts(cmark_strbuf *buf, const char *string) void cmark_strbuf_vprintf(cmark_strbuf *buf, const char *format, va_list ap) { - const int expected_size = buf->size + (strlen(format) * 2); - int len; + // TODO: Check for overflow. + const bufsize_t expected_size = buf->size + (strlen(format) * 2); ENSURE_SIZE(buf, expected_size); @@ -149,7 +155,7 @@ void cmark_strbuf_vprintf(cmark_strbuf *buf, const char *format, va_list ap) va_list args; va_copy(args, ap); - len = vsnprintf( + int len = vsnprintf( (char *)buf->ptr + buf->size, buf->asize - buf->size, format, args @@ -168,11 +174,13 @@ void cmark_strbuf_vprintf(cmark_strbuf *buf, const char *format, va_list ap) abort(); } + // TODO: Check for overflow. if (len + 1 <= buf->asize - buf->size) { buf->size += len; break; } + // TODO: Check for overflow. ENSURE_SIZE(buf, buf->size + len + 1); } } @@ -186,10 +194,11 @@ void cmark_strbuf_printf(cmark_strbuf *buf, const char *format, ...) va_end(ap); } -void cmark_strbuf_copy_cstr(char *data, int datasize, const cmark_strbuf *buf) +void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, const cmark_strbuf *buf) { - int copylen; + bufsize_t copylen; + // TODO: Check negative datasize. assert(data && datasize && buf); data[0] = '\0'; @@ -224,16 +233,19 @@ unsigned char *cmark_strbuf_detach(cmark_strbuf *buf) return data; } -void cmark_strbuf_attach(cmark_strbuf *buf, unsigned char *ptr, int asize) +void cmark_strbuf_attach(cmark_strbuf *buf, unsigned char *ptr, bufsize_t asize) { cmark_strbuf_free(buf); if (ptr) { buf->ptr = ptr; buf->size = strlen((char *)ptr); + // TODO: Check for negative asize. if (asize) + // TODO: Check for overflow. buf->asize = (asize < buf->size) ? buf->size + 1 : asize; else /* pass 0 to fall back on strlen + 1 */ + // TODO: Check for overflow. buf->asize = buf->size + 1; } else { cmark_strbuf_grow(buf, asize); @@ -247,19 +259,21 @@ int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b) (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0; } -int cmark_strbuf_strchr(const cmark_strbuf *buf, int c, int pos) +bufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos) { + // TODO: Bounds check. const unsigned char *p = (unsigned char *)memchr(buf->ptr + pos, c, buf->size - pos); if (!p) return -1; - return (int)(p - (const unsigned char *)buf->ptr); + return (bufsize_t)(p - (const unsigned char *)buf->ptr); } -int cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, int pos) +bufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos) { - int i; + bufsize_t i; + // TODO: Bounds check. for (i = pos; i >= 0; i--) { if (buf->ptr[i] == (unsigned char) c) return i; @@ -268,17 +282,19 @@ int cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, int pos) return -1; } -void cmark_strbuf_truncate(cmark_strbuf *buf, int len) +void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len) { + // TODO: Check for negative len. if (len < buf->size) { buf->size = len; buf->ptr[buf->size] = '\0'; } } -void cmark_strbuf_drop(cmark_strbuf *buf, int n) +void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n) { if (n > 0) { + // TODO: Bounds check. buf->size = buf->size - n; if (buf->size) memmove(buf->ptr, buf->ptr + n, buf->size); @@ -304,7 +320,7 @@ void cmark_strbuf_rtrim(cmark_strbuf *buf) void cmark_strbuf_trim(cmark_strbuf *buf) { - int i = 0; + bufsize_t i = 0; if (!buf->size) return; @@ -322,7 +338,7 @@ void cmark_strbuf_trim(cmark_strbuf *buf) void cmark_strbuf_normalize_whitespace(cmark_strbuf *s) { bool last_char_was_space = false; - int r, w; + bufsize_t r, w; for (r = 0, w = 0; r < s->size; ++r) { switch (s->ptr[r]) { @@ -347,7 +363,7 @@ void cmark_strbuf_normalize_whitespace(cmark_strbuf *s) // Destructively unescape a string: remove backslashes before punctuation chars. extern void cmark_strbuf_unescape(cmark_strbuf *buf) { - int r, w; + bufsize_t r, w; for (r = 0, w = 0; r < buf->size; ++r) { if (buf->ptr[r] == '\\' && cmark_ispunct(buf->ptr[r + 1])) diff --git a/src/buffer.h b/src/buffer.h index 417df26..99e6feb 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -3,20 +3,24 @@ #include <stddef.h> #include <stdarg.h> +#include <limits.h> #include "config.h" #ifdef __cplusplus extern "C" { #endif +typedef int bufsize_t; + typedef struct { unsigned char *ptr; - int asize, size; + bufsize_t asize, size; } cmark_strbuf; extern unsigned char cmark_strbuf__initbuf[]; #define GH_BUF_INIT { cmark_strbuf__initbuf, 0, 0 } +#define BUFSIZE_MAX INT_MAX /** * Initialize a cmark_strbuf structure. @@ -24,12 +28,12 @@ extern unsigned char cmark_strbuf__initbuf[]; * For the cases where GH_BUF_INIT cannot be used to do static * initialization. */ -void cmark_strbuf_init(cmark_strbuf *buf, int initial_size); +void cmark_strbuf_init(cmark_strbuf *buf, bufsize_t initial_size); /** * Grow the buffer to hold at least `target_size` bytes. */ -void cmark_strbuf_grow(cmark_strbuf *buf, int target_size); +void cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size); void cmark_strbuf_free(cmark_strbuf *buf); void cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b); @@ -38,9 +42,9 @@ size_t cmark_strbuf_len(const cmark_strbuf *buf); int cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b); -void cmark_strbuf_attach(cmark_strbuf *buf, unsigned char *ptr, int asize); +void cmark_strbuf_attach(cmark_strbuf *buf, unsigned char *ptr, bufsize_t asize); unsigned char *cmark_strbuf_detach(cmark_strbuf *buf); -void cmark_strbuf_copy_cstr(char *data, int datasize, const cmark_strbuf *buf); +void cmark_strbuf_copy_cstr(char *data, bufsize_t datasize, const cmark_strbuf *buf); static inline const char *cmark_strbuf_cstr(const cmark_strbuf *buf) { @@ -49,20 +53,20 @@ static inline const char *cmark_strbuf_cstr(const cmark_strbuf *buf) #define cmark_strbuf_at(buf, n) ((buf)->ptr[n]) -void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, int len); +void cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data, bufsize_t len); void cmark_strbuf_sets(cmark_strbuf *buf, const char *string); void cmark_strbuf_putc(cmark_strbuf *buf, int c); -void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, int len); +void cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data, bufsize_t len); void cmark_strbuf_puts(cmark_strbuf *buf, const char *string); void cmark_strbuf_printf(cmark_strbuf *buf, const char *format, ...) CMARK_ATTRIBUTE((format (printf, 2, 3))); void cmark_strbuf_vprintf(cmark_strbuf *buf, const char *format, va_list ap); void cmark_strbuf_clear(cmark_strbuf *buf); -int cmark_strbuf_strchr(const cmark_strbuf *buf, int c, int pos); -int cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, int pos); -void cmark_strbuf_drop(cmark_strbuf *buf, int n); -void cmark_strbuf_truncate(cmark_strbuf *buf, int len); +bufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos); +bufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos); +void cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n); +void cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len); void cmark_strbuf_rtrim(cmark_strbuf *buf); void cmark_strbuf_trim(cmark_strbuf *buf); void cmark_strbuf_normalize_whitespace(cmark_strbuf *s); |