MCPcopy Create free account
hub / github.com/KhronosGroup/KTX-Software / validateKVD

Method validateKVD

tools/ktx/validate.cpp:1274–1418  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1272}
1273
1274void ValidationContext::validateKVD() {
1275 const auto kvdByteOffset = header.keyValueData.byteOffset;
1276 const auto kvdByteLength = header.keyValueData.byteLength;
1277
1278 if (kvdByteOffset == 0 || kvdByteLength == 0)
1279 return; // There is no KVD block
1280
1281 const auto buffer = std::make_unique<uint8_t[]>(kvdByteLength);
1282 read(kvdByteOffset, buffer.get(), kvdByteLength, "the Key/Value Data");
1283 const auto* ptrKVD = buffer.get();
1284 const auto* ptrKVDEnd = ptrKVD + kvdByteLength;
1285
1286 struct KeyValueEntry {
1287 std::string key;
1288 const uint8_t* data;
1289 uint32_t size;
1290
1291 KeyValueEntry(std::string_view key, const uint8_t* data, uint32_t size) :
1292 key(key), data(data), size(size) {}
1293 };
1294 std::vector<KeyValueEntry> entries;
1295 std::unordered_set<std::string_view> keys;
1296
1297 uint32_t numKVEntry = 0;
1298 // Process Key-Value entries {size, key, \0, value} until the end of the KVD block
1299 // Where size is an uint32_t, and it equals to: sizeof(key) + 1 + sizeof(value)
1300 const auto* ptrEntry = ptrKVD;
1301 while (ptrEntry < ptrKVDEnd) {
1302 const auto remainingKVDBytes = ptrKVDEnd - ptrEntry;
1303
1304 if (++numKVEntry > MAX_NUM_KV_ENTRIES) {
1305 warning(Metadata::TooManyEntries, numKVEntry - 1, remainingKVDBytes);
1306 ptrEntry = ptrKVDEnd;
1307 break;
1308 }
1309
1310 if (remainingKVDBytes < 6) {
1311 error(Metadata::NotEnoughDataForAnEntry, remainingKVDBytes);
1312 ptrEntry = ptrKVDEnd;
1313 break;
1314 }
1315
1316 uint32_t sizeKeyValuePair;
1317 std::memcpy(&sizeKeyValuePair, ptrEntry, sizeof(uint32_t));
1318
1319 const auto* ptrKeyValuePair = ptrEntry + sizeof(uint32_t);
1320 const auto* ptrKey = ptrKeyValuePair;
1321
1322 if (sizeKeyValuePair < 2) {
1323 error(Metadata::KeyAndValueByteLengthTooSmall, sizeKeyValuePair);
1324 } else {
1325 if (ptrKeyValuePair + sizeKeyValuePair > ptrKVDEnd) {
1326 const auto bytesLeft = ptrKVDEnd - ptrKeyValuePair;
1327 error(Metadata::KeyAndValueByteLengthTooLarge, sizeKeyValuePair, bytesLeft);
1328 sizeKeyValuePair = static_cast<uint32_t>(bytesLeft); // Attempt recovery to read out at least the key
1329 }
1330
1331 // Determine key, finding the null terminator

Callers

nothing calls this directly

Calls 10

warningFunction · 0.85
errorFunction · 0.85
validateUTF8Function · 0.85
is_sortedFunction · 0.85
starts_withFunction · 0.70
alignFunction · 0.70
readFunction · 0.50
getMethod · 0.45
findMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected