lib/nbt: Fix NBT::validateRawNBTData() and NBT::validateRawListContents closing #52 and #53

Soda
BodgeMaster 2022-09-11 09:14:32 +02:00
parent 58b1199e38
commit aab91a2523
1 changed files with 23 additions and 18 deletions

View File

@ -595,18 +595,20 @@ namespace NBT {
} }
} }
bool validateRawList(uint8_t data[], uint64_t dataSize, uint64_t initialPosition, uint64_t* processedDataSize) { bool validateRawListContents(uint8_t data[], uint64_t dataSize, uint64_t initialPosition, uint64_t* processedDataSize) {
ErrorOr<int32_t> elementCount = helper::containedDataLength(data, dataSize, initialPosition); // get contained data length by reading it manually because
// the function that does it normally can't deal with
// headerless tags
//
// add one byte to position to skip the type byte
ErrorOr<int32_t> elementCount = helper::readInt32(data, dataSize, initialPosition+1);
if (elementCount.isError) { if (elementCount.isError) {
return false; return false;
} }
// there is no way this is an error bc it gets checked while trying
// to get the element count uint8_t contentType = data[initialPosition];
int16_t nameSize = helper::readInt16(data, dataSize, initialPosition+1).value; // contained type byte + 4 length bytes = 5
// type byte + two name size bytes = 3 *processedDataSize = 5;
uint8_t contentType = data[initialPosition + nameSize + 3];
// type byte + two name size bytes + contained type byte + 4 length bytes = 8
*processedDataSize = (uint64_t) nameSize + 8;
switch (contentType) { switch (contentType) {
case TagType::END: case TagType::END:
// everything except content has been touched at this point // everything except content has been touched at this point
@ -656,7 +658,8 @@ namespace NBT {
uint64_t* containedDataSize = new uint64_t; uint64_t* containedDataSize = new uint64_t;
for (int32_t i=0; i<elementCount.value; i++) { for (int32_t i=0; i<elementCount.value; i++) {
*containedDataSize = 0; *containedDataSize = 0;
if (validateRawList(data, dataSize, initialPosition+*processedDataSize, containedDataSize)) {
if (validateRawListContents(data, dataSize, initialPosition+*processedDataSize, containedDataSize)) {
*processedDataSize += *containedDataSize; *processedDataSize += *containedDataSize;
} else { } else {
delete containedDataSize; delete containedDataSize;
@ -670,7 +673,7 @@ namespace NBT {
uint64_t* containedDataSize = new uint64_t; uint64_t* containedDataSize = new uint64_t;
for (int32_t i=0; i<elementCount.value; i++) { for (int32_t i=0; i<elementCount.value; i++) {
*containedDataSize = 0; *containedDataSize = 0;
if (validateRawNBTData(data, dataSize, initialPosition, containedDataSize)) { if (validateRawNBTData(data, dataSize, initialPosition+*processedDataSize, containedDataSize)) {
*processedDataSize += *containedDataSize; *processedDataSize += *containedDataSize;
} else { } else {
delete containedDataSize; delete containedDataSize;
@ -743,22 +746,24 @@ namespace NBT {
return false; return false;
} }
uint64_t* processedTagSize = new uint64_t; // used seek to the start of the list's/compounds contents
*processedTagSize = 0;
if (data[currentPosition]==TagType::LIST) {
if (!validateRawList(data, dataSize, currentPosition, processedTagSize)) {
delete processedTagSize;
return false;
}
}
if (data[currentPosition]==TagType::COMPOUND) {
// seek to the start of the compound's contents
// //
// there is no way this is an error bc it gets // there is no way this is an error bc it gets
// checked while trying to parse the string above // checked while trying to parse the string above
int16_t nameSize = helper::readInt16(data, dataSize, currentPosition+1).value; int16_t nameSize = helper::readInt16(data, dataSize, currentPosition+1).value;
uint64_t* processedTagSize = new uint64_t;
*processedTagSize = 0;
if (data[currentPosition]==TagType::LIST) {
// type byte + two name size bytes = 3
if (!validateRawListContents(data, dataSize, currentPosition + (uint64_t) nameSize + 3, processedTagSize)) {
delete processedTagSize;
return false;
}
*processedTagSize += (uint64_t) nameSize + 3;
}
if (data[currentPosition]==TagType::COMPOUND) {
// type byte + two name size bytes = 3 // type byte + two name size bytes = 3
if (!validateRawNBTData(data, dataSize, currentPosition + (uint64_t) nameSize + 3, processedTagSize)) { if (!validateRawNBTData(data, dataSize, currentPosition + (uint64_t) nameSize + 3, processedTagSize)) {
delete processedTagSize; delete processedTagSize;