Skip to content

Commit

Permalink
[Bitstream] Add assert to ReadVBR and ReadVBR64
Browse files Browse the repository at this point in the history
We want to prevent UB potentially caused by left-shifting by type bit-width.

Differential Revision: https://reviews.llvm.org/D119307
  • Loading branch information
jkorous-apple committed Feb 16, 2022
1 parent 132553b commit 6280c29
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions llvm/include/llvm/Bitstream/BitstreamReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,21 +227,25 @@ class SimpleBitstreamCursor {
return R;
}

Expected<uint32_t> ReadVBR(unsigned NumBits) {
Expected<uint32_t> ReadVBR(const unsigned NumBits) {
Expected<unsigned> MaybeRead = Read(NumBits);
if (!MaybeRead)
return MaybeRead;
uint32_t Piece = MaybeRead.get();

if ((Piece & (1U << (NumBits-1))) == 0)
assert(NumBits <= 32 && NumBits >= 1 && "Invalid NumBits value");
const uint32_t MaskBitOrder = (NumBits - 1);
const uint32_t Mask = 1UL << MaskBitOrder;

if ((Piece & Mask) == 0)
return Piece;

uint32_t Result = 0;
unsigned NextBit = 0;
while (true) {
Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
Result |= (Piece & (Mask - 1)) << NextBit;

if ((Piece & (1U << (NumBits-1))) == 0)
if ((Piece & Mask) == 0)
return Result;

NextBit += NumBits-1;
Expand All @@ -258,21 +262,24 @@ class SimpleBitstreamCursor {

// Read a VBR that may have a value up to 64-bits in size. The chunk size of
// the VBR must still be <= 32 bits though.
Expected<uint64_t> ReadVBR64(unsigned NumBits) {
Expected<uint64_t> ReadVBR64(const unsigned NumBits) {
Expected<uint64_t> MaybeRead = Read(NumBits);
if (!MaybeRead)
return MaybeRead;
uint32_t Piece = MaybeRead.get();
assert(NumBits <= 32 && NumBits >= 1 && "Invalid NumBits value");
const uint32_t MaskBitOrder = (NumBits - 1);
const uint32_t Mask = 1UL << MaskBitOrder;

if ((Piece & (1U << (NumBits-1))) == 0)
if ((Piece & Mask) == 0)
return uint64_t(Piece);

uint64_t Result = 0;
unsigned NextBit = 0;
while (true) {
Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit;
Result |= uint64_t(Piece & (Mask - 1)) << NextBit;

if ((Piece & (1U << (NumBits-1))) == 0)
if ((Piece & Mask) == 0)
return Result;

NextBit += NumBits-1;
Expand Down

0 comments on commit 6280c29

Please sign in to comment.