aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2019-06-13 01:48:30 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2019-06-13 01:48:30 +0300
commitfd62683c0dc0a16a27fcfc82b43e57ef13ac9a38 (patch)
treeb044064d205408582101f358ca0efe83798da98d
parente1cdae6b96865aba121fc17d37519f670691d008 (diff)
downloadlibmicrohttpd-fd62683c0dc0a16a27fcfc82b43e57ef13ac9a38.tar.gz
libmicrohttpd-fd62683c0dc0a16a27fcfc82b43e57ef13ac9a38.zip
memorypool: fixed/rewritten MHD_pool_reallocate()
-rw-r--r--src/microhttpd/memorypool.c72
1 files changed, 35 insertions, 37 deletions
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index 3746eb71..4a890967 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -257,55 +257,53 @@ MHD_pool_reallocate (struct MemoryPool *pool,
257 size_t old_size, 257 size_t old_size,
258 size_t new_size) 258 size_t new_size)
259{ 259{
260 void *ret;
261 size_t asize; 260 size_t asize;
261 uint8_t *new_blc;
262 262
263 mhd_assert (pool->end >= pool->pos); 263 mhd_assert (pool->end >= pool->pos);
264 mhd_assert (pool->size >= pool->end - pool->pos); 264 mhd_assert (pool->size >= pool->end - pool->pos);
265 mhd_assert (old != NULL || old_size == 0); 265 mhd_assert (old != NULL || old_size == 0);
266 mhd_assert (old == NULL || pool->memory <= (uint8_t*)old); 266 mhd_assert (old == NULL || pool->memory <= (uint8_t*)old);
267 mhd_assert (old == NULL || pool->memory + pool->size >= (uint8_t*)old + old_size); 267 mhd_assert (old == NULL || pool->memory + pool->size >= (uint8_t*)old + old_size);
268 asize = ROUND_TO_ALIGN (new_size); 268 /* Blocks "from the end" must not be reallocated */
269 if ( (0 == asize) && 269 mhd_assert (old == NULL || pool->memory + pool->pos > (uint8_t*)old);
270 (0 != new_size) ) 270
271 return NULL; /* new_size too close to SIZE_MAX */ 271 if (pool->memory + new_size + 2 * ALIGN_SIZE< pool->memory)
272 if ( (pool->end < old_size) || 272 return NULL; /* Value wrap, too large new_size. */
273 (pool->end < asize) ) 273
274 return NULL; /* unsatisfiable or bogus request */ 274 if (0 != old_size)
275 275 { /* Need to relocate data */
276 if ( (pool->pos >= old_size) && 276 const size_t old_offset = (uint8_t*)old - pool->memory;
277 (&pool->memory[pool->pos - old_size] == old) ) 277
278 { 278 if (pool->pos == ROUND_TO_ALIGN (old_offset + old_size))
279 /* was the previous allocation - optimize! */ 279 { /* "old" block is the last allocated block */
280 if (pool->pos + asize - old_size <= pool->end) 280 const size_t new_apos = ROUND_TO_ALIGN (old_offset + new_size);
281 { 281 if (new_apos > pool->end)
282 /* fits */ 282 return NULL; /* No space */
283 pool->pos += asize - old_size; 283
284 if (asize < old_size) /* shrinking - zero again! */ 284 pool->pos = new_apos;
285 memset (&pool->memory[pool->pos], 285 /* Zero-out unused part if shrinking */
286 0, 286 if (old_size > new_size)
287 old_size - asize); 287 memset (old + new_size, 0, old_size - new_size);
288 return old; 288 return old;
289 } 289 }
290 /* does not fit */
291 return NULL;
292 } 290 }
293 if (asize <= old_size) 291 /* Need to allocate new block */
294 return old; /* cannot shrink, no need to move */ 292 asize = ROUND_TO_ALIGN (new_size);
295 if ((pool->pos + asize >= pool->pos) && 293 if (asize > pool->end - pool->pos)
296 (pool->pos + asize <= pool->end)) 294 return NULL; /* No space */
295
296 new_blc = pool->memory + pool->pos;
297 pool->pos += asize;
298
299 if (0 != old_size)
297 { 300 {
298 /* fits */ 301 /* Move data no new block, old block remains allocated */
299 ret = &pool->memory[pool->pos]; 302 memcpy (new_blc, old, old_size);
300 if (0 != old_size) 303 /* Zero-out old block */
301 memmove (ret, 304 memset (old, 0, old_size);
302 old,
303 old_size);
304 pool->pos += asize;
305 return ret;
306 } 305 }
307 /* does not fit */ 306 return new_blc;
308 return NULL;
309} 307}
310 308
311 309