aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-04 19:20:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:02:26 +0000
commit81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch)
tree311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp
parent5fff09660e06a66bed6482da9c70df328e16bbb6 (diff)
parent145449b1e420787bb99721a429341fa6be3adfb6 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp57
1 files changed, 37 insertions, 20 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp b/contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp
index 28adfe6268f9..c297e16bdfdf 100644
--- a/contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp
+++ b/contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp
@@ -16,6 +16,10 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
// BitstreamCursor implementation
//===----------------------------------------------------------------------===//
+//
+static Error error(const char *Message) {
+ return createStringError(std::errc::illegal_byte_sequence, Message);
+}
/// Having read the ENTER_SUBBLOCK abbrevid, enter the block.
Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
@@ -97,7 +101,7 @@ Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
unsigned Code = MaybeCode.get();
Expected<uint32_t> MaybeVBR = ReadVBR(6);
if (!MaybeVBR)
- return MaybeVBR.get();
+ return MaybeVBR.takeError();
unsigned NumElts = MaybeVBR.get();
for (unsigned i = 0; i != NumElts; ++i)
if (Expected<uint64_t> Res = ReadVBR64(6))
@@ -107,7 +111,11 @@ Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
return Code;
}
- const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
+ Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
+ if (!MaybeAbbv)
+ return MaybeAbbv.takeError();
+
+ const BitCodeAbbrev *Abbv = MaybeAbbv.get();
const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
unsigned Code;
if (CodeOp.isLiteral())
@@ -152,7 +160,7 @@ Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
// Decode the value as we are commanded.
switch (EltEnc.getEncoding()) {
default:
- report_fatal_error("Array element type can't be an Array or a Blob");
+ return error("Array element type can't be an Array or a Blob");
case BitCodeAbbrevOp::Fixed:
assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
if (Error Err =
@@ -212,8 +220,12 @@ Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
uint32_t Code = MaybeCode.get();
Expected<uint32_t> MaybeNumElts = ReadVBR(6);
if (!MaybeNumElts)
- return MaybeNumElts.takeError();
+ return error(
+ ("Failed to read size: " + toString(MaybeNumElts.takeError()))
+ .c_str());
uint32_t NumElts = MaybeNumElts.get();
+ if (!isSizePlausible(NumElts))
+ return error("Size is not plausible");
Vals.reserve(Vals.size() + NumElts);
for (unsigned i = 0; i != NumElts; ++i)
@@ -224,7 +236,10 @@ Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
return Code;
}
- const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
+ Expected<const BitCodeAbbrev *> MaybeAbbv = getAbbrev(AbbrevID);
+ if (!MaybeAbbv)
+ return MaybeAbbv.takeError();
+ const BitCodeAbbrev *Abbv = MaybeAbbv.get();
// Read the record code first.
assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
@@ -235,7 +250,7 @@ Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
else {
if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
- report_fatal_error("Abbreviation starts with an Array or a Blob");
+ return error("Abbreviation starts with an Array or a Blob");
if (Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp))
Code = MaybeCode.get();
else
@@ -262,22 +277,26 @@ Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
// Array case. Read the number of elements as a vbr6.
Expected<uint32_t> MaybeNumElts = ReadVBR(6);
if (!MaybeNumElts)
- return MaybeNumElts.takeError();
+ return error(
+ ("Failed to read size: " + toString(MaybeNumElts.takeError()))
+ .c_str());
uint32_t NumElts = MaybeNumElts.get();
+ if (!isSizePlausible(NumElts))
+ return error("Size is not plausible");
Vals.reserve(Vals.size() + NumElts);
// Get the element encoding.
if (i + 2 != e)
- report_fatal_error("Array op not second to last");
+ return error("Array op not second to last");
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
if (!EltEnc.isEncoding())
- report_fatal_error(
+ return error(
"Array element type has to be an encoding of a type");
// Read all the elements.
switch (EltEnc.getEncoding()) {
default:
- report_fatal_error("Array element type can't be an Array or a Blob");
+ return error("Array element type can't be an Array or a Blob");
case BitCodeAbbrevOp::Fixed:
for (; NumElts; --NumElts)
if (Expected<SimpleBitstreamCursor::word_t> MaybeVal =
@@ -316,13 +335,9 @@ Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
size_t CurBitPos = GetCurrentBitNo();
const size_t NewEnd = CurBitPos + alignTo(NumElts, 4) * 8;
- // If this would read off the end of the bitcode file, just set the
- // record to empty and return.
- if (!canSkipToPos(NewEnd/8)) {
- Vals.append(NumElts, 0);
- skipToEnd();
- break;
- }
+ // Make sure the bitstream is large enough to contain the blob.
+ if (!canSkipToPos(NewEnd/8))
+ return error("Blob ends too soon");
// Otherwise, inform the streamer that we need these bytes in memory. Skip
// over tail padding first, in case jumping to NewEnd invalidates the Blob
@@ -366,6 +381,9 @@ Error BitstreamCursor::ReadAbbrevRecord() {
Expected<word_t> MaybeEncoding = Read(3);
if (!MaybeEncoding)
return MaybeEncoding.takeError();
+ if (!BitCodeAbbrevOp::isValidEncoding(MaybeEncoding.get()))
+ return error("Invalid encoding");
+
BitCodeAbbrevOp::Encoding E =
(BitCodeAbbrevOp::Encoding)MaybeEncoding.get();
if (BitCodeAbbrevOp::hasEncodingData(E)) {
@@ -385,8 +403,7 @@ Error BitstreamCursor::ReadAbbrevRecord() {
if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
Data > MaxChunkSize)
- report_fatal_error(
- "Fixed or VBR abbrev record with size > MaxChunkData");
+ return error("Fixed or VBR abbrev record with size > MaxChunkData");
Abbv->Add(BitCodeAbbrevOp(E, Data));
} else
@@ -394,7 +411,7 @@ Error BitstreamCursor::ReadAbbrevRecord() {
}
if (Abbv->getNumOperandInfos() == 0)
- report_fatal_error("Abbrev record with no operands");
+ return error("Abbrev record with no operands");
CurAbbrevs.push_back(std::move(Abbv));
return Error::success();