From 03fb0d95c6c009fdb5d537a7306d0e20651c3a1b Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Tue, 14 Jan 2003 21:41:03 +0000 Subject: [PATCH] Rewrote MemBuffer to do some internal checks. committer: mfx 1042580463 +0000 --- src/mem.cpp | 101 +++++++++++++++++++++++++++++++--------------------- src/mem.h | 15 ++++---- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/mem.cpp b/src/mem.cpp index 764974bc..72b48f90 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -35,10 +35,10 @@ **************************************************************************/ MemBuffer::MemBuffer(unsigned size) : - ptr(NULL), alloc_ptr(NULL), alloc_size(0) + ptr(NULL), psize(0) { if (size > 0) - alloc(size, 0); + alloc(size); } @@ -49,44 +49,13 @@ MemBuffer::~MemBuffer() void MemBuffer::dealloc() { - if (alloc_ptr) - ::free(alloc_ptr); - alloc_ptr = ptr = NULL; - alloc_size = 0; -} - - -unsigned MemBuffer::getSize() const -{ - if (!alloc_ptr) - return 0; - unsigned size = alloc_size - (ptr - alloc_ptr); - assert((int)size > 0); - return size; -} - - -void MemBuffer::alloc(unsigned size, unsigned base_offset) -{ - // NOTE: we don't automaticlly free a used buffer - assert(alloc_ptr == NULL); - assert((int)size > 0); - size = base_offset + size; - alloc_ptr = (unsigned char *) malloc(size); - if (!alloc_ptr) + if (ptr) { - //throw bad_alloc(); - throwCantPack("out of memory"); - //exit(1); + checkState(); + ::free(ptr - 8); } - alloc_size = size; - ptr = alloc_ptr + base_offset; -} - - -void MemBuffer::alloc(unsigned size) -{ - alloc(size, 0); + ptr = NULL; + psize = 0; } @@ -94,7 +63,7 @@ void MemBuffer::allocForCompression(unsigned uncompressed_size, unsigned extra) { assert((int)uncompressed_size > 0); assert((int)extra >= 0); - alloc(uncompressed_size + uncompressed_size/8 + 256 + extra, 0); + alloc(uncompressed_size + uncompressed_size/8 + 256 + extra); } @@ -102,8 +71,58 @@ void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra { assert((int)uncompressed_size > 0); assert((int)extra >= 0); - //alloc(uncompressed_size + 3 + 512 + extra, 0); // 512 safety bytes - alloc(uncompressed_size + 3 + extra, 0); // 3 bytes for asm_fast decompresion + // note: 3 bytes are allowed overrun for the asm_fast decompressors +// alloc(uncompressed_size + 3 + 512 + extra); // 512 safety bytes + alloc(uncompressed_size + 3 + extra); +} + + +/************************************************************************* +// +**************************************************************************/ + +#define MAGIC1(p) ((unsigned)(p) ^ 0xfefdbeeb) +#define MAGIC2(p) ((unsigned)(p) ^ 0xfefdbeeb ^ 0x80024001) + +unsigned MemBuffer::global_alloc_counter = 0; + + +void MemBuffer::checkState() const +{ + if (!ptr) + throwInternalError("block not allocated"); + if (get_be32(ptr - 4) != MAGIC1(ptr)) + throwInternalError("memory clobbered before allocated block 1"); + if (get_be32(ptr - 8) != psize) + throwInternalError("memory clobbered before allocated block 2"); + if (get_be32(ptr + psize) != MAGIC2(ptr)) + throwInternalError("memory clobbered past end of allocated block"); +} + + +void MemBuffer::alloc(unsigned size) +{ + // NOTE: we don't automaticlly free a used buffer + assert(ptr == NULL); + assert(psize == 0); + // + assert((int)size > 0); + unsigned total = 4 + 4 + size + 4 + 4; + assert((int)total > 0); + unsigned char *p = (unsigned char *) malloc(total); + if (!p) + { + //throw bad_alloc(); + throwCantPack("out of memory"); + //exit(1); + } + ptr = p + 8; + psize = size; + // store magic state + set_be32(ptr - 8, psize); + set_be32(ptr - 4, MAGIC1(ptr)); + set_be32(ptr + psize, MAGIC2(ptr)); + set_be32(ptr + psize + 4, global_alloc_counter++); } diff --git a/src/mem.h b/src/mem.h index dd6d1b87..c6e8d2d0 100644 --- a/src/mem.h +++ b/src/mem.h @@ -46,24 +46,21 @@ public: void dealloc(); - const unsigned char *getBuf() const { return ptr; } - unsigned getSize() const; + void checkState() const; + + unsigned getSize() const { return psize; } operator unsigned char * () { return ptr; } //operator const unsigned char * () const { return ptr; } - + const unsigned char *getBuf() const { return ptr; } void *getVoidPtr() { return (void *) ptr; } const void *getVoidPtr() const { return (const void *) ptr; } private: - void alloc(unsigned size, unsigned base_offset); - -protected: unsigned char *ptr; - unsigned char *alloc_ptr; - unsigned alloc_size; + unsigned psize; + static unsigned global_alloc_counter; -private: // disable copy and assignment MemBuffer(MemBuffer const &); // {} MemBuffer& operator= (MemBuffer const &); // { return *this; }