From 915ffe224169f76355ed0cf547f2ee193e006d4f Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 14 May 2020 00:48:28 +0300 Subject: [PATCH] Handle non-node roots more gracefully (bug #5416) --- CHANGELOG.md | 1 + components/nifbullet/bulletnifloader.cpp | 19 ++++++------- components/nifosg/nifloader.cpp | 36 +++++++++++++----------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b88b5f9d..5ba33d939 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures Bug #5370: Opening an unlocked but trapped door uses the key Bug #5400: Editor: Verifier checks race of non-skin bodyparts + Bug #5416: Junk non-node records before the root node are not handled gracefully Feature #5362: Show the soul gems' trapped soul in count dialog 0.46.0 diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index dafee1b49..b1a970f91 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -132,20 +132,17 @@ osg::ref_ptr BulletNifLoader::load(const Nif::File& nif) mStaticMesh.reset(); mAvoidStaticMesh.reset(); - if (nif.numRoots() < 1) + Nif::Node* node; + for (size_t i = 0; i < nif.numRoots(); ++i) { - warn("Found no root nodes in NIF."); - return mShape; + Nif::Record* r = nif.getRoot(i); + assert(r != nullptr); + if ((node = dynamic_cast(r))) + break; } - - Nif::Record *r = nif.getRoot(0); - assert(r != nullptr); - - Nif::Node *node = dynamic_cast(r); - if (node == nullptr) + if (!node) { - warn("First root in file was not a node, but a " + - r->recName + ". Skipping file."); + warn("Found no root nodes in NIF."); return mShape; } diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 650d8db94..e115ad104 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -247,22 +247,23 @@ namespace NifOsg static void loadKf(Nif::NIFFilePtr nif, KeyframeHolder& target) { - if(nif->numRoots() < 1) + const Nif::NiSequenceStreamHelper *seq; + for (size_t i = 0; i < nif->numRoots(); ++i) { - nif->warn("Found no root nodes"); - return; + const Nif::Record *r = nif->getRoot(i); + assert(r != nullptr); + if (r->recType == Nif::RC_NiSequenceStreamHelper) + { + seq = static_cast(r); + break; + } } - const Nif::Record *r = nif->getRoot(0); - assert(r != nullptr); - - if(r->recType != Nif::RC_NiSequenceStreamHelper) + if (!seq) { - nif->warn("First root was not a NiSequenceStreamHelper, but a "+ - r->recName+"."); + nif->warn("Found no NiSequenceStreamHelper root record"); return; } - const Nif::NiSequenceStreamHelper *seq = static_cast(r); Nif::ExtraPtr extra = seq->extra; if(extra.empty() || extra->recType != Nif::RC_NiTextKeyExtraData) @@ -303,15 +304,16 @@ namespace NifOsg osg::ref_ptr load(Nif::NIFFilePtr nif, Resource::ImageManager* imageManager) { - if (nif->numRoots() < 1) + const Nif::Node* nifNode; + for (size_t i = 0; i < nif->numRoots(); ++i) + { + const Nif::Record* r = nif->getRoot(i); + if ((nifNode = dynamic_cast(r))) + break; + } + if (!nifNode) nif->fail("Found no root nodes"); - const Nif::Record* r = nif->getRoot(0); - - const Nif::Node* nifNode = dynamic_cast(r); - if (nifNode == nullptr) - nif->fail("First root was not a node, but a " + r->recName); - osg::ref_ptr textkeys (new TextKeyMapHolder); osg::ref_ptr created = handleNode(nifNode, nullptr, imageManager, std::vector(), 0, false, false, false, &textkeys->mTextKeys);