Skip to content

Commit

Permalink
Merge branch 'fix_asan_error_on_save' into 'master'
Browse files Browse the repository at this point in the history
Fix dangling pointer access on clicking save in the main menu (#7007)

Closes #7007

See merge request OpenMW/openmw!2408
  • Loading branch information
psi29a committed Sep 15, 2022
2 parents 16fd01a + a0cfcc5 commit 4d01489
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 18 deletions.
14 changes: 8 additions & 6 deletions apps/openmw/mwgui/savegamedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,26 +176,28 @@ namespace MWGui
{
if (it->begin()!=it->end())
{
const ESM::SavedGame& signature = it->getSignature();

std::stringstream title;
title << it->getSignature().mPlayerName;
title << signature.mPlayerName;

// For a custom class, we will not find it in the store (unless we loaded the savegame first).
// Fall back to name stored in savegame header in that case.
std::string_view className;
if (it->getSignature().mPlayerClassId.empty())
className = it->getSignature().mPlayerClassName;
if (signature.mPlayerClassId.empty())
className = signature.mPlayerClassName;
else
{
// Find the localised name for this class from the store
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().search(
it->getSignature().mPlayerClassId);
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>()
.search(signature.mPlayerClassId);
if (class_)
className = class_->mName;
else
className = "?"; // From an older savegame format that did not support custom classes properly.
}

title << " (#{sLevel} " << it->getSignature().mPlayerLevel << " " << MyGUI::TextIterator::toTagsString(toUString(className)) << ")";
title << " (#{sLevel} " << signature.mPlayerLevel << " " << MyGUI::TextIterator::toTagsString(toUString(className)) << ")";

mCharacterSelection->addItem (MyGUI::LanguageManager::getInstance().replaceTags(title.str()));

Expand Down
23 changes: 12 additions & 11 deletions apps/openmw/mwstate/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <filesystem>
#include <sstream>
#include <utility>
#include <algorithm>
#include <tuple>

#include <components/esm/defs.hpp>
#include <components/esm3/esmreader.hpp>
Expand Down Expand Up @@ -172,23 +174,22 @@ MWState::Character::SlotIterator MWState::Character::end() const
return mSlots.rend();
}

ESM::SavedGame MWState::Character::getSignature() const
const ESM::SavedGame& MWState::Character::getSignature() const
{
if (mSlots.empty())
throw std::logic_error ("character signature not available");

std::vector<Slot>::const_iterator iter (mSlots.begin());

Slot slot = *iter;
const auto tiePlayerLevelAndTimeStamp = [] (const Slot& v)
{
return std::tie(v.mProfile.mPlayerLevel, v.mTimeStamp);
};

for (++iter; iter!=mSlots.end(); ++iter)
if (iter->mProfile.mPlayerLevel>slot.mProfile.mPlayerLevel)
slot = *iter;
else if (iter->mProfile.mPlayerLevel==slot.mProfile.mPlayerLevel &&
iter->mTimeStamp>slot.mTimeStamp)
slot = *iter;
const auto lessByPlayerLevelAndTimeStamp = [&] (const Slot& l, const Slot& r)
{
return tiePlayerLevelAndTimeStamp(l) < tiePlayerLevelAndTimeStamp(r);
};

return slot.mProfile;
return std::max_element(mSlots.begin(), mSlots.end(), lessByPlayerLevelAndTimeStamp)->mProfile;
}

const std::filesystem::path& MWState::Character::getPath() const
Expand Down
2 changes: 1 addition & 1 deletion apps/openmw/mwstate/character.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ namespace MWState

const std::filesystem::path& getPath() const;

ESM::SavedGame getSignature() const;
const ESM::SavedGame& getSignature() const;
///< Return signature information for this character.
///
/// \attention This function must not be called if there are no slots.
Expand Down

0 comments on commit 4d01489

Please sign in to comment.