summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ogg/os_types.h13
-rw-r--r--src/bitwise.c6
2 files changed, 16 insertions, 3 deletions
diff --git a/include/ogg/os_types.h b/include/ogg/os_types.h
index 4d4315d..cefd04f 100644
--- a/include/ogg/os_types.h
+++ b/include/ogg/os_types.h
@@ -24,6 +24,19 @@
#define _ogg_realloc realloc
#define _ogg_free free
+/* get non-brittle portable type-based MIN/MAX. Assumes 2's-complement
+ math */
+#define TYPE_HALF_MAX_SIGNED(type) \
+ ((typeof(type))1 << (sizeof(type)*8-2))
+#define TYPE_MAX_SIGNED(type) \
+ (TYPE_HALF_MAX_SIGNED(type) - 1 + TYPE_HALF_MAX_SIGNED(type))
+#define TYPE_MIN_SIGNED(type) \
+ (-1 - TYPE_MAX_SIGNED(type))
+#define TYPE_MIN(type) \
+ ((typeof(type))-1 < 1?TYPE_MIN_SIGNED(type):(typeof(type))0)
+#define TYPE_MAX(type) \
+ ((typeof(type))~TYPE_MIN(type))
+
#if defined(_WIN32)
# if defined(__CYGWIN__)
diff --git a/src/bitwise.c b/src/bitwise.c
index 48b7192..7a57f55 100644
--- a/src/bitwise.c
+++ b/src/bitwise.c
@@ -84,7 +84,7 @@ void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){
if(b->endbyte>=b->storage-4){
void *ret;
if(!b->ptr)return;
- if(b->storage+BUFFER_INCREMENT<b->storage) goto err;
+ if(b->storage>TYPE_MAX(b->storage)-BUFFER_INCREMENT) goto err;
ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
if(!ret) goto err;
b->buffer=ret;
@@ -127,7 +127,7 @@ void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){
if(b->endbyte>=b->storage-4){
void *ret;
if(!b->ptr)return;
- if(b->storage+BUFFER_INCREMENT<b->storage) goto err;
+ if(b->storage>TYPE_MAX(b->storage)-BUFFER_INCREMENT) goto err;
ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT);
if(!ret) goto err;
b->buffer=ret;
@@ -198,7 +198,7 @@ static void oggpack_writecopy_helper(oggpack_buffer *b,
if(b->endbyte+bytes+1>=b->storage){
void *ret;
if(!b->ptr) goto err;
- if(b->storage=b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err;
+ if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err;
b->storage=b->endbyte+bytes+BUFFER_INCREMENT;
ret=_ogg_realloc(b->buffer,b->storage);
if(!ret) goto err;