diff options
-rw-r--r-- | buffer.c | 8 | ||||
-rw-r--r-- | buffer.h | 136 |
2 files changed, 118 insertions, 26 deletions
@@ -42,6 +42,12 @@ array_mult_safe (const size_t m1, const size_t m2) return (size_t) res; } +void +buf_size_error (size_t size) +{ + msg (M_FATAL, "fatal buffer size error, size=%lu", (unsigned long)size); +} + struct buffer #ifdef DMALLOC alloc_buf_debug (size_t size, const char *file, int line) @@ -64,6 +70,8 @@ alloc_buf_gc (size_t size, struct gc_arena *gc) #endif { struct buffer buf; + if (!buf_size_valid (size)) + buf_size_error (size); buf.capacity = (int)size; buf.offset = 0; buf.len = 0; @@ -28,6 +28,8 @@ #include "basic.h" #include "thread.h" +#define BUF_SIZE_MAX 1000000 + /* * Define verify_align function, otherwise * it will be a noop. @@ -74,12 +76,12 @@ struct gc_arena struct gc_entry *list; }; -#define BPTR(buf) ((buf)->data + (buf)->offset) -#define BEND(buf) (BPTR(buf) + (buf)->len) -#define BLAST(buf) (((buf)->data && (buf)->len) ? (BPTR(buf) + (buf)->len - 1) : NULL) -#define BLEN(buf) ((buf)->len) -#define BDEF(buf) ((buf)->data != NULL) -#define BSTR(buf) ((char *)BPTR(buf)) +#define BPTR(buf) (buf_bptr(buf)) +#define BEND(buf) (buf_bend(buf)) +#define BLAST(buf) (buf_blast(buf)) +#define BLEN(buf) (buf_len(buf)) +#define BDEF(buf) (buf_defined(buf)) +#define BSTR(buf) (buf_str(buf)) #define BCAP(buf) (buf_forward_capacity (buf)) void buf_clear (struct buffer *buf); @@ -97,6 +99,8 @@ size_t array_mult_safe (const size_t m1, const size_t m2); #define PA_BRACKET (1<<0) char *print_argv (const char **p, struct gc_arena *gc, const unsigned int flags); +void buf_size_error (const size_t size); + /* for dmalloc debugging */ #ifdef DMALLOC @@ -136,6 +140,69 @@ bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line) /* inline functions */ +static inline bool +buf_defined (const struct buffer *buf) +{ + return buf->data != NULL; +} + +static inline bool +buf_valid (const struct buffer *buf) +{ + return likely (buf->data != NULL) && likely (buf->len >= 0); +} + +static inline uint8_t * +buf_bptr (const struct buffer *buf) +{ + if (buf_valid (buf)) + return buf->data + buf->offset; + else + return NULL; +} + +static int +buf_len (const struct buffer *buf) +{ + if (buf_valid (buf)) + return buf->len; + else + return 0; +} + +static inline uint8_t * +buf_bend (const struct buffer *buf) +{ + return buf_bptr (buf) + buf_len (buf); +} + +static inline uint8_t * +buf_blast (const struct buffer *buf) +{ + if (buf_len (buf) > 0) + return buf_bptr (buf) + buf_len (buf) - 1; + else + return NULL; +} + +static inline bool +buf_size_valid (const size_t size) +{ + return likely (size < BUF_SIZE_MAX); +} + +static inline bool +buf_size_valid_signed (const int size) +{ + return likely (size >= -BUF_SIZE_MAX) && likely (size < BUF_SIZE_MAX); +} + +static inline char * +buf_str (const struct buffer *buf) +{ + return (char *)buf_bptr(buf); +} + static inline void buf_reset (struct buffer *buf) { @@ -162,15 +229,11 @@ buf_init_dowork (struct buffer *buf, int offset) return true; } -static inline bool -buf_defined (struct buffer *buf) -{ - return buf->data != NULL; -} - static inline void buf_set_write (struct buffer *buf, uint8_t *data, int size) { + if (!buf_size_valid (size)) + buf_size_error (size); buf->len = 0; buf->offset = 0; buf->capacity = size; @@ -182,6 +245,8 @@ buf_set_write (struct buffer *buf, uint8_t *data, int size) static inline void buf_set_read (struct buffer *buf, const uint8_t *data, int size) { + if (!buf_size_valid (size)) + buf_size_error (size); buf->len = buf->capacity = size; buf->offset = 0; buf->data = (uint8_t *)data; @@ -322,38 +387,57 @@ struct buffer buf_sub (struct buffer *buf, int size, bool prepend); static inline bool buf_safe (const struct buffer *buf, int len) { - return len >= 0 && buf->offset + buf->len + len <= buf->capacity; + return buf_valid (buf) && buf_size_valid (len) + && buf->offset + buf->len + len <= buf->capacity; } static inline bool buf_safe_bidir (const struct buffer *buf, int len) { - const int newlen = buf->len + len; - return newlen >= 0 && buf->offset + newlen <= buf->capacity; + if (buf_valid (buf) && buf_size_valid_signed (len)) + { + const int newlen = buf->len + len; + return newlen >= 0 && buf->offset + newlen <= buf->capacity; + } + else + return false; } static inline int buf_forward_capacity (const struct buffer *buf) { - int ret = buf->capacity - (buf->offset + buf->len); - if (ret < 0) - ret = 0; - return ret; + if (buf_valid (buf)) + { + int ret = buf->capacity - (buf->offset + buf->len); + if (ret < 0) + ret = 0; + return ret; + } + else + return 0; } static inline int buf_forward_capacity_total (const struct buffer *buf) { - int ret = buf->capacity - buf->offset; - if (ret < 0) - ret = 0; - return ret; + if (buf_valid (buf)) + { + int ret = buf->capacity - buf->offset; + if (ret < 0) + ret = 0; + return ret; + } + else + return 0; } static inline int buf_reverse_capacity (const struct buffer *buf) { - return buf->offset; + if (buf_valid (buf)) + return buf->offset; + else + return 0; } static inline bool @@ -373,7 +457,7 @@ buf_inc_len (struct buffer *buf, int inc) static inline uint8_t * buf_prepend (struct buffer *buf, int size) { - if (size < 0 || size > buf->offset) + if (!buf_valid (buf) || size < 0 || size > buf->offset) return NULL; buf->offset -= size; buf->len += size; @@ -383,7 +467,7 @@ buf_prepend (struct buffer *buf, int size) static inline bool buf_advance (struct buffer *buf, int size) { - if (size < 0 || buf->len < size) + if (!buf_valid (buf) || size < 0 || buf->len < size) return false; buf->offset += size; buf->len -= size; |