mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-19 03:25:54 -04:00
[clang] Fix out-of-bounds memory access in ComputeLineNumbers
Differential Revision: https://reviews.llvm.org/D72409
This commit is contained in:
parent
815a3f5433
commit
f28972facc
@ -1250,23 +1250,18 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
|
||||
|
||||
const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
|
||||
const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
|
||||
const std::size_t BufLen = End - Buf;
|
||||
unsigned I = 0;
|
||||
while (true) {
|
||||
// Skip over the contents of the line.
|
||||
while (Buf[I] != '\n' && Buf[I] != '\r' && Buf[I] != '\0')
|
||||
++I;
|
||||
|
||||
if (Buf[I] == '\n' || Buf[I] == '\r') {
|
||||
while (I < BufLen) {
|
||||
if (Buf[I] == '\n') {
|
||||
LineOffsets.push_back(I + 1);
|
||||
} else if (Buf[I] == '\r') {
|
||||
// If this is \r\n, skip both characters.
|
||||
if (Buf[I] == '\r' && Buf[I+1] == '\n')
|
||||
if (I + 1 < BufLen && Buf[I + 1] == '\n')
|
||||
++I;
|
||||
++I;
|
||||
LineOffsets.push_back(I);
|
||||
} else {
|
||||
// Otherwise, this is a NUL. If end of file, exit.
|
||||
if (Buf+I == End) break;
|
||||
++I;
|
||||
LineOffsets.push_back(I + 1);
|
||||
}
|
||||
++I;
|
||||
}
|
||||
|
||||
// Copy the offsets into the FileInfo structure.
|
||||
|
@ -20,7 +20,9 @@
|
||||
#include "clang/Lex/PreprocessorOptions.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <cstddef>
|
||||
|
||||
using namespace clang;
|
||||
|
||||
@ -241,6 +243,28 @@ TEST_F(SourceManagerTest, getInvalidBOM) {
|
||||
"UTF-32 (LE)");
|
||||
}
|
||||
|
||||
// Regression test - there was an out of bound access for buffers not terminated by zero.
|
||||
TEST_F(SourceManagerTest, getLineNumber) {
|
||||
const unsigned pageSize = llvm::sys::Process::getPageSizeEstimate();
|
||||
std::unique_ptr<char[]> source(new char[pageSize]);
|
||||
for(unsigned i = 0; i < pageSize; ++i) {
|
||||
source[i] = 'a';
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> Buf =
|
||||
llvm::MemoryBuffer::getMemBuffer(
|
||||
llvm::MemoryBufferRef(
|
||||
llvm::StringRef(source.get(), 3), "whatever"
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
FileID mainFileID = SourceMgr.createFileID(std::move(Buf));
|
||||
SourceMgr.setMainFileID(mainFileID);
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(SourceMgr.getLineNumber(mainFileID, 1, nullptr));
|
||||
}
|
||||
|
||||
#if defined(LLVM_ON_UNIX)
|
||||
|
||||
TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
|
||||
|
Loading…
Reference in New Issue
Block a user