Near end-of-input the caller's prev_length can exceed the
current lookahead, making the chain walk pointless since no
match can be longer than the available input. The non-slow
path never clamped this case — break_matching was slow-path
only — leaving the output contract unguarded.
Together with the existing `if (len >= lookahead)` early
return in the update block — which stops the chain walk as
soon as a match reaches lookahead — this ensures no
unnecessary chain steps are taken. madler/zlib does the full
chain walk when prev_length exceeds lookahead and clamps
best_len at the function exit resulting in extra work.
/* The code is optimized for STD_MAX_MATCH-2 multiple of 16. */
Assert(STD_MAX_MATCH == 258, "Code too clever");
- scan = window + strstart;
best_len = s->prev_length ? s->prev_length : STD_MIN_MATCH-1;
+ if (best_len >= lookahead)
+ return lookahead;
/* Calculate read offset which should only extend an extra byte
* to find the next best match length.
offset -= 4;
}
+ scan = window + strstart;
scan_start = zng_memread_8(scan);
scan_end = zng_memread_8(scan+offset);
mbase_end = (mbase_start+offset);