mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[serialization] Validate the control block -- is the module too new?
Not so interesting right now, but eventually we'll be validating other things as well, and it's best not to have FIXMEs lying around. Swift SVN r5175
This commit is contained in:
@@ -15,6 +15,51 @@
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
using namespace swift;
|
||||
using namespace swift::serialization;
|
||||
|
||||
static ModuleStatus
|
||||
validateControlBlock(llvm::BitstreamCursor &cursor,
|
||||
llvm::SmallVectorImpl<uint64_t> &scratch) {
|
||||
// The control block is malformed until we've at least read a major version
|
||||
// number.
|
||||
ModuleStatus result = ModuleStatus::Malformed;
|
||||
|
||||
auto next = cursor.advance();
|
||||
while (next.Kind != llvm::BitstreamEntry::EndBlock) {
|
||||
if (next.Kind == llvm::BitstreamEntry::Error)
|
||||
return ModuleStatus::Malformed;
|
||||
|
||||
if (next.Kind == llvm::BitstreamEntry::SubBlock) {
|
||||
// Unknown metadata sub-block, possibly for use by a future version of the
|
||||
// module format.
|
||||
if (cursor.SkipBlock())
|
||||
return ModuleStatus::Malformed;
|
||||
next = cursor.advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
scratch.clear();
|
||||
StringRef blobData;
|
||||
unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
|
||||
switch (kind) {
|
||||
case control_block::METADATA: {
|
||||
uint16_t versionMajor = scratch[0];
|
||||
if (versionMajor > VERSION_MAJOR)
|
||||
return ModuleStatus::FormatTooNew;
|
||||
result = ModuleStatus::Valid;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Unknown metadata record, possibly for use by a future version of the
|
||||
// module format.
|
||||
break;
|
||||
}
|
||||
|
||||
next = cursor.advance();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ModuleFile::ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input)
|
||||
: InputFile(std::move(input)),
|
||||
@@ -23,7 +68,6 @@ ModuleFile::ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input)
|
||||
Status(ModuleStatus::FallBackToTranslationUnit) {
|
||||
llvm::BitstreamCursor cursor{InputReader};
|
||||
|
||||
using namespace serialization;
|
||||
for (unsigned char byte : SIGNATURE) {
|
||||
if (cursor.AtEndOfStream() || cursor.Read(8) != byte)
|
||||
return error();
|
||||
@@ -42,12 +86,16 @@ ModuleFile::ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input)
|
||||
return error();
|
||||
break;
|
||||
|
||||
case CONTROL_BLOCK_ID:
|
||||
// FIXME: Actually validate the control block.
|
||||
if (cursor.SkipBlock())
|
||||
return error();
|
||||
case CONTROL_BLOCK_ID: {
|
||||
cursor.EnterSubBlock(CONTROL_BLOCK_ID);
|
||||
|
||||
ModuleStatus err = validateControlBlock(cursor, scratch);
|
||||
if (err != ModuleStatus::Valid)
|
||||
return error(err);
|
||||
|
||||
hasValidControlBlock = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case INPUT_BLOCK_ID: {
|
||||
if (!hasValidControlBlock)
|
||||
|
||||
Reference in New Issue
Block a user