Skip to content

Commit 4722405

Browse files
committed
Merge branch 'fix_niftest_afl_findings' into 'master'
Fix AFL findings in niftest See merge request OpenMW/openmw!4988
2 parents 93c4424 + 246759e commit 4722405

File tree

18 files changed

+393
-228
lines changed

18 files changed

+393
-228
lines changed

components/bgsm/stream.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
#include "stream.hpp"
22

3+
#include <osg/Vec2f>
4+
#include <osg/Vec3f>
5+
#include <osg/Vec4f>
6+
7+
#include <format>
8+
#include <stdexcept>
9+
#include <string>
10+
311
namespace Bgsm
412
{
513
template <>
@@ -30,8 +38,9 @@ namespace Bgsm
3038
throw std::runtime_error("Requested string length is too large: " + std::to_string(length));
3139
str = std::string(length, '\0');
3240
mStream->read(str.data(), length);
33-
if (mStream->bad())
34-
throw std::runtime_error("Failed to read sized string of " + std::to_string(length) + " chars");
41+
if (mStream->fail())
42+
throw std::runtime_error(std::format(
43+
"Failed to read sized string of {} chars: {}", length, std::generic_category().message(errno)));
3544
std::size_t end = str.find('\0');
3645
if (end != std::string::npos)
3746
str.erase(end);

components/bgsm/stream.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <array>
55
#include <cassert>
6-
#include <cstdint>
6+
#include <format>
77
#include <istream>
88
#include <stdexcept>
99
#include <string>
@@ -23,9 +23,9 @@ namespace Bgsm
2323
{
2424
static_assert(std::is_arithmetic_v<T>, "Buffer element type is not arithmetic");
2525
pIStream->read(reinterpret_cast<char*>(dest), numInstances * sizeof(T));
26-
if (pIStream->bad())
27-
throw std::runtime_error("Failed to read typed (" + std::string(typeid(T).name()) + ") buffer of "
28-
+ std::to_string(numInstances) + " instances");
26+
if (pIStream->fail())
27+
throw std::runtime_error(std::format("Failed to read typed ({}) buffer of {} instances: {}",
28+
typeid(T).name(), numInstances, std::generic_category().message(errno)));
2929
if constexpr (Misc::IS_BIG_ENDIAN)
3030
for (std::size_t i = 0; i < numInstances; i++)
3131
Misc::swapEndiannessInplace(dest[i]);

components/nif/controller.cpp

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88

99
namespace Nif
1010
{
11+
namespace
12+
{
13+
void readSkinnedShapeGroup(NIFStream& stream, std::vector<NiBoneLODController::SkinInfo>& value)
14+
{
15+
stream.readVectorOfRecords<uint32_t>(value);
16+
}
17+
}
1118

1219
void NiTimeController::read(NIFStream* nif)
1320
{
@@ -84,11 +91,10 @@ namespace Nif
8491
nif->read(mAccumRootName);
8592
mTextKeys.read(nif);
8693
}
87-
mControlledBlocks.resize(nif->get<uint32_t>());
94+
const uint32_t size = nif->get<uint32_t>();
8895
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 106))
8996
nif->read(mArrayGrowBy);
90-
for (ControlledBlock& block : mControlledBlocks)
91-
block.read(nif);
97+
nif->readVectorOfRecords(size, mControlledBlocks);
9298
}
9399

94100
void NiSequence::post(Reader& nif)
@@ -122,13 +128,8 @@ namespace Nif
122128
mStringPalette.read(nif);
123129
else if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() >= 24)
124130
{
125-
if (nif->getBethVersion() >= 29)
126-
mAnimNotesList.resize(nif->get<uint16_t>());
127-
else
128-
mAnimNotesList.resize(1);
129-
130-
for (auto& notes : mAnimNotesList)
131-
notes.read(nif);
131+
const uint16_t size = nif->getBethVersion() >= 29 ? nif->get<uint16_t>() : 1;
132+
nif->readVectorOfRecords(size, mAnimNotesList);
132133
}
133134
}
134135

@@ -482,29 +483,27 @@ namespace Nif
482483
mData.post(nif);
483484
}
484485

486+
void NiBoneLODController::SkinInfo::read(NIFStream* nif)
487+
{
488+
mShape.read(nif);
489+
mSkin.read(nif);
490+
}
491+
485492
void NiBoneLODController::read(NIFStream* nif)
486493
{
487494
NiTimeController::read(nif);
488495

489496
nif->read(mLOD);
490-
mNodeGroups.resize(nif->get<uint32_t>());
497+
const uint32_t nodeGroupsCount = nif->get<uint32_t>();
498+
mNodeGroups.reserve(nodeGroupsCount);
491499
nif->read(mNumNodeGroups);
492-
for (NiAVObjectList& group : mNodeGroups)
493-
readRecordList(nif, group);
500+
for (uint32_t i = 0; i < nodeGroupsCount; ++i)
501+
readRecordList(nif, mNodeGroups.emplace_back());
494502

495503
if (nif->getBethVersion() != 0 || nif->getVersion() < NIFStream::generateVersion(4, 2, 2, 0))
496504
return;
497505

498-
mSkinnedShapeGroups.resize(nif->get<uint32_t>());
499-
for (std::vector<SkinInfo>& group : mSkinnedShapeGroups)
500-
{
501-
group.resize(nif->get<uint32_t>());
502-
for (SkinInfo& info : group)
503-
{
504-
info.mShape.read(nif);
505-
info.mSkin.read(nif);
506-
}
507-
}
506+
nif->readVectorOfRecords<uint32_t>(readSkinnedShapeGroup, mSkinnedShapeGroups);
508507
readRecordList(nif, mShapeGroups);
509508
}
510509

@@ -892,9 +891,7 @@ namespace Nif
892891

893892
void BSTreadTransfInterpolator::read(NIFStream* nif)
894893
{
895-
mTransforms.resize(nif->get<uint32_t>());
896-
for (BSTreadTransform& transform : mTransforms)
897-
transform.read(nif);
894+
nif->readVectorOfRecords<uint32_t>(mTransforms);
898895
mData.read(nif);
899896
}
900897

components/nif/controller.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ namespace Nif
322322
{
323323
NiTriBasedGeomPtr mShape;
324324
NiSkinInstancePtr mSkin;
325+
326+
void read(NIFStream* nif);
325327
};
326328

327329
uint32_t mLOD;

components/nif/data.cpp

Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,46 @@
88

99
namespace Nif
1010
{
11+
namespace
12+
{
13+
void readNiSkinDataVertWeight(NIFStream& stream, NiSkinData::VertWeight& value)
14+
{
15+
auto& [vertex, weight] = value;
16+
stream.read(vertex);
17+
stream.read(weight);
18+
}
19+
20+
struct ReadNiSkinDataBoneInfo
21+
{
22+
bool mHasVertexWeights;
23+
24+
void operator()(NIFStream& stream, NiSkinData::BoneInfo& value) const
25+
{
26+
stream.read(value.mTransform);
27+
stream.read(value.mBoundSphere);
28+
29+
const uint16_t numVertices = stream.get<uint16_t>();
30+
31+
if (!mHasVertexWeights)
32+
return;
33+
34+
stream.readVectorOfRecords(numVertices, readNiSkinDataVertWeight, value.mWeights);
35+
}
36+
};
37+
38+
struct ReadNiMorphDataMorphData
39+
{
40+
uint32_t mNumVerts;
41+
42+
void operator()(NIFStream& stream, NiMorphData::MorphData& value) const
43+
{
44+
value.mKeyFrames = std::make_shared<FloatKeyMap>();
45+
value.mKeyFrames->read(&stream, /*morph*/ true);
46+
stream.readVector(value.mVertices, mNumVerts);
47+
}
48+
};
49+
}
50+
1151
void NiGeometryData::read(NIFStream* nif)
1252
{
1353
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 114))
@@ -215,20 +255,21 @@ namespace Nif
215255
nif->read(mSigned);
216256
}
217257

258+
void NiPixelData::Mipmap::read(NIFStream* nif)
259+
{
260+
nif->read(mWidth);
261+
nif->read(mHeight);
262+
nif->read(mOffset);
263+
}
264+
218265
void NiPixelData::read(NIFStream* nif)
219266
{
220267
mPixelFormat.read(nif);
221268
mPalette.read(nif);
222-
mMipmaps.resize(nif->get<uint32_t>());
269+
const uint32_t mipmapsCount = nif->get<uint32_t>();
223270
nif->read(mBytesPerPixel);
224-
for (Mipmap& mip : mMipmaps)
225-
{
226-
nif->read(mip.mWidth);
227-
nif->read(mip.mHeight);
228-
nif->read(mip.mOffset);
229-
}
230-
uint32_t numPixels;
231-
nif->read(numPixels);
271+
nif->readVectorOfRecords(mipmapsCount, mMipmaps);
272+
const uint32_t numPixels = nif->get<uint32_t>();
232273
if (nif->getVersion() >= NIFStream::generateVersion(10, 4, 0, 2))
233274
nif->read(mNumFaces);
234275
nif->readVector(mData, numPixels * mNumFaces);
@@ -247,12 +288,14 @@ namespace Nif
247288

248289
void NiVisData::read(NIFStream* nif)
249290
{
250-
mKeys = std::make_shared<std::vector<std::pair<float, bool>>>(nif->get<uint32_t>());
251-
for (auto& [time, value] : *mKeys)
252-
{
253-
nif->read(time);
254-
value = nif->get<uint8_t>() != 0;
255-
}
291+
const auto readPair = [](NIFStream& stream, std::pair<float, bool>& value) {
292+
stream.read(value.first);
293+
value.second = stream.get<uint8_t>() != 0;
294+
};
295+
296+
std::vector<std::pair<float, bool>> keys;
297+
nif->readVectorOfRecords<uint32_t>(readPair, keys);
298+
mKeys = std::make_shared<std::vector<std::pair<float, bool>>>(std::move(keys));
256299
}
257300

258301
void NiSkinInstance::read(NIFStream* nif)
@@ -296,16 +339,17 @@ namespace Nif
296339
return partitions;
297340
}
298341

342+
void BSDismemberSkinInstance::BodyPart::read(NIFStream* nif)
343+
{
344+
nif->read(mFlags);
345+
nif->read(mType);
346+
}
347+
299348
void BSDismemberSkinInstance::read(NIFStream* nif)
300349
{
301350
NiSkinInstance::read(nif);
302351

303-
mParts.resize(nif->get<uint32_t>());
304-
for (BodyPart& part : mParts)
305-
{
306-
nif->read(part.mFlags);
307-
nif->read(part.mType);
308-
}
352+
nif->readVectorOfRecords<uint32_t>(mParts);
309353
}
310354

311355
void BSSkinInstance::read(NIFStream* nif)
@@ -339,8 +383,7 @@ namespace Nif
339383
{
340384
nif->read(mTransform);
341385

342-
uint32_t numBones;
343-
nif->read(numBones);
386+
const uint32_t numBones = nif->get<uint32_t>();
344387
bool hasVertexWeights = true;
345388
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
346389
{
@@ -351,25 +394,8 @@ namespace Nif
351394
nif->read(hasVertexWeights);
352395
}
353396

354-
mBones.resize(numBones);
355-
for (BoneInfo& bi : mBones)
356-
{
357-
nif->read(bi.mTransform);
358-
nif->read(bi.mBoundSphere);
359-
360-
uint16_t numVertices;
361-
nif->read(numVertices);
362-
363-
if (!hasVertexWeights)
364-
continue;
365-
366-
bi.mWeights.resize(numVertices);
367-
for (auto& [vertex, weight] : bi.mWeights)
368-
{
369-
nif->read(vertex);
370-
nif->read(weight);
371-
}
372-
}
397+
const ReadNiSkinDataBoneInfo readBoneInfo{ .mHasVertexWeights = hasVertexWeights };
398+
nif->readVectorOfRecords(numBones, readBoneInfo, mBones);
373399
}
374400

375401
void NiSkinData::post(Reader& nif)
@@ -467,18 +493,12 @@ namespace Nif
467493

468494
void NiMorphData::read(NIFStream* nif)
469495
{
470-
uint32_t numMorphs, numVerts;
471-
nif->read(numMorphs);
472-
nif->read(numVerts);
496+
const uint32_t numMorphs = nif->get<uint32_t>();
497+
const uint32_t numVerts = nif->get<uint32_t>();
473498
nif->read(mRelativeTargets);
474499

475-
mMorphs.resize(numMorphs);
476-
for (MorphData& morph : mMorphs)
477-
{
478-
morph.mKeyFrames = std::make_shared<FloatKeyMap>();
479-
morph.mKeyFrames->read(nif, /*morph*/ true);
480-
nif->readVector(morph.mVertices, numVerts);
481-
}
500+
const ReadNiMorphDataMorphData readMorph{ .mNumVerts = numVerts };
501+
nif->readVectorOfRecords(numMorphs, readMorph, mMorphs);
482502
}
483503

484504
void NiKeyframeData::read(NIFStream* nif)

components/nif/data.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,11 @@ namespace Nif
169169
{
170170
struct Mipmap
171171
{
172-
uint32_t mWidth, mHeight;
172+
uint32_t mWidth;
173+
uint32_t mHeight;
173174
uint32_t mOffset;
175+
176+
void read(NIFStream* nif);
174177
};
175178

176179
NiPixelFormat mPixelFormat;
@@ -218,6 +221,8 @@ namespace Nif
218221
{
219222
uint16_t mFlags;
220223
uint16_t mType;
224+
225+
void read(NIFStream* nif);
221226
};
222227

223228
std::vector<BodyPart> mParts;

0 commit comments

Comments
 (0)