diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2019-06-13 19:03:27 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2019-06-13 19:16:51 +0300 |
commit | d12ed49fd33d991639512ee7637bfc644da3f123 (patch) | |
tree | 46a3d40e5cef308c2eec738a0132319db4feb270 | |
parent | 35d581d04fcfbd2052babcb35b9251af938c9e3e (diff) | |
download | libmicrohttpd-d12ed49fd33d991639512ee7637bfc644da3f123.tar.gz libmicrohttpd-d12ed49fd33d991639512ee7637bfc644da3f123.zip |
memorypool: reallocate: more checks for value wrap, small optimization
-rw-r--r-- | src/microhttpd/memorypool.c | 32 |
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; |