From 4d816544023e1aadc026b6692289eacfceec56c8 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 23 May 2016 19:55:06 -0500 Subject: [PATCH] Use tighter bound on max number of nodes --- lib/deflate_compress.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/deflate_compress.c b/lib/deflate_compress.c index e60bed7..2c89ed1 100644 --- a/lib/deflate_compress.c +++ b/lib/deflate_compress.c @@ -52,7 +52,8 @@ /* * The minimum and maximum block lengths, in bytes of source data, which the - * parsing algorithms may choose. + * parsing algorithms may choose. Caveat: due to implementation details, the + * actual maximum will be slightly higher than the number defined below. */ #define MIN_BLOCK_LENGTH 10000 #define MAX_BLOCK_LENGTH 300000 @@ -396,10 +397,19 @@ struct deflate_compressor { MAX_MATCHES_PER_POS + DEFLATE_MAX_MATCH_LEN - 1]; - /* Array of structures, one per position, for running - * the minimum-cost path algorithm. */ - struct deflate_optimum_node optimum[MAX_BLOCK_LENGTH + - 3 * DEFLATE_MAX_MATCH_LEN]; + /* + * Array of nodes, one per position, for running the + * minimum-cost path algorithm. + * + * This array must be large enough to accommodate the + * worst-case number of nodes, which occurs if we find a + * match of length DEFLATE_MAX_MATCH_LEN at position + * MAX_BLOCK_LENGTH - 1, producing a block of length + * MAX_BLOCK_LENGTH - 1 + DEFLATE_MAX_MATCH_LEN. Add + * one for the end-of-block node. + */ + struct deflate_optimum_node optimum[MAX_BLOCK_LENGTH - 1 + + DEFLATE_MAX_MATCH_LEN + 1]; /* The current cost model being used. */ struct deflate_costs costs; @@ -2301,12 +2311,13 @@ deflate_optimize_and_write_block(struct deflate_compressor *c, { struct deflate_optimum_node * const end_node = c->optimum + block_length; unsigned num_passes_remaining = c->num_optim_passes; - unsigned i; + u32 i; /* Force the block to really end at 'end_node', even if some matches * extend beyond it. */ - for (i = 1; i < DEFLATE_MAX_MATCH_LEN; i++) - end_node[i].cost_to_end = 0x80000000; + for (i = block_length; i <= MIN(block_length - 1 + DEFLATE_MAX_MATCH_LEN, + ARRAY_LEN(c->optimum) - 1); i++) + c->optimum[i].cost_to_end = 0x80000000; do { /*