From 55409f2b03dd9526074e2cc1312f068905fc0107 Mon Sep 17 00:00:00 2001 From: Alexey Tourbin Date: Mon, 3 Oct 2011 05:09:12 +0400 Subject: [PATCH] set.c: fixed assertion failure with malformed "empty set" set-string In decode_set_init(), we explicitly prohibit empty sets: // no empty sets for now if (*str == '\0') return -4; This does not validate *str character, since the decoder will check for errors anyway. However, this assumes that, otherwise, a non-empty set will be decoded. The assumption is wrong: it was actually possible to construct an "empty set" which triggered assertion failure. $ /usr/lib/rpm/setcmp yx00 yx00 setcmp: set.c:705: decode_delta: Assertion `c > 0' failed. zsh: abort /usr/lib/rpm/setcmp yx00 yx00 $ Here, the "00" part of the set-version yields a sequence of zero bits. Since trailing zero bits are okay, golomb decoding routine basically skips the whole sequence and returns 0. To fix the problem, we have to observe that only up to 5 trailing zero bits can be required to complete last base62 character, and the leading "0" sequence occupies 6 or more bits. --- lib/set.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/set.c b/lib/set.c index 10a5d59..36fc631 100644 --- a/lib/set.c +++ b/lib/set.c @@ -326,8 +326,12 @@ int decode_golomb(int bitc, const char *bitv, int Mshift, unsigned *v) break; } // trailing zero bits in the input are okay - if (bitc == 0 && bit == 0) + if (bitc == 0 && bit == 0) { + // up to 5 bits can be used to complete last character + if (q > 5) + return -10; break; + } // otherwise, incomplete value is not okay if (bitc < Mshift) return -10; @@ -637,7 +641,7 @@ int decode_base62_golomb(const char *base62, int Mshift, unsigned *v) } } eol: - if (state != ST_VLEN) + if (state != ST_VLEN || q > 5) return -10; return v - v_start; }