summaryrefslogtreecommitdiff
path: root/deflate_slow.c
diff options
context:
space:
mode:
authorSebastian Pop <s.pop@samsung.com>2018-09-24 09:57:48 -0500
committerHans Kristian Rosbach <hk-github@circlestorm.org>2018-10-16 13:53:02 +0200
commit2071b9349e3df5431f81613a43f3a4369a9ae3e5 (patch)
tree370460e49e7b07d00a53fae8a441cecbc9975fba /deflate_slow.c
parent3f4de7e7b4878f2aed96ea24f96c61b628962f9b (diff)
fix bug #207: avoid undefined integer overflow
zlib-ng used to fail when compiled with UBSan with this error: deflate_slow.c:112:21: runtime error: unsigned integer overflow: 45871 - 45872 cannot be represented in type 'unsigned int' The bug occurs in code added to zlib-ng under `#ifndef NOT_TWEAK_COMPILER`. The original code of zlib contains a loop with two induction variables: s->prev_length -= 2; do { if (++s->strstart <= max_insert) { functable.insert_string(s, s->strstart, 1); } } while (--s->prev_length != 0); The function insert_string is not executed when !(++s->strstart <= max_insert) i.e., when !(s->strstart + 1 <= max_insert) !(s->strstart < max_insert) max_insert <= s->strstart The function insert_string is executed when ++s->strstart <= max_insert i.e., when s->strstart + 1 <= max_insert s->strstart < max_insert The function is executed at most `max_insert - s->strstart` times, following the exit condition of the do-while `(--s->prev_length != 0)`. If the loop exits after evaluating the exit condition once, the function is executed once independently of `max_insert - s->strstart`. The number of times the function executes is the minimum between the number of iterations in the do-while loop and `max_insert - s->strstart`. The number of iterations of the loop is `mov_fwd = s->prev_length - 2`, and we know that this is at least one as otherwise `--s->prev_length` would overflow. The number of times the function insert_string is called is `min(mov_fwd, max_insert - s->strstart)`
Diffstat (limited to 'deflate_slow.c')
-rw-r--r--deflate_slow.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/deflate_slow.c b/deflate_slow.c
index 1763477..de53b2d 100644
--- a/deflate_slow.c
+++ b/deflate_slow.c
@@ -108,11 +108,13 @@ ZLIB_INTERNAL block_state deflate_slow(deflate_state *s, int flush) {
#else
{
unsigned int mov_fwd = s->prev_length - 2;
- unsigned int insert_cnt = mov_fwd;
- if (unlikely(insert_cnt > max_insert - s->strstart))
- insert_cnt = max_insert - s->strstart;
+ if (max_insert > s->strstart) {
+ unsigned int insert_cnt = mov_fwd;
+ if (unlikely(insert_cnt > max_insert - s->strstart))
+ insert_cnt = max_insert - s->strstart;
- functable.insert_string(s, s->strstart + 1, insert_cnt);
+ functable.insert_string(s, s->strstart + 1, insert_cnt);
+ }
s->prev_length = 0;
s->match_available = 0;
s->match_length = MIN_MATCH-1;