Skip to content

Commit 864bf89

Browse files
authored
[ClangImporter] Handle lookup tables with many entries (#17265)
In particular, there are frameworks with more than 65536 entries for 'init' as a base name. I can't think of a test case for this besides actually adding such a massive framework, but the assertions that were added here should catch the issue in Debug builds if it ever comes up again. I'm going to go harden everything else that uses this API next. rdar://problem/40828315
1 parent fb541ad commit 864bf89

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ namespace {
961961
if (key.Kind == DeclBaseName::Kind::Normal) {
962962
keyLength += key.Name.size(); // The name's length
963963
}
964+
assert(keyLength == static_cast<uint16_t>(keyLength));
964965

965966
// # of entries
966967
uint32_t dataLength = sizeof(uint16_t);
@@ -982,7 +983,7 @@ namespace {
982983

983984
endian::Writer<little> writer(out);
984985
writer.write<uint16_t>(keyLength);
985-
writer.write<uint16_t>(dataLength);
986+
writer.write<uint32_t>(dataLength);
986987
return { keyLength, dataLength };
987988
}
988989

@@ -1067,10 +1068,12 @@ namespace {
10671068
uint32_t keyLength = 1;
10681069
if (SwiftLookupTable::contextRequiresName(key.first))
10691070
keyLength += key.second.size();
1071+
assert(keyLength == static_cast<uint16_t>(keyLength));
10701072

10711073
// # of entries
10721074
uint32_t dataLength =
10731075
sizeof(uint16_t) + sizeof(uint64_t) * data.size();
1076+
assert(dataLength == static_cast<uint16_t>(dataLength));
10741077

10751078
endian::Writer<little> writer(out);
10761079
writer.write<uint16_t>(keyLength);
@@ -1226,7 +1229,7 @@ namespace {
12261229
static std::pair<unsigned, unsigned>
12271230
ReadKeyDataLength(const uint8_t *&data) {
12281231
unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
1229-
unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
1232+
unsigned dataLength = endian::readNext<uint32_t, little, unaligned>(data);
12301233
return { keyLength, dataLength };
12311234
}
12321235

0 commit comments

Comments
 (0)