diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-02-21 00:14:36 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-02-21 00:14:36 +0000 |
commit | 96a01fa04671d7c554007d256294f4ddd96d3eee (patch) | |
tree | 866023e74213cde3ce35aef41cf94a21222803f6 /clang/lib/Lex/HeaderMap.cpp | |
parent | 471efd244a7f970948cb0d189ec41d1840e9607b (diff) | |
download | bcm5719-llvm-96a01fa04671d7c554007d256294f4ddd96d3eee.tar.gz bcm5719-llvm-96a01fa04671d7c554007d256294f4ddd96d3eee.zip |
Lex: Never overflow the file in HeaderMap::lookupFilename()
If a header map file is corrupt, the strings in the string table may not
be null-terminated. The logic here previously relied on `MemoryBuffer`
always being null-terminated, but this isn't actually guaranteed by the
class AFAICT. Moreover, we're seeing a lot of crash traces at calls to
`strlen()` inside of `lookupFilename()`, so something is going wrong
there.
Instead, use `strnlen()` to get the length, and check for corruption.
Also remove code paths that could call `StringRef(nullptr)`. r261459
made these rather obvious (although they'd been there all along).
llvm-svn: 261461
Diffstat (limited to 'clang/lib/Lex/HeaderMap.cpp')
-rw-r--r-- | clang/lib/Lex/HeaderMap.cpp | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp index afa2631ac5b..67b663158f0 100644 --- a/clang/lib/Lex/HeaderMap.cpp +++ b/clang/lib/Lex/HeaderMap.cpp @@ -21,6 +21,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/Debug.h" +#include <cstring> #include <memory> using namespace clang; @@ -151,12 +152,17 @@ StringRef HeaderMapImpl::getString(unsigned StrTabIdx) const { // Check for invalid index. if (StrTabIdx >= FileBuffer->getBufferSize()) - return nullptr; + return ""; + + const char *Data = FileBuffer->getBufferStart() + StrTabIdx; + unsigned MaxLen = FileBuffer->getBufferSize() - StrTabIdx; + unsigned Len = strnlen(Data, MaxLen); + + // Check whether the buffer is null-terminated. + if (Len == MaxLen && Data[Len - 1]) + return ""; - // Otherwise, we have a valid pointer into the file. Just return it. We know - // that the "string" can not overrun the end of the file, because the buffer - // is nul terminated by virtue of being a MemoryBuffer. - return FileBuffer->getBufferStart()+StrTabIdx; + return StringRef(Data, Len); } //===----------------------------------------------------------------------===// |