diff options
-rw-r--r-- | fitz/res_store.c | 29 |
1 files 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); |