Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a few errors checks #119

Merged
merged 9 commits into from
Apr 22, 2021
7 changes: 7 additions & 0 deletions ZAPD/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@ bool Parse(const std::string& xmlFilePath, const std::string& basePath, const st
ZFile* file = new ZFile(fileMode, child, basePath, outPath, "", false);
Globals::Instance->files.push_back(file);
}
else
{
throw std::runtime_error(
StringHelper::Sprintf("Parse: Fatal error in '%s'.\n\t Found a resource outside of "
"a File element: '%s'\n",
xmlFilePath.c_str(), child->Name()));
}
}

for (ZFile* file : Globals::Instance->files)
Expand Down
1 change: 1 addition & 0 deletions ZAPD/ZArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ REGISTER_ZFILENODE(Array, ZArray);

ZArray::ZArray(ZFile* nParent) : ZResource(nParent)
{
canHaveInner = true;
}

void ZArray::ParseXML(tinyxml2::XMLElement* reader)
Expand Down
56 changes: 52 additions & 4 deletions ZAPD/ZFile.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "ZFile.h"
#include <algorithm>
#include <cassert>
#include <unordered_set>
#include "Directory.h"
#include "File.h"
#include "Globals.h"
Expand Down Expand Up @@ -124,18 +125,55 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
rawData = File::ReadAllBytes(basePath + "/" + name);
}

std::unordered_set<std::string> nameSet;
std::unordered_set<std::string> outNameSet;
std::unordered_set<std::string> offsetSet;

auto nodeMap = *GetNodeMap();
int rawDataIndex = 0;

for (XMLElement* child = reader->FirstChildElement(); child != NULL;
child = child->NextSiblingElement())
{
if (child->Attribute("Offset") != NULL)
rawDataIndex =
strtol(StringHelper::Split(child->Attribute("Offset"), "0x")[1].c_str(), NULL, 16);
const char* nameXml = child->Attribute("Name");
const char* outNameXml = child->Attribute("OutName");
const char* offsetXml = child->Attribute("Offset");

if (Globals::Instance->verbosity >= VERBOSITY_INFO)
printf("%s: 0x%06X\n", child->Attribute("Name"), rawDataIndex);
printf("%s: 0x%06X\n", nameXml, rawDataIndex);

if (offsetXml != NULL)
{
rawDataIndex = strtol(StringHelper::Split(offsetXml, "0x")[1].c_str(), NULL, 16);

if (offsetSet.find(offsetXml) != offsetSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Offset' attribute: %s \n",
name.c_str(), offsetXml));
}
offsetSet.insert(offsetXml);
}
if (outNameXml != NULL)
{
if (outNameSet.find(outNameXml) != outNameSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'OutName' attribute: %s \n",
name.c_str(), outNameXml));
}
outNameSet.insert(outNameXml);
}
if (nameXml != NULL)
{
if (nameSet.find(nameXml) != nameSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Name' attribute: %s \n",
name.c_str(), nameXml));
}
nameSet.insert(nameXml);
}

string nodeName = string(child->Name());

Expand Down Expand Up @@ -172,8 +210,18 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
resources.push_back(nRes);
rawDataIndex += nRes->GetRawDataSize();
}
else if (string(child->Name()) == "File")
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Can't declare a File inside a File.\n",
name.c_str()));
}
else
{
throw std::runtime_error(
StringHelper::Sprintf("ZFile::ParseXML: Error in '%s'.\n\t Unknown element found "
"inside a File element: '%s'.\n",
name.c_str(), nodeName.c_str()));
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions ZAPD/ZLimb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

using namespace std;

REGISTER_ZFILENODE(Limb, ZLimb);

Struct_800A57C0::Struct_800A57C0(const std::vector<uint8_t>& rawData, uint32_t fileOffset)
{
unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00);
Expand Down
23 changes: 23 additions & 0 deletions ZAPD/ZResource.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "ZResource.h"

#include <regex>
#include "StringHelper.h"

using namespace std;

ZResource::ZResource(ZFile* nParent)
Expand Down Expand Up @@ -42,7 +45,19 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
if (reader != nullptr)
{
if (reader->Attribute("Name") != nullptr)
{
name = reader->Attribute("Name");
static std::regex r("[a-zA-Z_]+[a-zA-Z0-9_]*",
std::regex::icase | std::regex::optimize);

if (!std::regex_match(name, r))
{
throw std::domain_error(
StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n\t Resource "
"with invalid 'Name' attribute.\n",
name.c_str()));
}
}
else
name = "";

Expand All @@ -55,6 +70,14 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
isCustomAsset = true;
else
isCustomAsset = false;

if (!canHaveInner && !reader->NoChildren())
{
throw std::runtime_error(
StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n\t Resource '%s' "
"with inner element/child detected.\n",
name.c_str(), reader->Name()));
}
}
}

Expand Down
1 change: 1 addition & 0 deletions ZAPD/ZResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class ZResource
std::vector<uint8_t> rawData;
int rawDataIndex;
std::string sourceOutput;
bool canHaveInner = false; // Can this type have an inner node?
bool isCustomAsset; // If set to true, create a reference for the asset in the file, but don't
// actually try to extract it from the file
};
Expand Down
6 changes: 3 additions & 3 deletions ZAPD/ZRoom/ZRoom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ ZRoom::ZRoom(ZFile* nParent) : ZResource(nParent)
extDefines = "";
scene = nullptr;
roomCount = -1;
canHaveInner = true;
}

ZRoom::~ZRoom()
Expand All @@ -67,9 +68,8 @@ ZRoom::~ZRoom()
void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const int nRawDataIndex, const std::string& nRelPath)
{
rawData = nRawData;
rawDataIndex = nRawDataIndex;
name = string(reader->Attribute("Name"));
ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex, nRelPath);

// room->scene = nScene;
scene = Globals::Instance->lastScene;

Expand Down