aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2019-06-13 19:03:27 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2019-06-13 19:16:51 +0300
commitd12ed49fd33d991639512ee7637bfc644da3f123 (patch)
tree46a3d40e5cef308c2eec738a0132319db4feb270
parent35d581d04fcfbd2052babcb35b9251af938c9e3e (diff)
downloadlibmicrohttpd-d12ed49fd33d991639512ee7637bfc644da3f123.tar.gz
libmicrohttpd-d12ed49fd33d991639512ee7637bfc644da3f123.zip
memorypool: reallocate: more checks for value wrap, small optimization
-rw-r--r--src/microhttpd/memorypool.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index 5f532b83..3770b8c3 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -267,29 +267,33 @@ MHD_pool_reallocate (struct MemoryPool *pool,
267 /* Blocks "from the end" must not be reallocated */ 267 /* Blocks "from the end" must not be reallocated */
268 mhd_assert (old == NULL || pool->memory + pool->pos > (uint8_t*)old); 268 mhd_assert (old == NULL || pool->memory + pool->pos > (uint8_t*)old);
269 269
270 if (new_size + 2 * ALIGN_SIZE < new_size)
271 return NULL; /* Value wrap, too large new_size. */
272
273 if (0 != old_size) 270 if (0 != old_size)
274 { /* Need to relocate data */ 271 { /* Need to save some data */
275 const size_t old_offset = (uint8_t*)old - pool->memory; 272 const size_t old_offset = (uint8_t*)old - pool->memory;
276 273 /* Try resizing in-place */
277 if (pool->pos == ROUND_TO_ALIGN (old_offset + old_size)) 274 if (pool->pos == ROUND_TO_ALIGN (old_offset + old_size))
278 { /* "old" block is the last allocated block */ 275 { /* "old" block is the last allocated block */
279 const size_t new_apos = ROUND_TO_ALIGN (old_offset + new_size); 276 const size_t new_apos = ROUND_TO_ALIGN (old_offset + new_size);
280 if (new_apos > pool->end)
281 return NULL; /* No space */
282
283 pool->pos = new_apos;
284 /* Zero-out unused part if shrinking */
285 if (old_size > new_size) 277 if (old_size > new_size)
286 memset ((uint8_t*)old + new_size, 0, old_size - new_size); 278 { /* Shrinking in-place, zero-out freed part */
279 memset ((uint8_t*)old + new_size, 0, old_size - new_size);
280 }
281 else
282 { /* Grow in-place, check for enough space. */
283 if ( (new_apos > pool->end) ||
284 (new_apos < pool->pos) ) /* Value wrap */
285 return NULL; /* No space */
286 }
287 /* Resized in-place */
288 pool->pos = new_apos;
287 return old; 289 return old;
288 } 290 }
289 } 291 }
290 /* Need to allocate new block */ 292 /* Need to allocate new block */
291 asize = ROUND_TO_ALIGN (new_size); 293 asize = ROUND_TO_ALIGN (new_size);
292 if (asize > pool->end - pool->pos) 294 if ( ( (0 == asize) &&
295 (0 != new_size) ) || /* Value wrap, too large new_size. */
296 (asize > pool->end - pool->pos) )
293 return NULL; /* No space */ 297 return NULL; /* No space */
294 298
295 new_blc = pool->memory + pool->pos; 299 new_blc = pool->memory + pool->pos;
@@ -297,9 +301,9 @@ MHD_pool_reallocate (struct MemoryPool *pool,
297 301
298 if (0 != old_size) 302 if (0 != old_size)
299 { 303 {
300 /* Move data no new block, old block remains allocated */ 304 /* Move data to new block, old block remains allocated */
301 memcpy (new_blc, old, old_size); 305 memcpy (new_blc, old, old_size);
302 /* Zero-out old block */ 306 /* Zero-out freed old block */
303 memset (old, 0, old_size); 307 memset (old, 0, old_size);
304 } 308 }
305 return new_blc; 309 return new_blc;