mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[serialization] Fix potential fall-off-the-end issues.
The way llvm::BitstreamCursor works is that reading an end-of-block code will pop the current block off the stack, along with all its record abbreviation codes. This means we’d no longer know how to read any records. Fix this by telling the cursor not to auto-pop blocks any time we’re doing a tentative read. Swift SVN r6135
This commit is contained in:
@@ -18,6 +18,8 @@
|
||||
|
||||
using namespace swift;
|
||||
using namespace swift::serialization;
|
||||
static constexpr const auto AF_DontPopBlockAtEnd =
|
||||
llvm::BitstreamCursor::AF_DontPopBlockAtEnd;
|
||||
|
||||
static ModuleStatus
|
||||
validateControlBlock(llvm::BitstreamCursor &cursor,
|
||||
@@ -68,7 +70,7 @@ Pattern *ModuleFile::maybeReadPattern() {
|
||||
|
||||
SmallVector<uint64_t, 8> scratch;
|
||||
|
||||
auto next = DeclTypeCursor.advance();
|
||||
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (next.Kind != llvm::BitstreamEntry::Record)
|
||||
return nullptr;
|
||||
|
||||
@@ -170,7 +172,7 @@ ProtocolConformance *ModuleFile::maybeReadConformance() {
|
||||
BCOffsetRAII lastRecordOffset(DeclTypeCursor);
|
||||
SmallVector<uint64_t, 8> scratch;
|
||||
|
||||
auto next = DeclTypeCursor.advance();
|
||||
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (next.Kind != llvm::BitstreamEntry::Record)
|
||||
return nullptr;
|
||||
|
||||
@@ -229,7 +231,7 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {
|
||||
SmallVector<uint64_t, 8> scratch;
|
||||
StringRef blobData;
|
||||
|
||||
auto next = DeclTypeCursor.advance();
|
||||
auto next = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (next.Kind != llvm::BitstreamEntry::Record)
|
||||
return nullptr;
|
||||
|
||||
@@ -254,7 +256,7 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {
|
||||
lastRecordOffset.reset();
|
||||
bool shouldContinue = true;
|
||||
|
||||
auto entry = DeclTypeCursor.advance();
|
||||
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
|
||||
@@ -888,7 +890,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
theClass->setConformances(ctx.AllocateCopy(conformanceBuf));
|
||||
|
||||
auto members = readMembers();
|
||||
assert(members.hasValue() && "could not read struct members");
|
||||
assert(members.hasValue() && "could not read class members");
|
||||
theClass->setMembers(members.getValue(), SourceRange());
|
||||
|
||||
break;
|
||||
@@ -1115,7 +1117,7 @@ Type ModuleFile::getType(TypeID TID) {
|
||||
// The tuple record itself is empty. Read all trailing elements.
|
||||
SmallVector<TupleTypeElt, 8> elements;
|
||||
while (true) {
|
||||
auto entry = DeclTypeCursor.advance();
|
||||
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
|
||||
@@ -1328,7 +1330,7 @@ Type ModuleFile::getType(TypeID TID) {
|
||||
|
||||
SmallVector<Substitution, 8> substitutions;
|
||||
while (true) {
|
||||
auto entry = DeclTypeCursor.advance();
|
||||
auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd);
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record)
|
||||
break;
|
||||
|
||||
@@ -1622,7 +1624,7 @@ ModuleFile::ModuleFile(llvm::OwningPtr<llvm::MemoryBuffer> &&input)
|
||||
break;
|
||||
}
|
||||
|
||||
topLevelEntry = cursor.advance(llvm::BitstreamCursor::AF_DontPopBlockAtEnd);
|
||||
topLevelEntry = cursor.advance(AF_DontPopBlockAtEnd);
|
||||
}
|
||||
|
||||
if (topLevelEntry.Kind != llvm::BitstreamEntry::EndBlock)
|
||||
|
||||
Reference in New Issue
Block a user