summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buffer.c56
-rw-r--r--src/buffer.h26
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);