From 6dfcd67f524a1931830a3b01198951a7843462db Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Fri, 13 Jan 2012 15:54:13 +0000 Subject: Scavenging fixes; overflow and division by zero. Ensure we don't get a division by zero (when *phase goes to 16). Also ensure we don't overflow the bounds of an unsigned int. Thanks to Zeniko for spotting these problems. --- fitz/res_store.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/fitz/res_store.c b/fitz/res_store.c index 6a38f438..dc9b14a2 100644 --- a/fitz/res_store.c +++ b/fitz/res_store.c @@ -436,23 +436,34 @@ int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase) #endif do { + unsigned int tofree; + /* Calculate 'max' as the maximum size of the store for this phase */ - if (store->max != FZ_STORE_UNLIMITED) + if (*phase >= 16) + max = 0; + else if (store->max != FZ_STORE_UNLIMITED) max = store->max / 16 * (16 - *phase); else max = store->size / (16 - *phase) * (15 - *phase); (*phase)++; - if (size + store->size > max) - if (scavenge(ctx, size + store->size - max)) - { + /* Slightly baroque calculations to avoid overflow */ + if (size > UINT_MAX - store->size) + tofree = UINT_MAX - max; + else if (size + store->size > max) + continue; + else + tofree = size + store->size - max; + + if (scavenge(ctx, tofree)) + { #ifdef DEBUG_SCAVENGING - printf("scavenged: store=%d\n", store->size); - fz_debug_store(ctx); - Memento_stats(); + printf("scavenged: store=%d\n", store->size); + fz_debug_store(ctx); + Memento_stats(); #endif - return 1; - } + return 1; + } } while (max > 0); -- cgit v1.2.3