From e68a454fd85ef33f821ee1b2142f1f2f3ea6246e Mon Sep 17 00:00:00 2001 From: Dobrohotov Alexei Date: Sun, 23 May 2021 16:02:05 +0300 Subject: [PATCH] More ESM cleanup --- components/esm/esmreader.cpp | 32 +++++++++++++------------------- components/esm/esmreader.hpp | 4 ---- components/esm/loadland.cpp | 4 +++- components/esm/loadregn.cpp | 2 +- 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/components/esm/esmreader.cpp b/components/esm/esmreader.cpp index 30c38d739c..899dc745fb 100644 --- a/components/esm/esmreader.cpp +++ b/components/esm/esmreader.cpp @@ -119,13 +119,13 @@ std::string ESMReader::getHString() // them. For some reason, they break the rules, and contain a byte // (value 0) even if the header says there is no data. If // Morrowind accepts it, so should we. - if (mCtx.leftSub == 0 && !mEsm->peek()) + if (mCtx.leftSub == 0 && hasMoreSubs() && !mEsm->peek()) { // Skip the following zero byte mCtx.leftRec--; char c; - getExact(&c, 1); - return ""; + getT(c); + return std::string(); } return getString(mCtx.leftSub); @@ -155,14 +155,12 @@ void ESMReader::getSubNameIs(const char* name) { getSubName(); if (mCtx.subName != name) - fail( - "Expected subrecord " + std::string(name) + " but got " - + mCtx.subName.toString()); + fail("Expected subrecord " + std::string(name) + " but got " + mCtx.subName.toString()); } bool ESMReader::isNextSub(const char* name) { - if (!mCtx.leftRec) + if (!hasMoreSubs()) return false; getSubName(); @@ -177,7 +175,7 @@ bool ESMReader::isNextSub(const char* name) bool ESMReader::peekNextSub(const char *name) { - if (!mCtx.leftRec) + if (!hasMoreSubs()) return false; getSubName(); @@ -234,21 +232,17 @@ void ESMReader::skipHSubUntil(const char *name) void ESMReader::getSubHeader() { - if (mCtx.leftRec < 4) + if (mCtx.leftRec < sizeof(mCtx.leftSub)) fail("End of record while reading sub-record header"); // Get subrecord size getT(mCtx.leftSub); + mCtx.leftRec -= sizeof(mCtx.leftSub); // Adjust number of record bytes left - mCtx.leftRec -= mCtx.leftSub + 4; -} - -void ESMReader::getSubHeaderIs(int size) -{ - getSubHeader(); - if (size != static_cast (mCtx.leftSub)) - fail("getSubHeaderIs(): Sub header mismatch"); + if (mCtx.leftRec < mCtx.leftSub) + fail("Record size is larger than rest of file"); + mCtx.leftRec -= mCtx.leftSub; } NAME ESMReader::getRecName() @@ -276,7 +270,7 @@ void ESMReader::skipRecord() void ESMReader::getRecHeader(uint32_t &flags) { // General error checking - if (mCtx.leftFile < 12) + if (mCtx.leftFile < 3 * sizeof(uint32_t)) fail("End of file while reading record header"); if (mCtx.leftRec) fail("Previous record contains unread bytes"); @@ -284,7 +278,7 @@ void ESMReader::getRecHeader(uint32_t &flags) getUint(mCtx.leftRec); getUint(flags);// This header entry is always zero getUint(flags); - mCtx.leftFile -= 12; + mCtx.leftFile -= 3 * sizeof(uint32_t); // Check that sizes add up if (mCtx.leftFile < mCtx.leftRec) diff --git a/components/esm/esmreader.hpp b/components/esm/esmreader.hpp index 503bb637d7..32adf8561e 100644 --- a/components/esm/esmreader.hpp +++ b/components/esm/esmreader.hpp @@ -206,10 +206,6 @@ public: */ void getSubHeader(); - /** Get sub header and check the size - */ - void getSubHeaderIs(int size); - /************************************************************************* * * Low level record methods diff --git a/components/esm/loadland.cpp b/components/esm/loadland.cpp index 38596628f2..d23452d76e 100644 --- a/components/esm/loadland.cpp +++ b/components/esm/loadland.cpp @@ -50,7 +50,9 @@ namespace ESM switch (esm.retSubName().intval) { case ESM::FourCC<'I','N','T','V'>::value: - esm.getSubHeaderIs(8); + esm.getSubHeader(); + if (esm.getSubSize() != 8) + esm.fail("Subrecord size is not equal to 8"); esm.getT(mX); esm.getT(mY); hasLocation = true; diff --git a/components/esm/loadregn.cpp b/components/esm/loadregn.cpp index a56b9f2474..ada33dc3f8 100644 --- a/components/esm/loadregn.cpp +++ b/components/esm/loadregn.cpp @@ -39,7 +39,7 @@ namespace ESM // May include the additional two bytes (but not necessarily) if (esm.getSubSize() == sizeof(mData)) { - esm.getExact(&mData, sizeof(mData)); + esm.getT(mData); } else {