Skip to content

Commit

Permalink
Add a few errors checks (#119)
Browse files Browse the repository at this point in the history
* Check for repeated names, outnames and offsets

Signed-off-by: angie <[email protected]>

* Check for File inside File

Signed-off-by: angie <[email protected]>

* Error if a ZResource node has a child

Signed-off-by: angie <[email protected]>

* Error if an invalid ZResource name is included in the XML

Signed-off-by: angie <[email protected]>

* error when a ZResource is not in a ZFile

Signed-off-by: angie <[email protected]>

* ups

Signed-off-by: angie <[email protected]>

* Add error if unknown element is found and other fixes

* Run format
  • Loading branch information
AngheloAlf authored Apr 22, 2021
1 parent e06757c commit b0d98ff
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 7 deletions.
7 changes: 7 additions & 0 deletions ZAPD/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,13 @@ bool Parse(const std::string& xmlFilePath, const std::string& basePath, const st
ZFile* file = new ZFile(fileMode, child, basePath, outPath, "", xmlFilePath, 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 @@ -125,18 +126,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 @@ -173,8 +211,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

0 comments on commit b0d98ff

Please sign in to comment.