Skip to content

Commit c0381ab

Browse files
StephenCWillsAJenbo
authored andcommitted
Validate stash size to avoid in-game corruption
1 parent 9763196 commit c0381ab

1 file changed

Lines changed: 29 additions & 1 deletion

File tree

Source/loadsave.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "mpq/mpq_common.hpp"
3333
#include "pfile.h"
3434
#include "playerdat.hpp"
35+
#include "plrmsg.h"
3536
#include "qol/stash.h"
3637
#include "stores.h"
3738
#include "utils/endian.hpp"
@@ -114,6 +115,11 @@ class LoadHelper {
114115
&& m_size_ >= (m_cur_ + size);
115116
}
116117

118+
size_t Size()
119+
{
120+
return m_size_;
121+
}
122+
117123
template <typename T>
118124
constexpr void Skip(size_t count = 1)
119125
{
@@ -1957,6 +1963,21 @@ void LoadLevel(LevelConversionData *levelConversionData)
19571963
const int DiabloItemSaveSize = 368;
19581964
const int HellfireItemSaveSize = 372;
19591965

1966+
bool IsStashSizeValid(size_t stashSize, uint32_t pages, uint32_t itemCount)
1967+
{
1968+
const size_t itemSize = (gbIsHellfire ? HellfireItemSaveSize : DiabloItemSaveSize);
1969+
1970+
const size_t expectedSize = sizeof(uint8_t)
1971+
+ sizeof(uint32_t)
1972+
+ sizeof(uint32_t)
1973+
+ (sizeof(uint32_t) + 10 * 10 * sizeof(uint16_t)) * pages
1974+
+ sizeof(uint32_t)
1975+
+ itemSize * itemCount
1976+
+ sizeof(uint32_t);
1977+
1978+
return stashSize == expectedSize;
1979+
}
1980+
19601981
} // namespace
19611982

19621983
void ConvertLevels(SaveWriter &saveWriter)
@@ -2256,8 +2277,10 @@ void LoadStash()
22562277
return;
22572278

22582279
auto version = file.NextLE<uint8_t>();
2259-
if (version > StashVersion)
2280+
if (version > StashVersion) {
2281+
EventPlrMsg(_("Stash version invalid. If you attempt to access your stash, data will be overwritten!!"), UiFlags::ColorRed);
22602282
return;
2283+
}
22612284

22622285
Stash.gold = file.NextLE<uint32_t>();
22632286

@@ -2272,6 +2295,11 @@ void LoadStash()
22722295
}
22732296

22742297
auto itemCount = file.NextLE<uint32_t>();
2298+
if (!IsStashSizeValid(file.Size(), pages, itemCount)) {
2299+
Stash = {};
2300+
EventPlrMsg(_("Stash size invalid. If you attempt to access your stash, data will be overwritten!!"), UiFlags::ColorRed);
2301+
return;
2302+
}
22752303
Stash.stashList.resize(itemCount);
22762304
for (unsigned i = 0; i < itemCount; i++) {
22772305
LoadAndValidateItemData(file, Stash.stashList[i]);

0 commit comments

Comments
 (0)