diff --git a/include/llvm/DebugInfo/CodeView/StreamRef.h b/include/llvm/DebugInfo/CodeView/StreamRef.h index b581c120cca..22c4bdb5941 100644 --- a/include/llvm/DebugInfo/CodeView/StreamRef.h +++ b/include/llvm/DebugInfo/CodeView/StreamRef.h @@ -29,6 +29,8 @@ public: Error readBytes(uint32_t Offset, uint32_t Size, ArrayRef &Buffer) const override { + if (ViewOffset + Offset < Offset) + return make_error(cv_error_code::insufficient_buffer); if (Size + Offset > Length) return make_error(cv_error_code::insufficient_buffer); return Stream->readBytes(ViewOffset + Offset, Size, Buffer); diff --git a/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h b/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h index 717a7880f3c..fccea2ac247 100644 --- a/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h +++ b/include/llvm/DebugInfo/PDB/Raw/IPDBFile.h @@ -33,8 +33,8 @@ public: virtual ArrayRef getStreamBlockList(uint32_t StreamIndex) const = 0; - virtual ArrayRef getBlockData(uint32_t BlockIndex, - uint32_t NumBytes) const = 0; + virtual Expected> getBlockData(uint32_t BlockIndex, + uint32_t NumBytes) const = 0; virtual Error setBlockData(uint32_t BlockIndex, uint32_t Offset, ArrayRef Data) const = 0; }; diff --git a/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/include/llvm/DebugInfo/PDB/Raw/PDBFile.h index f5aad723a77..a8e1dc5c307 100644 --- a/include/llvm/DebugInfo/PDB/Raw/PDBFile.h +++ b/include/llvm/DebugInfo/PDB/Raw/PDBFile.h @@ -84,8 +84,8 @@ public: getStreamBlockList(uint32_t StreamIndex) const override; size_t getFileSize() const; - ArrayRef getBlockData(uint32_t BlockIndex, - uint32_t NumBytes) const override; + Expected> getBlockData(uint32_t BlockIndex, + uint32_t NumBytes) const override; Error setBlockData(uint32_t BlockIndex, uint32_t Offset, ArrayRef Data) const override; diff --git a/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp b/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp index 3463871227b..92b2048c3c2 100644 --- a/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp +++ b/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp @@ -139,8 +139,10 @@ Error MappedBlockStream::readLongestContiguousChunk( uint32_t BlockSpan = Last - First + 1; uint32_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * Pdb.getBlockSize(); - Buffer = Pdb.getBlockData(BlockList[First], Pdb.getBlockSize()); - Buffer = Buffer.drop_front(OffsetInFirstBlock); + auto Result = Pdb.getBlockData(BlockList[First], Pdb.getBlockSize()); + if (!Result) + return Result.takeError(); + Buffer = Result->drop_front(OffsetInFirstBlock); Buffer = ArrayRef(Buffer.data(), ByteSpan); return Error::success(); } @@ -173,8 +175,12 @@ bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size, } uint32_t FirstBlockAddr = BlockList[BlockNum]; - auto Data = Pdb.getBlockData(FirstBlockAddr, Pdb.getBlockSize()); - Data = Data.drop_front(OffsetInBlock); + auto Result = Pdb.getBlockData(FirstBlockAddr, Pdb.getBlockSize()); + if (!Result) { + consumeError(Result.takeError()); + return false; + } + auto Data = Result->drop_front(OffsetInBlock); Buffer = ArrayRef(Data.data(), Size); return true; } @@ -197,8 +203,11 @@ Error MappedBlockStream::readBytes(uint32_t Offset, while (BytesLeft > 0) { uint32_t StreamBlockAddr = BlockList[BlockNum]; - auto Data = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize()); + auto Result = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize()); + if (!Result) + return Result.takeError(); + auto Data = *Result; const uint8_t *ChunkStart = Data.data() + OffsetInBlock; uint32_t BytesInChunk = std::min(BytesLeft, Pdb.getBlockSize() - OffsetInBlock); diff --git a/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/lib/DebugInfo/PDB/Raw/PDBFile.cpp index 2d8e0d0ed91..b289fd0124b 100644 --- a/lib/DebugInfo/PDB/Raw/PDBFile.cpp +++ b/lib/DebugInfo/PDB/Raw/PDBFile.cpp @@ -73,13 +73,13 @@ PDBFile::getStreamBlockList(uint32_t StreamIndex) const { size_t PDBFile::getFileSize() const { return Buffer->getLength(); } -ArrayRef PDBFile::getBlockData(uint32_t BlockIndex, - uint32_t NumBytes) const { +Expected> PDBFile::getBlockData(uint32_t BlockIndex, + uint32_t NumBytes) const { uint64_t StreamBlockOffset = blockToOffset(BlockIndex, getBlockSize()); ArrayRef Result; if (auto EC = Buffer->readBytes(StreamBlockOffset, NumBytes, Result)) - consumeError(std::move(EC)); + return std::move(EC); return Result; } @@ -460,4 +460,4 @@ Error PDBFile::commit() { } return Buffer->commit(); -} \ No newline at end of file +} diff --git a/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp b/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp index e54f7ab1250..dd6fce23736 100644 --- a/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp +++ b/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp @@ -61,8 +61,8 @@ public: return ArrayRef(); return Blocks; } - ArrayRef getBlockData(uint32_t BlockIndex, - uint32_t NumBytes) const override { + Expected> getBlockData(uint32_t BlockIndex, + uint32_t NumBytes) const override { return ArrayRef(&Data[BlockIndex], NumBytes); }