Skip to content

Commit 570ed72

Browse files
authored
Add assertions to prevent truncation when using llvm::endian::Writer (#17266)
Also, stop serializing a few constant values, saving a tiny bit of space in swiftmodule files.
1 parent 7b91682 commit 570ed72

File tree

5 files changed

+17
-9
lines changed

5 files changed

+17
-9
lines changed

lib/ClangImporter/SwiftLookupTable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,7 @@ namespace {
999999

10001000
// # of entries
10011001
writer.write<uint16_t>(data.size());
1002+
assert(data.size() == static_cast<uint16_t>(data.size()));
10021003

10031004
bool isModule = Writer.getLangOpts().isCompilingModule();
10041005
for (auto &fullEntry : data) {

lib/Serialization/DeserializeSIL.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,7 @@ class SILDeserializer::FuncTableInfo {
111111

112112
static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
113113
unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
114-
unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
115-
return { keyLength, dataLength };
114+
return { keyLength, sizeof(uint32_t) };
116115
}
117116

118117
static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
@@ -121,7 +120,7 @@ class SILDeserializer::FuncTableInfo {
121120

122121
static data_type ReadData(internal_key_type key, const uint8_t *data,
123122
unsigned length) {
124-
assert(length == 4 && "Expect a single DeclID.");
123+
assert(length == sizeof(uint32_t) && "Expect a single DeclID.");
125124
data_type result = endian::readNext<uint32_t, little, unaligned>(data);
126125
return result;
127126
}

lib/Serialization/ModuleFile.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,8 @@ class ModuleFile::DeclMembersTableInfo {
594594
}
595595

596596
static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
597-
unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
598597
unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
599-
return { keyLength, dataLength };
598+
return { sizeof(uint32_t), dataLength };
600599
}
601600

602601
static internal_key_type ReadKey(const uint8_t *data, unsigned length) {

lib/Serialization/Serialization.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,11 @@ namespace {
118118
if (key.getKind() == DeclBaseName::Kind::Normal) {
119119
keyLength += key.getIdentifier().str().size(); // The name's length
120120
}
121+
assert(keyLength == static_cast<uint16_t>(keyLength));
121122

122123
uint32_t dataLength = (sizeof(uint32_t) + 1) * data.size();
124+
assert(dataLength == static_cast<uint16_t>(dataLength));
125+
123126
endian::Writer<little> writer(out);
124127
writer.write<uint16_t>(keyLength);
125128
writer.write<uint16_t>(dataLength);
@@ -195,12 +198,14 @@ namespace {
195198
key_type_ref key,
196199
data_type_ref data) {
197200
uint32_t keyLength = key.str().size();
201+
assert(keyLength == static_cast<uint16_t>(keyLength));
198202
uint32_t dataLength = (sizeof(uint32_t) * 2) * data.size();
199203
for (auto dataPair : data) {
200204
int32_t nameData = getNameDataForBase(dataPair.first);
201205
if (nameData > 0)
202206
dataLength += nameData;
203207
}
208+
assert(dataLength == static_cast<uint16_t>(dataLength));
204209
endian::Writer<little> writer(out);
205210
writer.write<uint16_t>(keyLength);
206211
writer.write<uint16_t>(dataLength);
@@ -242,9 +247,11 @@ namespace {
242247
key_type_ref key,
243248
data_type_ref data) {
244249
uint32_t keyLength = key.size();
250+
assert(keyLength == static_cast<uint16_t>(keyLength));
245251
uint32_t dataLength = sizeof(uint32_t);
246252
endian::Writer<little> writer(out);
247253
writer.write<uint16_t>(keyLength);
254+
// No need to write the data length; it's constant.
248255
return { keyLength, dataLength };
249256
}
250257

@@ -281,7 +288,9 @@ namespace {
281288
key_type_ref key,
282289
data_type_ref data) {
283290
uint32_t keyLength = key.str().size();
291+
assert(keyLength == static_cast<uint16_t>(keyLength));
284292
uint32_t dataLength = (sizeof(uint32_t) * 2) * data.size();
293+
assert(dataLength == static_cast<uint16_t>(dataLength));
285294
endian::Writer<little> writer(out);
286295
writer.write<uint16_t>(keyLength);
287296
writer.write<uint16_t>(dataLength);
@@ -334,6 +343,7 @@ namespace {
334343
if (key.getKind() == DeclBaseName::Kind::Normal) {
335344
keyLength += key.getIdentifier().str().size(); // The name's length
336345
}
346+
assert(keyLength == static_cast<uint16_t>(keyLength));
337347
uint32_t dataLength = sizeof(uint32_t);
338348
endian::Writer<little> writer(out);
339349
writer.write<uint16_t>(keyLength);
@@ -387,12 +397,11 @@ namespace {
387397
// This will trap if a single ValueDecl has more than 16383 members
388398
// with the same DeclBaseName. Seems highly unlikely.
389399
assert((data.size() < (1 << 14)) && "Too many members");
390-
uint32_t keyLength = sizeof(uint32_t); // key DeclID
391400
uint32_t dataLength = sizeof(uint32_t) * data.size(); // value DeclIDs
392401
endian::Writer<little> writer(out);
393-
writer.write<uint16_t>(keyLength);
402+
// No need to write the key length; it's constant.
394403
writer.write<uint16_t>(dataLength);
395-
return { keyLength, dataLength };
404+
return { sizeof(uint32_t), dataLength };
396405
}
397406

398407
void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {

lib/Serialization/SerializeSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ namespace {
121121
uint32_t dataLength = sizeof(uint32_t);
122122
endian::Writer<little> writer(out);
123123
writer.write<uint16_t>(keyLength);
124-
writer.write<uint16_t>(dataLength);
124+
// No need to write the data length; it's constant.
125125
return { keyLength, dataLength };
126126
}
127127

0 commit comments

Comments
 (0)