lib/nbt: Make constructor NBT::Tag::Compound::Compound(name, data) private
The constructor has been made private and replaced with a static wrapper function to make constructing from invalid data impossible. If there is more than one end tag or an end tag isn’t at the end, an error will be returned.windows
parent
bc2255de6b
commit
60a8ac9788
|
@ -976,6 +976,20 @@ namespace NBT {
|
||||||
this->endPointer = new End();
|
this->endPointer = new End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<Compound*> Compound::constructWithData(tiny_utf8::string name, std::vector<Generic*> data) {
|
||||||
|
if (data.size() > 0) {
|
||||||
|
for (uint64_t i=0; i<data.size(); i++) {
|
||||||
|
if (data[i]->getTagType() == TagType::END && i != data.size()-1) {
|
||||||
|
return ErrorOr<Compound*>(true, ErrorCodes::NOT_ALLOWED, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data[data.size()-1]->getTagType() == TagType::END) {
|
||||||
|
return ErrorOr<Compound*>(new Compound(name, std::vector(data.begin(), data.end()-1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ErrorOr<Compound*>(new Compound(name, data));
|
||||||
|
}
|
||||||
|
|
||||||
Compound::~Compound() {
|
Compound::~Compound() {
|
||||||
for (uint64_t i=0; i<this->tags.size(); i++) {
|
for (uint64_t i=0; i<this->tags.size(); i++) {
|
||||||
delete this->tags.at(i);
|
delete this->tags.at(i);
|
||||||
|
@ -1342,7 +1356,7 @@ namespace NBT {
|
||||||
returnValue = ErrorOr<std::vector<Tag::Generic*>>(true, nextCompoundData.errorCode);
|
returnValue = ErrorOr<std::vector<Tag::Generic*>>(true, nextCompoundData.errorCode);
|
||||||
goto returnError;
|
goto returnError;
|
||||||
}
|
}
|
||||||
contents.push_back(new Tag::Compound("", nextCompoundData.value));
|
contents.push_back(reinterpret_cast<Tag::Generic*>(Tag::Compound::constructWithData("", nextCompoundData.value).value));
|
||||||
*processedDataSize += *containedDataSize;
|
*processedDataSize += *containedDataSize;
|
||||||
}
|
}
|
||||||
delete containedDataSize;
|
delete containedDataSize;
|
||||||
|
@ -1454,7 +1468,7 @@ namespace NBT {
|
||||||
returnValue = ErrorOr<std::vector<Tag::Generic*>>(true, compoundData.errorCode);
|
returnValue = ErrorOr<std::vector<Tag::Generic*>>(true, compoundData.errorCode);
|
||||||
goto returnNow;
|
goto returnNow;
|
||||||
}
|
}
|
||||||
tags.push_back(new Tag::Compound(tagName.value, compoundData.value));
|
tags.push_back(reinterpret_cast<Tag::Generic*>(Tag::Compound::constructWithData(tagName.value, compoundData.value).value));
|
||||||
*processedTagSize += (uint64_t) nameSize + 3;
|
*processedTagSize += (uint64_t) nameSize + 3;
|
||||||
}
|
}
|
||||||
currentPosition += *processedTagSize;
|
currentPosition += *processedTagSize;
|
||||||
|
|
|
@ -248,10 +248,10 @@ namespace NBT {
|
||||||
std::vector<Generic*> tags;
|
std::vector<Generic*> tags;
|
||||||
// built-in end tag
|
// built-in end tag
|
||||||
End* endPointer;
|
End* endPointer;
|
||||||
|
Compound(tiny_utf8::string name, std::vector<Generic*> data);
|
||||||
public:
|
public:
|
||||||
Compound();
|
Compound();
|
||||||
Compound(tiny_utf8::string name);
|
Compound(tiny_utf8::string name);
|
||||||
Compound(tiny_utf8::string name, std::vector<Generic*> data);
|
|
||||||
|
|
||||||
~Compound() override;
|
~Compound() override;
|
||||||
|
|
||||||
|
@ -262,6 +262,7 @@ namespace NBT {
|
||||||
ErrorOrVoid appendPointer(Generic* pointer);
|
ErrorOrVoid appendPointer(Generic* pointer);
|
||||||
ErrorOrVoid deleteElement(uint64_t position);
|
ErrorOrVoid deleteElement(uint64_t position);
|
||||||
uint64_t length();
|
uint64_t length();
|
||||||
|
static ErrorOr<Compound*> constructWithData(tiny_utf8::string name, std::vector<Generic*> data);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Int32Array: public Generic {
|
class Int32Array: public Generic {
|
||||||
|
|
|
@ -890,7 +890,11 @@ int main(){
|
||||||
NBT::Tag::Compound compound_0 = NBT::Tag::Compound();
|
NBT::Tag::Compound compound_0 = NBT::Tag::Compound();
|
||||||
compound_0.name = "compound_0";
|
compound_0.name = "compound_0";
|
||||||
NBT::Tag::Compound compound_1 = NBT::Tag::Compound("compound_1");
|
NBT::Tag::Compound compound_1 = NBT::Tag::Compound("compound_1");
|
||||||
NBT::Tag::Compound compound_2 = NBT::Tag::Compound("compound_2", compoundDataVector);
|
//TODO: Check that constructing with a vector containing an end tag that
|
||||||
|
// isn’t at the end results in a clearly defined failure mode (issue #60)
|
||||||
|
ErrorOr<NBT::Tag::Compound*> compound_2_or_error = NBT::Tag::Compound::constructWithData("compound_2", compoundDataVector);
|
||||||
|
ASSERT(!compound_2_or_error.isError);
|
||||||
|
NBT::Tag::Compound* compound_2 = compound_2_or_error.value;
|
||||||
|
|
||||||
ASSERT(!compound_1.appendPointer(new NBT::Tag::Int32("0", 69420)).isError);
|
ASSERT(!compound_1.appendPointer(new NBT::Tag::Int32("0", 69420)).isError);
|
||||||
ASSERT(!compound_1.appendPointer(new NBT::Tag::Int8("1", 1)).isError);
|
ASSERT(!compound_1.appendPointer(new NBT::Tag::Int8("1", 1)).isError);
|
||||||
|
@ -906,15 +910,15 @@ int main(){
|
||||||
resultNotAllowed = compound_1.setElementPointerAt(0, new NBT::Tag::End());
|
resultNotAllowed = compound_1.setElementPointerAt(0, new NBT::Tag::End());
|
||||||
ASSERT(resultNotAllowed.isError && resultNotAllowed.errorCode==ErrorCodes::NOT_ALLOWED);
|
ASSERT(resultNotAllowed.isError && resultNotAllowed.errorCode==ErrorCodes::NOT_ALLOWED);
|
||||||
ASSERT(compound_0.setElementPointerAt(1, new NBT::Tag::Int8()).isError && compound_0.setElementPointerAt(1, new NBT::Tag::Int8()).errorCode == ErrorCodes::OUT_OF_RANGE);
|
ASSERT(compound_0.setElementPointerAt(1, new NBT::Tag::Int8()).isError && compound_0.setElementPointerAt(1, new NBT::Tag::Int8()).errorCode == ErrorCodes::OUT_OF_RANGE);
|
||||||
ASSERT(!compound_2.deleteElement(1).isError);
|
ASSERT(!compound_2->deleteElement(1).isError);
|
||||||
ASSERT(compound_0.deleteElement(0).isError && compound_0.deleteElement(0).errorCode == ErrorCodes::NOT_ALLOWED);
|
ASSERT(compound_0.deleteElement(0).isError && compound_0.deleteElement(0).errorCode == ErrorCodes::NOT_ALLOWED);
|
||||||
ASSERT(compound_0.deleteElement(1).isError && compound_0.deleteElement(1).errorCode == ErrorCodes::OUT_OF_RANGE);
|
ASSERT(compound_0.deleteElement(1).isError && compound_0.deleteElement(1).errorCode == ErrorCodes::OUT_OF_RANGE);
|
||||||
ASSERT(compound_0.length() == 1);
|
ASSERT(compound_0.length() == 1);
|
||||||
ASSERT(compound_1.length() == 3);
|
ASSERT(compound_1.length() == 3);
|
||||||
ASSERT(compound_2.length() == 4);
|
ASSERT(compound_2->length() == 4);
|
||||||
compound_0.serialize(&vector);
|
compound_0.serialize(&vector);
|
||||||
compound_1.serialize(&vector);
|
compound_1.serialize(&vector);
|
||||||
compound_2.serialize(&vector);
|
compound_2->serialize(&vector);
|
||||||
ASSERT(vector.size() == 95);
|
ASSERT(vector.size() == 95);
|
||||||
ASSERT(
|
ASSERT(
|
||||||
vector.at( 0) == 10 &&
|
vector.at( 0) == 10 &&
|
||||||
|
@ -1016,7 +1020,7 @@ int main(){
|
||||||
vector.clear();
|
vector.clear();
|
||||||
compound_0.serializeWithoutHeader(&vector);
|
compound_0.serializeWithoutHeader(&vector);
|
||||||
compound_1.serializeWithoutHeader(&vector);
|
compound_1.serializeWithoutHeader(&vector);
|
||||||
compound_2.serializeWithoutHeader(&vector);
|
compound_2->serializeWithoutHeader(&vector);
|
||||||
ASSERT(vector.size() == 56);
|
ASSERT(vector.size() == 56);
|
||||||
ASSERT(
|
ASSERT(
|
||||||
vector.at( 0) == 0 &&
|
vector.at( 0) == 0 &&
|
||||||
|
|
Loading…
Reference in New Issue