Index: llvm/include/llvm/Bitstream/BitstreamReader.h =================================================================== --- llvm/include/llvm/Bitstream/BitstreamReader.h +++ llvm/include/llvm/Bitstream/BitstreamReader.h @@ -227,21 +227,28 @@ return R; } - Expected ReadVBR(unsigned NumBits) { + Expected ReadVBR(const unsigned NumBits) { Expected MaybeRead = Read(NumBits); if (!MaybeRead) return MaybeRead; uint32_t Piece = MaybeRead.get(); - if ((Piece & (1U << (NumBits-1))) == 0) + if (NumBits >= 33 || NumBits == 0) + return make_error("Invalid NumBits value: " + + std::to_string(NumBits), + llvm::inconvertibleErrorCode()); + 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; Index: llvm/lib/Bitstream/Reader/BitstreamReader.cpp =================================================================== --- llvm/lib/Bitstream/Reader/BitstreamReader.cpp +++ llvm/lib/Bitstream/Reader/BitstreamReader.cpp @@ -220,7 +220,9 @@ uint32_t Code = MaybeCode.get(); Expected MaybeNumElts = ReadVBR(6); if (!MaybeNumElts) - return MaybeNumElts.takeError(); + return error(("Failed to read size: " + + toString(std::move(MaybeNumElts.takeError()))) + .c_str()); uint32_t NumElts = MaybeNumElts.get(); if (!isSizePlausible(NumElts)) return error("Size is not plausible"); @@ -275,7 +277,9 @@ // Array case. Read the number of elements as a vbr6. Expected MaybeNumElts = ReadVBR(6); if (!MaybeNumElts) - return MaybeNumElts.takeError(); + return error(("Failed to read size: " + + toString(std::move(MaybeNumElts.takeError()))) + .c_str()); uint32_t NumElts = MaybeNumElts.get(); if (!isSizePlausible(NumElts)) return error("Size is not plausible"); Index: llvm/test/Bitcode/invalid.test =================================================================== --- llvm/test/Bitcode/invalid.test +++ llvm/test/Bitcode/invalid.test @@ -275,7 +275,7 @@ RUN: not llvm-dis -disable-output %p/Inputs/unterminated-vbr.bc 2>&1 | \ RUN: FileCheck --check-prefix=UNTERMINATED-VBR %s -UNTERMINATED-VBR: Unterminated VBR +UNTERMINATED-VBR: Failed to read size: Unterminated VBR RUN: not llvm-dis -disable-output %p/Inputs/comdat-name-too-large.bc 2>&1 | \ RUN: FileCheck --check-prefix=COMDAT-NAME-TOO-LARGE %s