diff options
author | Willem Jan Palenstijn | 2012-12-01 12:29:17 +0100 |
---|---|---|
committer | Willem Jan Palenstijn | 2012-12-01 12:40:24 +0100 |
commit | 02fe2ded354ecbfd87acdc4493be4b41a759d1d9 (patch) | |
tree | 815201dad71ab80e22388c513ea3e2e59a3f345d | |
parent | 8881f71ac5ae68422f27703928911e246b38c4b6 (diff) | |
download | scummvm-rg350-02fe2ded354ecbfd87acdc4493be4b41a759d1d9.tar.gz scummvm-rg350-02fe2ded354ecbfd87acdc4493be4b41a759d1d9.tar.bz2 scummvm-rg350-02fe2ded354ecbfd87acdc4493be4b41a759d1d9.zip |
DREAMWEB: Check for exFrame data corruption on load
This provides earlier detection for corrupted savegames caused by
bug #3591088
-rw-r--r-- | engines/dreamweb/saveload.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp index 162ad53cde..8a0791d19b 100644 --- a/engines/dreamweb/saveload.cpp +++ b/engines/dreamweb/saveload.cpp @@ -574,6 +574,14 @@ void DreamWebEngine::savePosition(unsigned int slot, const char *descbuf) { delete outSaveFile; } + +// Utility struct for a savegame sanity check in loadPosition +struct FrameExtent { + uint16 start; + uint16 length; + bool operator<(const struct FrameExtent& other) const { return start<other.start; } +}; + void DreamWebEngine::loadPosition(unsigned int slot) { _timeCount = 0; clearChanges(); @@ -653,6 +661,42 @@ void DreamWebEngine::loadPosition(unsigned int slot) { } delete inSaveFile; + + + // Do a sanity check on exFrames data to detect exFrames corruption + // caused by a (now fixed) bug in emergencyPurge. See bug #3591088. + // Gather the location of frame data of all used ex object frames. + Common::List<FrameExtent> flist; + for (unsigned int i = 0; i < kNumexobjects; ++i) { + if (_exData[i].mapad[0] != 0xff) { + FrameExtent fe; + Frame *frame = &_exFrames._frames[3*i+0]; + fe.start = frame->ptr(); + fe.length = frame->width * frame->height; + flist.push_back(fe); + + frame = &_exFrames._frames[3*i+1]; + fe.start = frame->ptr(); + fe.length = frame->width * frame->height; + flist.push_back(fe); + } + } + // ...and check if the frames overlap. + Common::sort(flist.begin(), flist.end(), Common::Less<FrameExtent>()); + Common::List<FrameExtent>::const_iterator iter; + uint16 curEnd = 0; + for (iter = flist.begin(); iter != flist.end(); ++iter) { + if (iter->start < curEnd) + error("exFrames data corruption in savegame"); + curEnd = iter->start + iter->length; + } + if (curEnd > _vars._exFramePos) { + if (curEnd > kExframeslen) + error("exFrames data corruption in savegame"); + warning("Fixing up exFramePos"); + _vars._exFramePos = curEnd; + } + // (end of sanity check) } // Count number of save files, and load their descriptions into _saveNames |