From 1f059e848de23a03f21e564b9e6b3b2d8dec87a2 Mon Sep 17 00:00:00 2001 From: Erik de Castro Lopo Date: Mon, 18 Nov 2019 19:02:31 +1100 Subject: libFLAC/bitreader.c: Fix shift invoking undefined behaviour Credit: Oss-Fuzz Issue: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18535 Testcase: fuzzer_decoder-6573800707063808 --- src/libFLAC/bitreader.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libFLAC/bitreader.c b/src/libFLAC/bitreader.c index d2c058d9..3fdb12bd 100644 --- a/src/libFLAC/bitreader.c +++ b/src/libFLAC/bitreader.c @@ -403,18 +403,19 @@ FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *va /* this also works when consumed_bits==0, it's just a little slower than necessary for that case */ const uint32_t n = FLAC__BITS_PER_WORD - br->consumed_bits; const brword word = br->buffer[br->consumed_words]; + const brword mask = br->consumed_bits < FLAC__BITS_PER_WORD ? FLAC__WORD_ALL_ONES >> br->consumed_bits : 0; if(bits < n) { - *val = (FLAC__uint32)((word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)) >> (n-bits)); /* The result has <= 32 non-zero bits */ + *val = (FLAC__uint32)((word & mask) >> (n-bits)); /* The result has <= 32 non-zero bits */ br->consumed_bits += bits; return true; } /* (FLAC__BITS_PER_WORD - br->consumed_bits <= bits) ==> (FLAC__WORD_ALL_ONES >> br->consumed_bits) has no more than 'bits' non-zero bits */ - *val = (FLAC__uint32)(word & (FLAC__WORD_ALL_ONES >> br->consumed_bits)); + *val = (FLAC__uint32)(word & mask); bits -= n; br->consumed_words++; br->consumed_bits = 0; if(bits) { /* if there are still bits left to read, there have to be less than 32 so they will all be in the next word */ - *val <<= bits; + *val = bits >= 32 ? 0 : *val << bits ; *val |= (FLAC__uint32)(br->buffer[br->consumed_words] >> (FLAC__BITS_PER_WORD-bits)); br->consumed_bits = bits; } -- cgit v1.2.1