From e48a4767cffa0b4106639a78da7be1a4a7e28af4 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sun, 5 Jan 2014 22:39:00 -0500 Subject: [PATCH] Fix #365 plRegistryKeyList::Read assumed that plUoid object IDs are always sequential. This is not the case since f664e8b resulted in all keys getting an ID. The problem manifested itself here because there were temporary materials that were being created and thrown away, causing object ID gaps. --- .../PubUtilLib/plResMgr/plRegistryKeyList.cpp | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp index 040b60c7..d6a64160 100644 --- a/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp +++ b/Sources/Plasma/PubUtilLib/plResMgr/plRegistryKeyList.cpp @@ -52,7 +52,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com plRegistryKeyList::~plRegistryKeyList() { std::for_each(fKeys.begin(), fKeys.end(), - [] (plKeyImp* key) { if (!key->ObjectIsLoaded()) delete key; } + [] (plKeyImp* key) { if (key && !key->ObjectIsLoaded()) delete key; } ); } @@ -85,7 +85,7 @@ plKeyImp* plRegistryKeyList::FindKey(const plUoid& uoid) const // because of local data. Verify that we have the right key by // name, and if it's wrong, do the slower find-by-name. plKeyImp *keyImp = fKeys[objectID-1]; - if (keyImp->GetName().CompareI(uoid.GetObjectName()) != 0) + if (!keyImp || keyImp->GetName().CompareI(uoid.GetObjectName()) != 0) return FindKey(uoid.GetObjectName()); else return keyImp; @@ -172,8 +172,9 @@ bool plRegistryKeyList::SetKeyUnused(plKeyImp* key, LoadStatus& loadStatusChange // Recall that vectors are index zero but normal object IDs are index one... else if (id <= fKeys.size()) { - if (fKeys[id-1]->GetUoid().GetObjectID() == id) - foundKey = fKeys[id-1]; + plKeyImp* tempKey = fKeys[id-1]; + if (tempKey && tempKey->GetUoid().GetObjectID() == id) + foundKey = tempKey; } // Last chance: do a slow name search for that key. @@ -203,14 +204,19 @@ void plRegistryKeyList::Read(hsStream* s) s->ReadByte(); uint32_t numKeys = s->ReadLE32(); - fKeys.reserve(numKeys); + fKeys.reserve((numKeys * 3) / 2); for (uint32_t i = 0; i < numKeys; ++i) { plKeyImp* newKey = new plKeyImp; newKey->Read(s); - fKeys.push_back(newKey); + + uint32_t id = newKey->GetUoid().GetObjectID(); + if (fKeys.size() < id) + fKeys.resize(id); + fKeys[id - 1] = newKey; } + fKeys.shrink_to_fit(); } void plRegistryKeyList::Write(hsStream* s) @@ -229,7 +235,7 @@ void plRegistryKeyList::Write(hsStream* s) for (auto it = fKeys.begin(); it != fKeys.end(); ++it) { plKeyImp* key = *it; - if (key->ObjectIsLoaded()) + if (key && key->ObjectIsLoaded()) { ++keyCount; key->Write(s);