diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Bitstream/Reader/BitstreamReader.cpp | 57 |
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(); |