@@ -172,12 +172,14 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
172
172
static ValidationInfo validateControlBlock (
173
173
llvm::BitstreamCursor &cursor, SmallVectorImpl<uint64_t > &scratch,
174
174
std::pair<uint16_t , uint16_t > expectedVersion, bool requiresOSSAModules,
175
+ bool requiresRevisionMatch,
175
176
ExtendedValidationInfo *extendedInfo,
176
177
PathObfuscator &pathRecoverer) {
177
178
// The control block is malformed until we've at least read a major version
178
179
// number.
179
180
ValidationInfo result;
180
181
bool versionSeen = false ;
182
+ bool revisionSeen = false ;
181
183
182
184
while (!cursor.AtEndOfStream ()) {
183
185
Expected<llvm::BitstreamEntry> maybeEntry = cursor.advance ();
@@ -308,6 +310,8 @@ static ValidationInfo validateControlBlock(
308
310
break ;
309
311
}
310
312
case control_block::REVISION: {
313
+ revisionSeen = true ;
314
+
311
315
// Tagged compilers should only load modules if they were
312
316
// produced by the exact same compiler tag.
313
317
@@ -331,8 +335,12 @@ static ValidationInfo validateControlBlock(
331
335
if (isCompilerTagged) {
332
336
StringRef compilerRevision = forcedDebugRevision ?
333
337
forcedDebugRevision : version::getSwiftRevision ();
334
- if (moduleRevision != compilerRevision)
338
+ if (moduleRevision != compilerRevision) {
335
339
result.status = Status::RevisionIncompatible;
340
+
341
+ // We can't trust this module format at this point.
342
+ return result;
343
+ }
336
344
}
337
345
break ;
338
346
}
@@ -349,6 +357,13 @@ static ValidationInfo validateControlBlock(
349
357
}
350
358
}
351
359
360
+ // Last resort check in cases where the format is broken enough that
361
+ // we didn't read the REVISION block, report such a case as incompatible.
362
+ if (requiresRevisionMatch &&
363
+ !revisionSeen &&
364
+ result.status == Status::Valid)
365
+ result.status = Status::RevisionIncompatible;
366
+
352
367
return result;
353
368
}
354
369
@@ -471,7 +486,8 @@ ValidationInfo serialization::validateSerializedAST(
471
486
result = validateControlBlock (
472
487
cursor, scratch,
473
488
{SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR},
474
- requiresOSSAModules, extendedInfo, localObfuscator);
489
+ requiresOSSAModules, /* requiresRevisionMatch=*/ true ,
490
+ extendedInfo, localObfuscator);
475
491
if (result.status == Status::Malformed)
476
492
return result;
477
493
} else if (dependencies &&
@@ -979,7 +995,7 @@ bool ModuleFileSharedCore::readModuleDocIfPresent(PathObfuscator &pathRecoverer)
979
995
980
996
info = validateControlBlock (
981
997
docCursor, scratch, {SWIFTDOC_VERSION_MAJOR, SWIFTDOC_VERSION_MINOR},
982
- RequiresOSSAModules,
998
+ RequiresOSSAModules, /* requiresRevisionMatch= */ false ,
983
999
/* extendedInfo*/ nullptr , pathRecoverer);
984
1000
if (info.status != Status::Valid)
985
1001
return false ;
@@ -1123,7 +1139,7 @@ bool ModuleFileSharedCore::readModuleSourceInfoIfPresent(PathObfuscator &pathRec
1123
1139
info = validateControlBlock (
1124
1140
infoCursor, scratch,
1125
1141
{SWIFTSOURCEINFO_VERSION_MAJOR, SWIFTSOURCEINFO_VERSION_MINOR},
1126
- RequiresOSSAModules,
1142
+ RequiresOSSAModules, /* requiresRevisionMatch= */ false ,
1127
1143
/* extendedInfo*/ nullptr ,
1128
1144
pathRecoverer);
1129
1145
if (info.status != Status::Valid)
@@ -1251,7 +1267,8 @@ ModuleFileSharedCore::ModuleFileSharedCore(
1251
1267
info = validateControlBlock (
1252
1268
cursor, scratch,
1253
1269
{SWIFTMODULE_VERSION_MAJOR, SWIFTMODULE_VERSION_MINOR},
1254
- RequiresOSSAModules, &extInfo, pathRecoverer);
1270
+ RequiresOSSAModules, /* requiresRevisionMatch=*/ true ,
1271
+ &extInfo, pathRecoverer);
1255
1272
if (info.status != Status::Valid) {
1256
1273
error (info.status );
1257
1274
return ;
0 commit comments