Sanity checks for the .bhv system (#293)
* Barebones fix. * Sanity checks for the .bhv system. * Two more sanity checks.
This commit is contained in:
parent
463c92b774
commit
5e95fb14f1
|
@ -89,6 +89,7 @@ public:
|
|||
inline s32 Offset() const { return mOffset; }
|
||||
inline bool EoF() const { return mOffset >= mSize; }
|
||||
inline void SetOffset(s32 aOffset) const { mOffset = aOffset; }
|
||||
inline const char *GetFilename() const { return mFilename; }
|
||||
|
||||
public:
|
||||
static BinFile *OpenR(const char *aFilename) {
|
||||
|
|
|
@ -44,7 +44,7 @@ extern "C" {
|
|||
// Current Behavior Version
|
||||
#define BEHAVIOR_MAJOR_VER 1
|
||||
#define BEHAVIOR_MINOR_VER 0
|
||||
#define BEHAVIOR_PATCH_VER 0
|
||||
#define BEHAVIOR_PATCH_VER 1
|
||||
|
||||
// Minimum Behavior Version (That can be read)
|
||||
#define BEHAVIOR_MIN_MAJOR_VER 1
|
||||
|
@ -2485,6 +2485,15 @@ static bool DynOS_Bhv_WriteBinary(const SysPath &aOutputFilename, GfxData *aGfxD
|
|||
/////////////
|
||||
|
||||
static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxData) {
|
||||
// Sanity check the files size. The minimum valid size is 9 bytes.
|
||||
// 1 byte for the type, 1 bytes for the name length, 3 bytes for the version, And 4 bytes for the behaviors size.
|
||||
if (aFile->Size() < 9) {
|
||||
PrintError(" ERROR: Behavior file is smaller then it should be, Rejecting '%s'.", aFile->GetFilename());
|
||||
// We have nothing to return, So return NULL.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate our node.
|
||||
DataNode<BehaviorScript> *_Node = New<DataNode<BehaviorScript>>();
|
||||
|
||||
// Name
|
||||
|
@ -2500,12 +2509,19 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
|
|||
// If the major version doesn't match, then a drasitc change has happened and
|
||||
// we can't read it no matter what. If it's just minor or patch. We might have
|
||||
// code to support it.
|
||||
u32 dataSize = aFile->Read<u32>();
|
||||
if (majorVersion != BEHAVIOR_MIN_MAJOR_VER || (minorVersion < BEHAVIOR_MIN_MINOR_VER || patchVersion < BEHAVIOR_MIN_PATCH_VER)) {
|
||||
PrintError(" ERROR: Behavior version is %u.%u.%u, but reading behaviors under %u.%u.%u is not supported!", majorVersion, minorVersion, patchVersion, BEHAVIOR_MIN_MAJOR_VER, BEHAVIOR_MIN_MINOR_VER, BEHAVIOR_MIN_PATCH_VER);
|
||||
PrintError(" ERROR: Behavior file is version %u.%u.%u, which is not supported! Rejecting '%s'.", majorVersion, minorVersion, patchVersion, aFile->GetFilename());
|
||||
// We don't return this since we failed to read the behavior.
|
||||
Delete(_Node);
|
||||
// We have nothing to return, So return NULL.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Skip the rest of the bytes saved for this behavior.
|
||||
aFile->Skip(dataSize);
|
||||
// If we have nothing in the .bhv file, It compiled incorrectly or is maliciously crafted.
|
||||
// We also check if the specified behavior size is valid for the file.
|
||||
u32 dataSize = aFile->Read<u32>();
|
||||
if (dataSize == 0 || (dataSize > (aFile->Size() - aFile->Offset()))) {
|
||||
PrintError(" ERROR: Behavior file has a invalid behavior in it! Rejecting '%s'.", aFile->GetFilename());
|
||||
// We don't return this since we failed to read the behavior.
|
||||
Delete(_Node);
|
||||
// We have nothing to return, So return NULL.
|
||||
|
@ -2516,11 +2532,6 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
|
|||
_Node->mSize = dataSize;
|
||||
_Node->mData = New<BehaviorScript>(_Node->mSize);
|
||||
|
||||
// Add it
|
||||
if (aGfxData != NULL) {
|
||||
aGfxData->mBehaviorScripts.Add(_Node);
|
||||
}
|
||||
|
||||
// Read it
|
||||
for (u32 i = 0; i != _Node->mSize; ++i) {
|
||||
if (aFile->EoF()) {
|
||||
|
@ -2536,6 +2547,11 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
|
|||
}
|
||||
}
|
||||
|
||||
// Add it
|
||||
if (aGfxData != NULL) {
|
||||
aGfxData->mBehaviorScripts.Add(_Node);
|
||||
}
|
||||
|
||||
return _Node;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ GfxData *DynOS_Bhv_GetActiveGfx(BehaviorScript *bhvScript) {
|
|||
for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) {
|
||||
auto &gfxData = _CustomBehaviorScripts[i].second;
|
||||
auto &scripts = gfxData->mBehaviorScripts;
|
||||
if (scripts.Count() == 0) { continue; }
|
||||
if (bhvScript == scripts[scripts.Count() - 1]->mData) {
|
||||
return gfxData;
|
||||
}
|
||||
|
@ -67,6 +68,7 @@ s32 DynOS_Bhv_GetActiveModIndex(BehaviorScript *bhvScript) {
|
|||
for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) {
|
||||
auto &gfxData = _CustomBehaviorScripts[i].second;
|
||||
auto &scripts = gfxData->mBehaviorScripts;
|
||||
if (scripts.Count() == 0) { continue; }
|
||||
if (bhvScript == scripts[scripts.Count() - 1]->mData) {
|
||||
return gfxData->mModIndex;
|
||||
}
|
||||
|
@ -96,7 +98,10 @@ void DynOS_Bhv_HookAllCustomBehaviors() {
|
|||
for (s32 i = 0; i < _CustomBehaviorScripts.Count(); ++i) {
|
||||
auto &scriptName = _CustomBehaviorScripts[i].first;
|
||||
auto &aGfxData = _CustomBehaviorScripts[i].second;
|
||||
auto &script = aGfxData->mBehaviorScripts[aGfxData->mBehaviorScripts.Count() - 1]->mData;
|
||||
if (aGfxData->mBehaviorScripts.Count() == 0) { continue; }
|
||||
auto *node = aGfxData->mBehaviorScripts[aGfxData->mBehaviorScripts.Count() - 1];
|
||||
if (node == nullptr) { continue; }
|
||||
auto &script = node->mData;
|
||||
|
||||
// Theres currently no better place but to do this here.
|
||||
if (smlua_hook_custom_bhv(script, scriptName) == 0) {
|
||||
|
|
Loading…
Reference in New Issue