From d6cc5494a9dd25fe640c1602cdf1b566690c9ba7 Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Sat, 1 Nov 2014 19:41:47 +0900 Subject: [PATCH] Fixed memory size caluclation problem. See https://github.com/msgpack/msgpack-c/issues/149 --- erb/cpp03_zone.hpp.erb | 7 ++++++- include/msgpack/detail/cpp03_zone.hpp | 7 ++++++- include/msgpack/detail/cpp11_zone.hpp | 7 ++++++- include/msgpack/sbuffer.h | 10 ++++++++-- include/msgpack/sbuffer.hpp | 9 ++++++++- include/msgpack/unpack.hpp | 7 ++++++- include/msgpack/vrefbuffer.hpp | 7 ++++++- src/unpack.c | 14 ++++++++++++-- src/vrefbuffer.c | 7 ++++++- src/zone.c | 8 ++++++-- 10 files changed, 70 insertions(+), 13 deletions(-) diff --git a/erb/cpp03_zone.hpp.erb b/erb/cpp03_zone.hpp.erb index 9b16bb65..e5226fe4 100644 --- a/erb/cpp03_zone.hpp.erb +++ b/erb/cpp03_zone.hpp.erb @@ -226,7 +226,12 @@ inline void* zone::allocate_expand(size_t size) size_t sz = m_chunk_size; while(sz < size) { - sz *= 2; + size_t tmp_sz = sz * 2; + if (tmp_sz <= sz) { + sz = size; + break; + } + sz = tmp_sz; } chunk* c = static_cast(::malloc(sizeof(chunk) + sz)); diff --git a/include/msgpack/detail/cpp03_zone.hpp b/include/msgpack/detail/cpp03_zone.hpp index 8d202232..3d55cfa2 100644 --- a/include/msgpack/detail/cpp03_zone.hpp +++ b/include/msgpack/detail/cpp03_zone.hpp @@ -271,7 +271,12 @@ inline void* zone::allocate_expand(size_t size) size_t sz = m_chunk_size; while(sz < size) { - sz *= 2; + size_t tmp_sz = sz * 2; + if (tmp_sz <= sz) { + sz = size; + break; + } + sz = tmp_sz; } chunk* c = static_cast(::malloc(sizeof(chunk) + sz)); diff --git a/include/msgpack/detail/cpp11_zone.hpp b/include/msgpack/detail/cpp11_zone.hpp index f3ec210b..7256aa34 100644 --- a/include/msgpack/detail/cpp11_zone.hpp +++ b/include/msgpack/detail/cpp11_zone.hpp @@ -269,7 +269,12 @@ inline void* zone::allocate_expand(size_t size) size_t sz = m_chunk_size; while(sz < size) { - sz *= 2; + size_t tmp_sz = sz * 2; + if (tmp_sz <= sz) { + sz = size; + break; + } + sz = tmp_sz; } chunk* c = static_cast(::malloc(sizeof(chunk) + sz)); diff --git a/include/msgpack/sbuffer.h b/include/msgpack/sbuffer.h index edfb246f..41202935 100644 --- a/include/msgpack/sbuffer.h +++ b/include/msgpack/sbuffer.h @@ -73,7 +73,14 @@ static inline int msgpack_sbuffer_write(void* data, const char* buf, size_t len) size_t nsize = (sbuf->alloc) ? sbuf->alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; - while(nsize < sbuf->size + len) { nsize *= 2; } + while(nsize < sbuf->size + len) { + size_t tmp_nsize = nsize * 2; + if (tmp_nsize <= nsize) { + nsize = sbuf->size + len; + break; + } + nsize = tmp_nsize; + } tmp = realloc(sbuf->data, nsize); if(!tmp) { return -1; } @@ -109,4 +116,3 @@ static inline void msgpack_sbuffer_clear(msgpack_sbuffer* sbuf) #endif #endif /* msgpack/sbuffer.h */ - diff --git a/include/msgpack/sbuffer.hpp b/include/msgpack/sbuffer.hpp index 531f9f16..7b968ae0 100644 --- a/include/msgpack/sbuffer.hpp +++ b/include/msgpack/sbuffer.hpp @@ -94,7 +94,14 @@ private: size_t nsize = (m_alloc > 0) ? m_alloc * 2 : MSGPACK_SBUFFER_INIT_SIZE; - while(nsize < m_size + len) { nsize *= 2; } + while(nsize < m_size + len) { + size_t tmp_nsize = nsize * 2; + if (tmp_nsize <= nsize) { + nsize = m_size + len; + break; + } + nsize = tmp_nsize; + } void* tmp = ::realloc(m_data, nsize); if(!tmp) { diff --git a/include/msgpack/unpack.hpp b/include/msgpack/unpack.hpp index 0486d8b3..b64ad53b 100644 --- a/include/msgpack/unpack.hpp +++ b/include/msgpack/unpack.hpp @@ -1101,7 +1101,12 @@ inline void unpacker::expand_buffer(std::size_t size) if(m_off == COUNTER_SIZE) { std::size_t next_size = (m_used + m_free) * 2; // include COUNTER_SIZE while(next_size < size + m_used) { - next_size *= 2; + std::size_t tmp_next_size = next_size * 2; + if (tmp_next_size <= next_size) { + next_size = size + m_used; + break; + } + next_size = tmp_next_size; } char* tmp = static_cast(::realloc(m_buffer, next_size)); diff --git a/include/msgpack/vrefbuffer.hpp b/include/msgpack/vrefbuffer.hpp index 28cd31ca..3e4e271b 100644 --- a/include/msgpack/vrefbuffer.hpp +++ b/include/msgpack/vrefbuffer.hpp @@ -202,7 +202,12 @@ public: const size_t reqsize = nused + tosize; size_t nnext = (to->m_end - to->m_array) * 2; while(nnext < reqsize) { - nnext *= 2; + size_t tmp_nnext = nnext * 2; + if (tmp_nnext <= nnext) { + nnext = reqsize; + break; + } + nnext = tmp_nnext; } iovec* nvec = static_cast(::realloc( diff --git a/src/unpack.c b/src/unpack.c index 33b1bec0..801a0d27 100644 --- a/src/unpack.c +++ b/src/unpack.c @@ -396,7 +396,12 @@ bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size) if(mpac->off == COUNTER_SIZE) { size_t next_size = (mpac->used + mpac->free) * 2; // include COUNTER_SIZE while(next_size < size + mpac->used) { - next_size *= 2; + size_t tmp_next_size = next_size * 2; + if (tmp_next_size <= next_size) { + next_size = size + mpac->used; + break; + } + next_size = tmp_next_size; } char* tmp = (char*)realloc(mpac->buffer, next_size); @@ -411,7 +416,12 @@ bool msgpack_unpacker_expand_buffer(msgpack_unpacker* mpac, size_t size) size_t next_size = mpac->initial_buffer_size; // include COUNTER_SIZE size_t not_parsed = mpac->used - mpac->off; while(next_size < size + not_parsed + COUNTER_SIZE) { - next_size *= 2; + size_t tmp_next_size = next_size * 2; + if (tmp_next_size <= next_size) { + next_size = size + not_parsed + COUNTER_SIZE; + break; + } + next_size = tmp_next_size; } char* tmp = (char*)malloc(next_size); diff --git a/src/vrefbuffer.c b/src/vrefbuffer.c index 1070ba2c..232b1c20 100644 --- a/src/vrefbuffer.c +++ b/src/vrefbuffer.c @@ -179,7 +179,12 @@ int msgpack_vrefbuffer_migrate(msgpack_vrefbuffer* vbuf, msgpack_vrefbuffer* to) const size_t reqsize = nused + tosize; size_t nnext = (size_t)(to->end - to->array) * 2; while(nnext < reqsize) { - nnext *= 2; + size_t tmp_nnext = nnext * 2; + if (tmp_nnext <= nnext) { + nnext = reqsize; + break; + } + nnext = tmp_nnext; } struct iovec* nvec = (struct iovec*)realloc( diff --git a/src/zone.c b/src/zone.c index 33e25169..45faf180 100644 --- a/src/zone.c +++ b/src/zone.c @@ -79,7 +79,12 @@ void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size) size_t sz = zone->chunk_size; while(sz < size) { - sz *= 2; + size_t tmp_sz = sz * 2; + if (tmp_sz <= sz) { + tmp_sz = size; + break; + } + sz = tmp_sz; } msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc( @@ -218,4 +223,3 @@ void msgpack_zone_free(msgpack_zone* zone) msgpack_zone_destroy(zone); free(zone); } -