summaryrefslogtreecommitdiffstats
path: root/lib/Lex/HeaderMap.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-02-20 21:24:31 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-02-20 21:24:31 +0000
commit39c202cadc520b275dd3952573147dff214ea9f2 (patch)
tree9e24130154fdf297ec732988a727403446fb20d6 /lib/Lex/HeaderMap.cpp
parent4a8b8ff576265eb20d5dda28e7cb4ef8d0da1159 (diff)
Lex: Check whether the header map buffer has space for the buckets
Check up front whether the header map buffer has space for all of its declared buckets. There was already a check in `getBucket()`, but it had UB (comparing pointers that were outside of objects in the error path) and was insufficient (only checking for a single byte of the relevant bucket). I fixed the check, moved it to `checkHeader()`, and left a fixed version behind as an assertion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261449 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/HeaderMap.cpp')
-rw-r--r--lib/Lex/HeaderMap.cpp20
1 files changed, 10 insertions, 10 deletions
diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp
index 2b31ab9d04..220e70d8d5 100644
--- a/lib/Lex/HeaderMap.cpp
+++ b/lib/Lex/HeaderMap.cpp
@@ -83,14 +83,16 @@ bool HeaderMapImpl::checkHeader(const llvm::MemoryBuffer &File,
if (Header->Reserved != 0)
return false;
- // Check the number of buckets.
+ // Check the number of buckets. It should be a power of two, and there
+ // should be enough space in the file for all of them.
auto NumBuckets = NeedsByteSwap
? llvm::sys::getSwappedBytes(Header->NumBuckets)
: Header->NumBuckets;
-
- // If the number of buckets is not a power of two, the headermap is corrupt.
if (NumBuckets & (NumBuckets - 1))
return false;
+ if (File.getBufferSize() <
+ sizeof(HMapHeader) + sizeof(HMapBucket) * NumBuckets)
+ return false;
// Okay, everything looks good.
return true;
@@ -122,21 +124,19 @@ const HMapHeader &HeaderMapImpl::getHeader() const {
/// bswap'ing its fields as appropriate. If the bucket number is not valid,
/// this return a bucket with an empty key (0).
HMapBucket HeaderMapImpl::getBucket(unsigned BucketNo) const {
+ assert(FileBuffer->getBufferSize() >=
+ sizeof(HMapHeader) + sizeof(HMapBucket) * BucketNo &&
+ "Expected bucket to be in range");
+
HMapBucket Result;
Result.Key = HMAP_EmptyBucketKey;
const HMapBucket *BucketArray =
reinterpret_cast<const HMapBucket*>(FileBuffer->getBufferStart() +
sizeof(HMapHeader));
-
const HMapBucket *BucketPtr = BucketArray+BucketNo;
- if ((const char*)(BucketPtr+1) > FileBuffer->getBufferEnd()) {
- Result.Prefix = 0;
- Result.Suffix = 0;
- return Result; // Invalid buffer, corrupt hmap.
- }
- // Otherwise, the bucket is valid. Load the values, bswapping as needed.
+ // Load the values, bswapping as needed.
Result.Key = getEndianAdjustedWord(BucketPtr->Key);
Result.Prefix = getEndianAdjustedWord(BucketPtr->Prefix);
Result.Suffix = getEndianAdjustedWord(BucketPtr->Suffix);