In MemoryBuffer::getOpenFile() make sure that the buffer is null-terminated if

the caller requested a null-terminated one.

When mapping the file there could be a racing issue that resulted in the file being larger
than the FileSize passed by the caller. We already have an assertion
for this in MemoryBuffer::init() but have a runtime guarantee that
the buffer will be null-terminated, so do a copy that adds a null-terminator.

Protects against crash of rdar://11161822.

llvm-svn: 154082
This commit is contained in:
Argyrios Kyrtzidis 2012-04-05 04:23:56 +00:00
parent 64f4e8d5b3
commit f5736f87f2

View File

@ -304,6 +304,16 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
RealMapOffset)) { RealMapOffset)) {
result.reset(GetNamedBuffer<MemoryBufferMMapFile>( result.reset(GetNamedBuffer<MemoryBufferMMapFile>(
StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator)); StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator));
if (RequiresNullTerminator && result->getBufferEnd()[0] != '\0') {
// There could be a racing issue that resulted in the file being larger
// than the FileSize passed by the caller. We already have an assertion
// for this in MemoryBuffer::init() but have a runtime guarantee that
// the buffer will be null-terminated here, so do a copy that adds a
// null-terminator.
result.reset(MemoryBuffer::getMemBufferCopy(result->getBuffer(),
Filename));
}
return error_code::success(); return error_code::success();
} }
} }
@ -339,6 +349,7 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
if (NumRead == 0) { if (NumRead == 0) {
assert(0 && "We got inaccurate FileSize value or fstat reported an " assert(0 && "We got inaccurate FileSize value or fstat reported an "
"invalid file size."); "invalid file size.");
*BufPtr = '\0'; // null-terminate at the actual size.
break; break;
} }
BytesLeft -= NumRead; BytesLeft -= NumRead;