summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik de Castro Lopo <erikd@mega-nerd.com>2019-11-18 19:02:31 +1100
committerErik de Castro Lopo <erikd@mega-nerd.com>2019-11-19 06:10:19 +1100
commit1f059e848de23a03f21e564b9e6b3b2d8dec87a2 (patch)
treed973ac8ebe073b3291395cf3b715923a2a7b77ab
parented1b67b9a8a1c712e2bd7167493ab3b7e2910789 (diff)
downloadflac-1f059e848de23a03f21e564b9e6b3b2d8dec87a2.tar.gz
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
-rw-r--r--src/libFLAC/bitreader.c7
1 files 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;
}