Do not use union to access FIXED_STRING<4> as int

https://en.cppreference.com/w/cpp/language/union:
> It's undefined behavior to read from the member of the union that wasn't most recently written.
pull/3186/head
elsid 3 years ago
parent 62dfbb33d9
commit 18d3102148
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -367,10 +367,10 @@ int load(Arguments& info)
EsmTool::RecordBase *record = EsmTool::RecordBase::create(n);
if (record == nullptr)
{
if (skipped.count(n.intval) == 0)
if (skipped.count(n.toInt()) == 0)
{
std::cout << "Skipping " << n.toString() << " records.\n";
skipped.emplace(n.intval);
skipped.emplace(n.toInt());
}
esm.skipRecord();
@ -402,7 +402,7 @@ int load(Arguments& info)
record->print();
}
if (record->getType().intval == ESM::REC_CELL && loadCells && interested)
if (record->getType().toInt() == ESM::REC_CELL && loadCells && interested)
{
loadCell(record->cast<ESM::Cell>()->get(), esm, info);
}
@ -415,7 +415,7 @@ int load(Arguments& info)
{
delete record;
}
++info.data.mRecordStats[n.intval];
++info.data.mRecordStats[n.toInt()];
}
} catch(std::exception &e) {
@ -459,7 +459,7 @@ int clone(Arguments& info)
for (std::pair<int, int> stat : info.data.mRecordStats)
{
ESM::NAME name;
name.intval = stat.first;
name = stat.first;
int amount = stat.second;
std::cout << std::setw(digitCount) << amount << " " << name.toString() << " ";
if (++i % 3 == 0)
@ -496,7 +496,7 @@ int clone(Arguments& info)
esm.startRecord(typeName.toString(), record->getFlags());
record->save(esm);
if (typeName.intval == ESM::REC_CELL) {
if (typeName.toInt() == ESM::REC_CELL) {
ESM::Cell *ptr = &record->cast<ESM::Cell>()->get();
if (!info.data.mCellRefs[ptr].empty())
{

@ -176,7 +176,7 @@ RecordBase::create(const ESM::NAME type)
{
RecordBase *record = nullptr;
switch (type.intval) {
switch (type.toInt()) {
case ESM::REC_ACTI:
{
record = new EsmTool::Record<ESM::Activator>;

@ -324,14 +324,14 @@ namespace ESSImport
ESM::NAME n = esm.getRecName();
esm.getRecHeader();
auto it = converters.find(n.intval);
auto it = converters.find(n.toInt());
if (it != converters.end())
{
it->second->read(esm);
}
else
{
if (unknownRecords.insert(n.intval).second)
if (unknownRecords.insert(n.toInt()).second)
{
std::ios::fmtflags f(std::cerr.flags());
std::cerr << "Error: unknown record " << n.toString() << " (0x" << std::hex << esm.getFileOffset() << ")" << std::endl;

@ -35,7 +35,7 @@ QSet<QString> CellNameLoader::getCellNames(QStringList &contentPaths)
bool CellNameLoader::isCellRecord(ESM::NAME &recordName)
{
return recordName.intval == ESM::REC_CELL;
return recordName.toInt() == ESM::REC_CELL;
}
QString CellNameLoader::getCellName(ESM::ESMReader &esmReader)

@ -1086,7 +1086,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
bool unhandledRecord = false;
switch (n.intval)
switch (n.toInt())
{
case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break;
case ESM::REC_GMST: mGmsts.load (*mReader, mBase); break;

@ -406,7 +406,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
ESM::NAME n = reader.getRecName();
reader.getRecHeader();
switch (n.intval)
switch (n.toInt())
{
case ESM::REC_SAVE:
{
@ -427,12 +427,12 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
case ESM::REC_JOUR_LEGACY:
case ESM::REC_QUES:
MWBase::Environment::get().getJournal()->readRecord (reader, n.intval);
MWBase::Environment::get().getJournal()->readRecord (reader, n.toInt());
break;
case ESM::REC_DIAS:
MWBase::Environment::get().getDialogueManager()->readRecord (reader, n.intval);
MWBase::Environment::get().getDialogueManager()->readRecord (reader, n.toInt());
break;
case ESM::REC_ALCH:
@ -457,7 +457,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
case ESM::REC_LEVI:
case ESM::REC_CREA:
case ESM::REC_CONT:
MWBase::Environment::get().getWorld()->readRecord(reader, n.intval, contentFileMap);
MWBase::Environment::get().getWorld()->readRecord(reader, n.toInt(), contentFileMap);
break;
case ESM::REC_CAM_:
@ -466,7 +466,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
case ESM::REC_GSCR:
MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord (reader, n.intval, contentFileMap);
MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord (reader, n.toInt(), contentFileMap);
break;
case ESM::REC_GMAP:
@ -474,21 +474,21 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
case ESM::REC_ASPL:
case ESM::REC_MARK:
MWBase::Environment::get().getWindowManager()->readRecord(reader, n.intval);
MWBase::Environment::get().getWindowManager()->readRecord(reader, n.toInt());
break;
case ESM::REC_DCOU:
case ESM::REC_STLN:
MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.intval);
MWBase::Environment::get().getMechanicsManager()->readRecord(reader, n.toInt());
break;
case ESM::REC_INPU:
MWBase::Environment::get().getInputManager()->readRecord(reader, n.intval);
MWBase::Environment::get().getInputManager()->readRecord(reader, n.toInt());
break;
case ESM::REC_LUAM:
MWBase::Environment::get().getLuaManager()->readRecord(reader, n.intval);
MWBase::Environment::get().getLuaManager()->readRecord(reader, n.toInt());
break;
default:

@ -190,10 +190,10 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
esm.getRecHeader();
// Look up the record type.
std::map<int, StoreBase *>::iterator it = mStores.find(n.intval);
std::map<int, StoreBase *>::iterator it = mStores.find(n.toInt());
if (it == mStores.end()) {
if (n.intval == ESM::REC_INFO) {
if (n.toInt() == ESM::REC_INFO) {
if (dialogue)
{
dialogue->readInfo(esm, esm.getIndex() != 0);
@ -203,12 +203,12 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
Log(Debug::Error) << "Error: info record without dialog";
esm.skipRecord();
}
} else if (n.intval == ESM::REC_MGEF) {
} else if (n.toInt() == ESM::REC_MGEF) {
mMagicEffects.load (esm);
} else if (n.intval == ESM::REC_SKIL) {
} else if (n.toInt() == ESM::REC_SKIL) {
mSkills.load (esm);
}
else if (n.intval==ESM::REC_FILT || n.intval == ESM::REC_DBGP)
else if (n.toInt() == ESM::REC_FILT || n.toInt() == ESM::REC_DBGP)
{
// ignore project file only records
esm.skipRecord();
@ -224,7 +224,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
continue;
}
if (n.intval==ESM::REC_DIAL) {
if (n.toInt() == ESM::REC_DIAL) {
dialogue = const_cast<ESM::Dialogue*>(mDialogs.find(id.mId));
} else {
dialogue = nullptr;

@ -66,7 +66,7 @@ void ESM::CellRef::loadData(ESMReader &esm, bool &isDeleted)
while (!isLoaded && esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'U','N','A','M'>::value:
esm.getHT(mReferenceBlocked);

@ -14,7 +14,7 @@ void ESM::DebugProfile::load (ESMReader& esm, bool &isDeleted)
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -102,25 +102,35 @@ struct FIXED_STRING : public FIXED_STRING_BASE<FIXED_STRING, SIZE>
template <>
struct FIXED_STRING<4> : public FIXED_STRING_BASE<FIXED_STRING, 4>
{
union {
char data[4];
uint32_t intval;
};
char data[4];
using FIXED_STRING_BASE::operator==;
using FIXED_STRING_BASE::operator!=;
bool operator==(uint32_t v) const { return v == intval; }
bool operator!=(uint32_t v) const { return v != intval; }
bool operator==(uint32_t v) const { return v == toInt(); }
bool operator!=(uint32_t v) const { return v != toInt(); }
FIXED_STRING<4>& operator=(std::uint32_t value)
{
std::memcpy(data, &value, sizeof(data));
return *this;
}
void assign(const std::string& value)
{
intval = 0;
std::memset(data, 0, sizeof(data));
std::memcpy(data, value.data(), std::min(value.size(), sizeof(data)));
}
char const* ro_data() const { return data; }
char* rw_data() { return data; }
std::uint32_t toInt() const
{
std::uint32_t value;
std::memcpy(&value, data, sizeof(data));
return value;
}
};
typedef FIXED_STRING<4> NAME;

@ -14,7 +14,7 @@ void ESM::Filter::load (ESMReader& esm, bool &isDeleted)
while (esm.hasMoreSubs())
{
esm.getSubName();
uint32_t name = esm.retSubName().intval;
uint32_t name = esm.retSubName().toInt();
switch (name)
{
case ESM::SREC_NAME:

@ -17,7 +17,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -20,7 +20,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -50,7 +50,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -19,7 +19,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -70,7 +70,7 @@ namespace ESM
while (!isLoaded && esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mName = esm.getHString();
@ -117,7 +117,7 @@ namespace ESM
while (!isLoaded && esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'I','N','T','V'>::value:
int waterl;

@ -48,7 +48,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -20,7 +20,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -42,7 +42,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -31,7 +31,7 @@ namespace ESM {
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -28,7 +28,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'D','A','T','A'>::value:
{

@ -17,7 +17,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -19,7 +19,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -41,7 +41,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -23,7 +23,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'D','A','T','A'>::value:
esm.getHT(mData, 12);

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -47,7 +47,7 @@ namespace ESM
while (!isLoaded && esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'I','N','T','V'>::value:
esm.getSubHeader();
@ -83,7 +83,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'V','N','M','L'>::value:
esm.skipHSub();

@ -16,7 +16,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -17,7 +17,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -209,7 +209,7 @@ void MagicEffect::load(ESMReader &esm, bool &isDeleted)
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'I','T','E','X'>::value:
mIcon = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -26,7 +26,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -46,7 +46,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mCell = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -30,7 +30,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -17,7 +17,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -91,7 +91,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'S','C','H','D'>::value:
{

@ -137,7 +137,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::FourCC<'I','N','D','X'>::value:
esm.getHT(mIndex);

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -20,7 +20,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -19,7 +19,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -18,7 +18,7 @@ namespace ESM
while (esm.hasMoreSubs())
{
esm.getSubName();
switch (esm.retSubName().intval)
switch (esm.retSubName().toInt())
{
case ESM::SREC_NAME:
mId = esm.getHString();

@ -10,13 +10,13 @@ namespace ESM
void Transport::add(ESMReader &esm)
{
if (esm.retSubName().intval == ESM::FourCC<'D','O','D','T'>::value)
if (esm.retSubName().toInt() == ESM::FourCC<'D','O','D','T'>::value)
{
Dest dodt;
esm.getHExact(&dodt.mPos, 24);
mList.push_back(dodt);
}
else if (esm.retSubName().intval == ESM::FourCC<'D','N','A','M'>::value)
else if (esm.retSubName().toInt() == ESM::FourCC<'D','N','A','M'>::value)
{
const std::string name = esm.getHString();
if (mList.empty())

Loading…
Cancel
Save