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.
This commit is contained in:
Alexey Tourbin 2011-10-03 05:09:12 +04:00
parent 57e524d737
commit 55409f2b03

View File

@ -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;
}