aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/recorderfile.cpp3
-rw-r--r--engines/access/access.cpp12
-rw-r--r--engines/access/access.h2
-rw-r--r--engines/access/detection.cpp12
-rw-r--r--engines/adl/detection.cpp6
-rw-r--r--engines/agi/detection.cpp6
-rw-r--r--engines/avalanche/detection.cpp7
-rw-r--r--engines/bbvs/bbvs.h2
-rw-r--r--engines/bbvs/detection.cpp4
-rw-r--r--engines/bbvs/saveload.cpp10
-rw-r--r--engines/cge/cge.h2
-rw-r--r--engines/cge/cge_main.cpp12
-rw-r--r--engines/cge/detection.cpp6
-rw-r--r--engines/cge2/cge2.h2
-rw-r--r--engines/cge2/detection.cpp6
-rw-r--r--engines/cge2/saveload.cpp12
-rw-r--r--engines/cruise/detection.cpp11
-rw-r--r--engines/cruise/saveload.cpp13
-rw-r--r--engines/cruise/saveload.h2
-rw-r--r--engines/dm/dm.h2
-rw-r--r--engines/dm/loadsave.cpp13
-rw-r--r--engines/draci/detection.cpp10
-rw-r--r--engines/draci/saveload.cpp11
-rw-r--r--engines/draci/saveload.h2
-rw-r--r--engines/drascula/detection.cpp6
-rw-r--r--engines/dreamweb/detection.cpp7
-rw-r--r--engines/fullpipe/detection.cpp8
-rw-r--r--engines/fullpipe/gameloader.h4
-rw-r--r--engines/fullpipe/modal.cpp3
-rw-r--r--engines/fullpipe/stateloader.cpp10
-rw-r--r--engines/gnap/detection.cpp15
-rw-r--r--engines/gnap/gnap.h2
-rw-r--r--engines/gnap/menu.cpp7
-rw-r--r--engines/hopkins/detection.cpp9
-rw-r--r--engines/hopkins/dialogs.cpp2
-rw-r--r--engines/hopkins/saveload.cpp19
-rw-r--r--engines/hopkins/saveload.h4
-rw-r--r--engines/hugo/detection.cpp7
-rw-r--r--engines/kyra/detection.cpp4
-rw-r--r--engines/kyra/kyra_v1.h2
-rw-r--r--engines/kyra/saveload.cpp11
-rw-r--r--engines/lab/lab.h2
-rw-r--r--engines/lab/savegame.cpp14
-rw-r--r--engines/lilliput/detection.cpp6
-rw-r--r--engines/macventure/detection.cpp4
-rw-r--r--engines/macventure/saveload.cpp9
-rw-r--r--engines/mads/detection.cpp12
-rw-r--r--engines/mads/game.cpp12
-rw-r--r--engines/mads/game.h2
-rw-r--r--engines/mohawk/myst_state.cpp7
-rw-r--r--engines/mohawk/riven_saveload.cpp6
-rw-r--r--engines/mortevielle/saveload.cpp20
-rw-r--r--engines/mortevielle/saveload.h2
-rw-r--r--engines/neverhood/detection.cpp4
-rw-r--r--engines/neverhood/menumodule.cpp2
-rw-r--r--engines/neverhood/neverhood.h2
-rw-r--r--engines/neverhood/saveload.cpp10
-rw-r--r--engines/prince/detection.cpp6
-rw-r--r--engines/prince/prince.h2
-rw-r--r--engines/prince/saveload.cpp12
-rw-r--r--engines/saga/detection.cpp6
-rw-r--r--engines/sci/detection.cpp9
-rw-r--r--engines/scumm/saveload.cpp4
-rw-r--r--engines/sherlock/detection.cpp5
-rw-r--r--engines/sherlock/saveload.cpp20
-rw-r--r--engines/sherlock/saveload.h2
-rw-r--r--engines/supernova/detection.cpp6
-rw-r--r--engines/sword1/detection.cpp6
-rw-r--r--engines/teenagent/detection.cpp7
-rw-r--r--engines/titanic/core/project_item.cpp17
-rw-r--r--engines/titanic/core/project_item.h2
-rw-r--r--engines/titanic/detection.cpp10
-rw-r--r--engines/titanic/pet_control/pet_load_save.cpp5
-rw-r--r--engines/titanic/titanic.cpp6
-rw-r--r--engines/toltecs/detection.cpp4
-rw-r--r--engines/toltecs/menu.cpp2
-rw-r--r--engines/toltecs/saveload.cpp10
-rw-r--r--engines/toltecs/toltecs.h2
-rw-r--r--engines/toon/detection.cpp6
-rw-r--r--engines/tsage/detection.cpp9
-rw-r--r--engines/tsage/saveload.cpp15
-rw-r--r--engines/tsage/saveload.h2
-rw-r--r--engines/tucker/detection.cpp4
-rw-r--r--engines/tucker/saveload.cpp10
-rw-r--r--engines/tucker/tucker.h4
-rw-r--r--engines/voyeur/detection.cpp3
-rw-r--r--engines/voyeur/voyeur.cpp11
-rw-r--r--engines/voyeur/voyeur.h2
-rw-r--r--engines/xeen/detection.cpp13
-rw-r--r--engines/xeen/saves.cpp12
-rw-r--r--engines/xeen/saves.h2
-rw-r--r--engines/zvision/detection.cpp2
-rw-r--r--engines/zvision/file/save_manager.cpp6
-rw-r--r--engines/zvision/file/save_manager.h2
-rw-r--r--graphics/thumbnail.cpp28
-rw-r--r--graphics/thumbnail.h2
96 files changed, 341 insertions, 337 deletions
diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp
index 1f283715d0..7552cd45b3 100644
--- a/common/recorderfile.cpp
+++ b/common/recorderfile.cpp
@@ -608,7 +608,8 @@ Graphics::Surface *PlaybackFile::getScreenShot(int number) {
if (screenCount == number) {
screenCount++;
_readStream->seek(-4, SEEK_CUR);
- return Graphics::loadThumbnail(*_readStream);
+ Graphics::Surface *thumbnail;
+ return Graphics::loadThumbnail(*_readStream, thumbnail) ? thumbnail : NULL;
} else {
uint32 size = _readStream->readUint32BE();
_readStream->skip(size-8);
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index 1855280a24..c1af19026b 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -488,11 +488,6 @@ Common::Error AccessEngine::loadGameState(int slot) {
if (!readSavegameHeader(saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Load most of the savegame data
synchronize(s);
delete saveFile;
@@ -537,9 +532,8 @@ void AccessEngine::synchronize(Common::Serializer &s) {
const char *const SAVEGAME_STR = "ACCESS";
#define SAVEGAME_STR_SIZE 6
-bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header) {
+WARN_UNUSED_RESULT bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -557,9 +551,9 @@ bool AccessEngine::readSavegameHeader(Common::InSaveFile *in, AccessSavegameHead
header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
diff --git a/engines/access/access.h b/engines/access/access.h
index 972dd4c380..56646f01c9 100644
--- a/engines/access/access.h
+++ b/engines/access/access.h
@@ -306,7 +306,7 @@ public:
/**
* Read in a savegame header
*/
- static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, AccessSavegameHeader &header, bool skipThumbnail = true);
/**
* Write out a savegame header
diff --git a/engines/access/detection.cpp b/engines/access/detection.cpp
index 3e70de3635..186fcbdf06 100644
--- a/engines/access/detection.cpp
+++ b/engines/access/detection.cpp
@@ -157,11 +157,9 @@ SaveStateList AccessMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- Access::AccessEngine::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+ if (Access::AccessEngine::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -187,7 +185,11 @@ SaveStateDescriptor AccessMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Access::AccessSavegameHeader header;
- Access::AccessEngine::readSavegameHeader(f, header);
+ if (!Access::AccessEngine::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index e63beb2c07..ab634bc02a 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -401,7 +401,11 @@ SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int sl
return SaveStateDescriptor();
}
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*inFile);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*inFile, thumbnail)) {
+ delete inFile;
+ return SaveStateDescriptor();
+ }
sd.setThumbnail(thumbnail);
delete inFile;
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index e26f5c84fc..817be08f2c 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -375,7 +375,11 @@ SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int sl
char saveVersion = in->readByte();
if (saveVersion >= 4) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
descriptor.setThumbnail(thumbnail);
diff --git a/engines/avalanche/detection.cpp b/engines/avalanche/detection.cpp
index def395b77f..64634dc017 100644
--- a/engines/avalanche/detection.cpp
+++ b/engines/avalanche/detection.cpp
@@ -193,7 +193,12 @@ SaveStateDescriptor AvalancheMetaEngine::querySaveMetaInfos(const char *target,
SaveStateDescriptor desc(slot, description);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*f);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*f, thumbnail)) {
+ warning("Cannot read thumbnail data, possibly broken savegame");
+ delete f;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
delete f;
diff --git a/engines/bbvs/bbvs.h b/engines/bbvs/bbvs.h
index 9fb6b9cac3..a9d37c2551 100644
--- a/engines/bbvs/bbvs.h
+++ b/engines/bbvs/bbvs.h
@@ -417,7 +417,7 @@ public:
const char *getSavegameFilename(int num);
bool existsSavegame(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
- static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
void allocSnapshot();
void freeSnapshot();
diff --git a/engines/bbvs/detection.cpp b/engines/bbvs/detection.cpp
index 1b2c644dda..b30c6d3f2d 100644
--- a/engines/bbvs/detection.cpp
+++ b/engines/bbvs/detection.cpp
@@ -124,7 +124,7 @@ SaveStateList BbvsMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Bbvs::BbvsEngine::readSaveHeader(in, false, header) == Bbvs::BbvsEngine::kRSHENoError) {
+ if (Bbvs::BbvsEngine::readSaveHeader(in, header) == Bbvs::BbvsEngine::kRSHENoError) {
saveList.push_back(SaveStateDescriptor(slotNum, header.description));
}
delete in;
@@ -142,7 +142,7 @@ SaveStateDescriptor BbvsMetaEngine::querySaveMetaInfos(const char *target, int s
if (in) {
Bbvs::BbvsEngine::SaveHeader header;
Bbvs::BbvsEngine::kReadSaveHeaderError error;
- error = Bbvs::BbvsEngine::readSaveHeader(in, true, header);
+ error = Bbvs::BbvsEngine::readSaveHeader(in, header, false);
delete in;
if (error == Bbvs::BbvsEngine::kRSHENoError) {
SaveStateDescriptor desc(slot, header.description);
diff --git a/engines/bbvs/saveload.cpp b/engines/bbvs/saveload.cpp
index 74c255c860..d4782aad39 100644
--- a/engines/bbvs/saveload.cpp
+++ b/engines/bbvs/saveload.cpp
@@ -27,7 +27,7 @@
namespace Bbvs {
-BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
header.version = in->readUint32LE();
if (header.version > BBVS_SAVEGAME_VERSION)
@@ -38,10 +38,8 @@ BbvsEngine::kReadSaveHeaderError BbvsEngine::readSaveHeader(Common::SeekableRead
while (descriptionLen--)
header.description += (char)in->readByte();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
// Not used yet, reserved for future usage
@@ -101,7 +99,7 @@ void BbvsEngine::loadgame(const char *filename) {
SaveHeader header;
- kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+ kReadSaveHeaderError errorCode = readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
diff --git a/engines/cge/cge.h b/engines/cge/cge.h
index d3f8a93c1d..668224d2f7 100644
--- a/engines/cge/cge.h
+++ b/engines/cge/cge.h
@@ -246,7 +246,7 @@ public:
void mainLoop();
void handleFrame();
void saveGame(int slotNumber, const Common::String &desc);
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
void switchMusic();
void selectPocket(int n);
void expandSprite(Sprite *spr);
diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp
index b60f201cb0..fcbbf34a4d 100644
--- a/engines/cge/cge_main.cpp
+++ b/engines/cge/cge_main.cpp
@@ -242,10 +242,6 @@ bool CGEEngine::loadGame(int slotNumber, SavegameHeader *header, bool tiny) {
delete readStream;
return true;
}
-
- // Delete the thumbnail
- saveHeader.thumbnail->free();
- delete saveHeader.thumbnail;
}
// Get in the savegame
@@ -424,9 +420,7 @@ void CGEEngine::syncGame(Common::SeekableReadStream *readStream, Common::WriteSt
}
}
-bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = nullptr;
-
+WARN_UNUSED_RESULT bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
if (header.version > kSavegameVersion)
@@ -439,9 +433,9 @@ bool CGEEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &heade
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
diff --git a/engines/cge/detection.cpp b/engines/cge/detection.cpp
index 482591bf50..cae2e036b9 100644
--- a/engines/cge/detection.cpp
+++ b/engines/cge/detection.cpp
@@ -221,10 +221,6 @@ SaveStateList CGEMetaEngine::listSaves(const char *target) const {
// Valid savegame
if (CGE::CGEEngine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
} else {
// Must be an original format savegame
@@ -253,7 +249,7 @@ SaveStateDescriptor CGEMetaEngine::querySaveMetaInfos(const char *target, int sl
f->read(buffer, kSavegameStrSize + 1);
bool hasHeader = !strncmp(buffer, CGE::savegameStr, kSavegameStrSize + 1) &&
- CGE::CGEEngine::readSavegameHeader(f, header);
+ CGE::CGEEngine::readSavegameHeader(f, header, false);
delete f;
if (!hasHeader) {
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h
index 18f919b5eb..899520c6dd 100644
--- a/engines/cge2/cge2.h
+++ b/engines/cge2/cge2.h
@@ -161,7 +161,7 @@ public:
virtual Common::Error loadGameState(int slot);
virtual Common::Error run();
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
GUI::Debugger *getDebugger() {
return _console;
diff --git a/engines/cge2/detection.cpp b/engines/cge2/detection.cpp
index d05dfffedc..68f16d8dc9 100644
--- a/engines/cge2/detection.cpp
+++ b/engines/cge2/detection.cpp
@@ -221,10 +221,6 @@ SaveStateList CGE2MetaEngine::listSaves(const char *target) const {
// Valid savegame
if (CGE2::CGE2Engine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
} else {
// Must be an original format savegame
@@ -253,7 +249,7 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
f->read(buffer, kSavegameStrSize + 1);
bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
- CGE2::CGE2Engine::readSavegameHeader(f, header);
+ CGE2::CGE2Engine::readSavegameHeader(f, header, false);
delete f;
if (!hasHeader) {
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index cd0be84567..83cba5316d 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -117,10 +117,6 @@ bool CGE2Engine::loadGame(int slotNumber) {
delete readStream;
return false;
}
-
- // Delete the thumbnail
- saveHeader.thumbnail->free();
- delete saveHeader.thumbnail;
}
resetGame();
@@ -180,9 +176,7 @@ void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &h
out->writeSint16LE(td.tm_min);
}
-bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = nullptr;
-
+WARN_UNUSED_RESULT bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
if (header.version > kSavegameVersion)
@@ -195,9 +189,9 @@ bool CGE2Engine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &head
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp
index 6f5d236173..3dfd414fd2 100644
--- a/engines/cruise/detection.cpp
+++ b/engines/cruise/detection.cpp
@@ -241,9 +241,8 @@ SaveStateList CruiseMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
Cruise::CruiseSavegameHeader header;
- Cruise::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- delete header.thumbnail;
+ if (Cruise::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
delete in;
}
}
@@ -264,7 +263,11 @@ SaveStateDescriptor CruiseMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Cruise::CruiseSavegameHeader header;
- Cruise::readSavegameHeader(f, header);
+ if (!Cruise::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp
index a62648df08..7aaeb06905 100644
--- a/engines/cruise/saveload.cpp
+++ b/engines/cruise/saveload.cpp
@@ -43,9 +43,8 @@ struct overlayRestoreTemporary {
overlayRestoreTemporary ovlRestoreData[90];
-bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) {
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[6];
- header.thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, 6);
@@ -62,9 +61,9 @@ bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header) {
while ((ch = (char)in->readByte()) != '\0') header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
return true;
}
@@ -827,8 +826,10 @@ Common::Error loadSavegameData(int saveGameIdx) {
// Skip over the savegame header
CruiseSavegameHeader header;
- readSavegameHeader(f, header);
- delete header.thumbnail;
+ if (!readSavegameHeader(f, header)) {
+ delete f;
+ return Common::kReadingFailed;
+ }
// Synchronise the remaining data of the savegame
Common::Serializer s(f, NULL);
diff --git a/engines/cruise/saveload.h b/engines/cruise/saveload.h
index 6fb1f4b545..c92f0e9da5 100644
--- a/engines/cruise/saveload.h
+++ b/engines/cruise/saveload.h
@@ -38,7 +38,7 @@ struct CruiseSavegameHeader {
Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName);
Common::Error loadSavegameData(int saveGameIdx);
-bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header);
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, CruiseSavegameHeader &header, bool skipThumbnail = true);
void initVars();
} // End of namespace Cruise
diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index 16307778ba..e330cb6be7 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -332,7 +332,7 @@ public:
Thing _thingParty; // @ C0xFFFF_THING_PARTY
};
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header);
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header, bool skipThumbnail = true);
} // End of namespace DM
diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp
index 3d8f76c33f..864a726367 100644
--- a/engines/dm/loadsave.cpp
+++ b/engines/dm/loadsave.cpp
@@ -70,7 +70,10 @@ LoadgameResult DMEngine::loadgame(int16 slot) {
file = saveFileManager->openForLoading(fileName);
SaveGameHeader header;
- readSaveGameHeader(file, &header);
+ if (!readSaveGameHeader(file, &header)) {
+ delete file;
+ return kDMLoadgameFailure;
+ }
warning("MISSING CODE: missing check for matching format and platform in save in f435_loadgame");
@@ -397,7 +400,7 @@ bool DMEngine::writeCompleteSaveFile(int16 saveSlot, Common::String& saveDescrip
return true;
}
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header) {
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header, bool skipThumbnail) {
uint32 id = in->readUint32BE();
// Check if it's a valid ScummVM savegame
@@ -419,7 +422,11 @@ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader *header) {
header->_descr.setDescription(saveName);
// Get the thumbnail
- header->_descr.setThumbnail(Graphics::loadThumbnail(*in));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail, skipThumbnail)) {
+ return false;
+ }
+ header->_descr.setThumbnail(thumbnail);
uint32 saveDate = in->readUint32BE();
uint16 saveTime = in->readUint16BE();
diff --git a/engines/draci/detection.cpp b/engines/draci/detection.cpp
index 65427bd8cd..9a76e3890c 100644
--- a/engines/draci/detection.cpp
+++ b/engines/draci/detection.cpp
@@ -132,10 +132,6 @@ SaveStateList DraciMetaEngine::listSaves(const char *target) const {
Draci::DraciSavegameHeader header;
if (Draci::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
delete in;
}
@@ -157,7 +153,11 @@ SaveStateDescriptor DraciMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Draci::DraciSavegameHeader header;
- Draci::readSavegameHeader(f, header);
+ if (!Draci::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/draci/saveload.cpp b/engines/draci/saveload.cpp
index 3e7f8651c1..e30af5375e 100644
--- a/engines/draci/saveload.cpp
+++ b/engines/draci/saveload.cpp
@@ -35,9 +35,8 @@ namespace Draci {
static const char *const draciIdentString = "DRACI";
-bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) {
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[6];
- header.thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, 6);
@@ -59,9 +58,9 @@ bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header) {
header.playtime = in->readUint32LE();
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
return true;
}
@@ -130,10 +129,6 @@ Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm) {
if (!readSavegameHeader(f, header)) {
return Common::kNoGameDataFoundError;
}
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
// Pre-processing
vm->_game->rememberRoomNumAsPrevious();
diff --git a/engines/draci/saveload.h b/engines/draci/saveload.h
index 6f951a3409..bceaebb468 100644
--- a/engines/draci/saveload.h
+++ b/engines/draci/saveload.h
@@ -42,7 +42,7 @@ struct DraciSavegameHeader {
class DraciEngine;
-bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header);
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, DraciSavegameHeader &header, bool skipThumbnail = true);
void writeSavegameHeader(Common::OutSaveFile *out, const DraciSavegameHeader &header);
Common::Error saveSavegameData(int saveGameIdx, const Common::String &saveName, DraciEngine &vm);
Common::Error loadSavegameData(int saveGameIdx, DraciEngine *vm);
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 5f453839e7..a1f2f3e117 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -430,7 +430,11 @@ SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, i
return SaveStateDescriptor();
}
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
delete in;
diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp
index 11966047b0..36af0c3811 100644
--- a/engines/dreamweb/detection.cpp
+++ b/engines/dreamweb/detection.cpp
@@ -198,7 +198,12 @@ SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, i
uint32 saveDate = in->readUint32LE();
uint32 saveTime = in->readUint32LE();
uint32 playTime = in->readUint32LE();
- Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ warning("Missing or broken thumbnail - skipping");
+ delete in;
+ return desc;
+ }
int day = (saveDate >> 24) & 0xFF;
int month = (saveDate >> 16) & 0xFF;
diff --git a/engines/fullpipe/detection.cpp b/engines/fullpipe/detection.cpp
index 9dd1d6beb4..3144a0ebff 100644
--- a/engines/fullpipe/detection.cpp
+++ b/engines/fullpipe/detection.cpp
@@ -184,7 +184,9 @@ SaveStateList FullpipeMetaEngine::listSaves(const char *target) const {
Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file));
if (in) {
Fullpipe::FullpipeSavegameHeader header;
- Fullpipe::readSavegameHeader(in.get(), header);
+ if (!Fullpipe::readSavegameHeader(in.get(), header)) {
+ continue;
+ }
SaveStateDescriptor desc;
@@ -212,7 +214,9 @@ SaveStateDescriptor FullpipeMetaEngine::querySaveMetaInfos(const char *target, i
if (f) {
Fullpipe::FullpipeSavegameHeader header;
- Fullpipe::readSavegameHeader(f.get(), header);
+ if (!Fullpipe::readSavegameHeader(f.get(), header, false)) {
+ return SaveStateDescriptor();
+ }
// Create the return descriptor
SaveStateDescriptor desc;
diff --git a/engines/fullpipe/gameloader.h b/engines/fullpipe/gameloader.h
index 03c3093086..eb5957c78e 100644
--- a/engines/fullpipe/gameloader.h
+++ b/engines/fullpipe/gameloader.h
@@ -84,7 +84,7 @@ struct FullpipeSavegameHeader {
uint32 date;
uint16 time;
uint32 playtime;
- Common::SharedPtr<Graphics::Surface> thumbnail;
+ Graphics::Surface *thumbnail;
};
struct SaveHeader {
@@ -142,7 +142,7 @@ class GameLoader : public CObject {
};
const char *getSavegameFile(int saveGameIdx);
-bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header);
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header, bool skipThumbnail = true);
void parseSavegameHeader(Fullpipe::FullpipeSavegameHeader &header, SaveStateDescriptor &desc);
Inventory2 *getGameLoaderInventory();
diff --git a/engines/fullpipe/modal.cpp b/engines/fullpipe/modal.cpp
index be1e73ff70..45ccabc7d5 100644
--- a/engines/fullpipe/modal.cpp
+++ b/engines/fullpipe/modal.cpp
@@ -2142,7 +2142,8 @@ bool ModalSaveGame::getFileInfo(int slot, FileInfo *fileinfo) {
return false;
Fullpipe::FullpipeSavegameHeader header;
- Fullpipe::readSavegameHeader(f.get(), header);
+ if (!Fullpipe::readSavegameHeader(f.get(), header))
+ return false;
// Create the return descriptor
SaveStateDescriptor desc(slot, header.saveName);
diff --git a/engines/fullpipe/stateloader.cpp b/engines/fullpipe/stateloader.cpp
index 9d4d5ab09a..250c527f40 100644
--- a/engines/fullpipe/stateloader.cpp
+++ b/engines/fullpipe/stateloader.cpp
@@ -193,7 +193,7 @@ void fillDummyHeader(Fullpipe::FullpipeSavegameHeader &header) {
header.playtime = 0;
}
-bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header) {
+WARN_UNUSED_RESULT bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header, bool skipThumbnail) {
uint oldPos = in->pos();
in->seek(-4, SEEK_END);
@@ -237,13 +237,13 @@ bool readSavegameHeader(Common::InSaveFile *in, FullpipeSavegameHeader &header)
header.description = header.saveName;
// Get the thumbnail
- header.thumbnail = Common::SharedPtr<Graphics::Surface>(Graphics::loadThumbnail(*in), Graphics::SurfaceDeleter());
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ in->seek(oldPos, SEEK_SET); // Rewind the file
+ return false;
+ }
in->seek(oldPos, SEEK_SET); // Rewind the file
- if (!header.thumbnail)
- return false;
-
return true;
}
diff --git a/engines/gnap/detection.cpp b/engines/gnap/detection.cpp
index d19d420ff8..97c9128002 100644
--- a/engines/gnap/detection.cpp
+++ b/engines/gnap/detection.cpp
@@ -141,13 +141,8 @@ SaveStateList GnapMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- Gnap::GnapEngine::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
+ if (Gnap::GnapEngine::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
delete in;
}
}
@@ -179,7 +174,11 @@ SaveStateDescriptor GnapMetaEngine::querySaveMetaInfos(const char *target, int s
SaveStateDescriptor desc(slot, saveName);
if (version != 1) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
}
diff --git a/engines/gnap/gnap.h b/engines/gnap/gnap.h
index dbefa31795..dd653304e7 100644
--- a/engines/gnap/gnap.h
+++ b/engines/gnap/gnap.h
@@ -319,7 +319,7 @@ public:
Common::String generateSaveName(int slot);
void synchronize(Common::Serializer &s);
void writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeader &header);
- static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail = true);
void delayTicks(int val, int idx, bool updateCursor);
void delayTicksA(int val, int idx);
diff --git a/engines/gnap/menu.cpp b/engines/gnap/menu.cpp
index 9606273b4c..34b5f18473 100644
--- a/engines/gnap/menu.cpp
+++ b/engines/gnap/menu.cpp
@@ -589,9 +589,8 @@ void GnapEngine::writeSavegameHeader(Common::OutSaveFile *out, GnapSavegameHeade
out->writeSint16LE(td.tm_min);
}
-bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header) {
+WARN_UNUSED_RESULT bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -612,9 +611,9 @@ bool GnapEngine::readSavegameHeader(Common::InSaveFile *in, GnapSavegameHeader &
if (header._version == 1)
header._thumbnail = nullptr;
else {
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
}
// Read in save date/time
diff --git a/engines/hopkins/detection.cpp b/engines/hopkins/detection.cpp
index 041afecaa8..ebefee6278 100644
--- a/engines/hopkins/detection.cpp
+++ b/engines/hopkins/detection.cpp
@@ -168,9 +168,6 @@ SaveStateList HopkinsMetaEngine::listSaves(const char *target) const {
if (in) {
if (Hopkins::SaveLoadManager::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
}
delete in;
@@ -198,7 +195,11 @@ SaveStateDescriptor HopkinsMetaEngine::querySaveMetaInfos(const char *target, in
if (f) {
Hopkins::hopkinsSavegameHeader header;
- Hopkins::SaveLoadManager::readSavegameHeader(f, header);
+ if (!Hopkins::SaveLoadManager::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/hopkins/dialogs.cpp b/engines/hopkins/dialogs.cpp
index fc613f892d..b8f1c73304 100644
--- a/engines/hopkins/dialogs.cpp
+++ b/engines/hopkins/dialogs.cpp
@@ -692,7 +692,7 @@ void DialogsManager::showSaveLoad(SaveLoadMode mode) {
for (int slotNumber = 1; slotNumber <= 6; ++slotNumber) {
hopkinsSavegameHeader header;
- if (_vm->_saveLoad->readSavegameHeader(slotNumber, header)) {
+ if (_vm->_saveLoad->readSavegameHeader(slotNumber, header, false)) {
Graphics::Surface thumb8;
_vm->_saveLoad->convertThumb16To8(header._thumbnail, &thumb8);
diff --git a/engines/hopkins/saveload.cpp b/engines/hopkins/saveload.cpp
index 05c7fb8119..35a80458ff 100644
--- a/engines/hopkins/saveload.cpp
+++ b/engines/hopkins/saveload.cpp
@@ -77,9 +77,8 @@ void SaveLoadManager::load(const Common::String &file, byte *buf) {
delete savefile;
}
-bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -96,9 +95,9 @@ bool SaveLoadManager::readSavegameHeader(Common::InSaveFile *in, hopkinsSavegame
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
@@ -186,10 +185,10 @@ Common::Error SaveLoadManager::loadGame(int slot) {
// Read in the savegame header
hopkinsSavegameHeader header;
- readSavegameHeader(savefile, header);
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
+ if (!readSavegameHeader(savefile, header)) {
+ delete savefile;
+ return Common::kReadingFailed;
+ }
// Read in the savegame data
syncSavegameData(serializer, header._version);
@@ -212,14 +211,14 @@ Common::Error SaveLoadManager::loadGame(int slot) {
return Common::kNoError;
}
-bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SaveLoadManager::readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail) {
// Try and open the save file for reading
Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(
_vm->generateSaveName(slot));
if (!savefile)
return false;
- bool result = readSavegameHeader(savefile, header);
+ bool result = readSavegameHeader(savefile, header, skipThumbnail);
delete savefile;
return result;
}
diff --git a/engines/hopkins/saveload.h b/engines/hopkins/saveload.h
index 7b4ec307f5..33234f49fa 100644
--- a/engines/hopkins/saveload.h
+++ b/engines/hopkins/saveload.h
@@ -61,9 +61,9 @@ public:
bool saveFile(const Common::String &file, const void *buf, size_t n);
void load(const Common::String &file, byte *buf);
- static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, hopkinsSavegameHeader &header, bool skipThumbnail = true);
void writeSavegameHeader(Common::OutSaveFile *out, hopkinsSavegameHeader &header);
- bool readSavegameHeader(int slot, hopkinsSavegameHeader &header);
+ WARN_UNUSED_RESULT bool readSavegameHeader(int slot, hopkinsSavegameHeader &header, bool skipThumbnail = true);
Common::Error saveGame(int slot, const Common::String &saveName);
Common::Error loadGame(int slot);
diff --git a/engines/hugo/detection.cpp b/engines/hugo/detection.cpp
index 4e4746c002..6d2fec5421 100644
--- a/engines/hugo/detection.cpp
+++ b/engines/hugo/detection.cpp
@@ -241,7 +241,12 @@ SaveStateDescriptor HugoMetaEngine::querySaveMetaInfos(const char *target, int s
SaveStateDescriptor desc(slot, saveName);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ warning("Missing or broken savegame thumbnail");
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
uint32 saveDate = file->readUint32BE();
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 70c7e7c93c..79e1d9f494 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -256,7 +256,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
- if (Kyra::KyraEngine_v1::readSaveHeader(in, false, header) == Kyra::KyraEngine_v1::kRSHENoError) {
+ if (Kyra::KyraEngine_v1::readSaveHeader(in, header) == Kyra::KyraEngine_v1::kRSHENoError) {
// WORKAROUND: Old savegames are using 'German' as description for kyra3 restart game save (slot 0),
// since that looks odd we replace it by "New Game".
if (slotNum == 0 && header.gameID == Kyra::GI_KYRA3)
@@ -298,7 +298,7 @@ SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int s
Kyra::KyraEngine_v1::SaveHeader header;
Kyra::KyraEngine_v1::ReadSaveHeaderError error;
- error = Kyra::KyraEngine_v1::readSaveHeader(in, true, header);
+ error = Kyra::KyraEngine_v1::readSaveHeader(in, header, false);
delete in;
if (error == Kyra::KyraEngine_v1::kRSHENoError) {
diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h
index 4de7494510..bbbd59a4b8 100644
--- a/engines/kyra/kyra_v1.h
+++ b/engines/kyra/kyra_v1.h
@@ -416,7 +416,7 @@ protected:
kRSHEIoError = 3
};
- static ReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *file, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static ReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *file, SaveHeader &header, bool skipThumbnail = true);
void loadGameStateCheck(int slot);
virtual Common::Error loadGameState(int slot) = 0;
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index b44850f5c9..c306d6cb5d 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -37,12 +37,11 @@
namespace Kyra {
-KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
uint32 type = in->readUint32BE();
header.originalSave = false;
header.oldHeader = false;
header.flags = 0;
- header.thumbnail = 0;
if (type == MKTAG('K', 'Y', 'R', 'A') || type == MKTAG('A', 'R', 'Y', 'K')) { // old Kyra1 header ID
header.gameID = GI_KYRA1;
@@ -125,10 +124,8 @@ KyraEngine_v1::ReadSaveHeaderError KyraEngine_v1::readSaveHeader(Common::Seekabl
header.flags = in->readUint32BE();
if (header.version >= 14) {
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
}
@@ -140,7 +137,7 @@ Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filena
if (!(in = _saveFileMan->openForLoading(filename)))
return 0;
- ReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, false, header);
+ ReadSaveHeaderError errorCode = KyraEngine_v1::readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
if (errorCode == kRSHEInvalidType)
warning("No ScummVM Kyra engine savefile header");
diff --git a/engines/lab/lab.h b/engines/lab/lab.h
index 2a1e527098..aedf0181ec 100644
--- a/engines/lab/lab.h
+++ b/engines/lab/lab.h
@@ -502,7 +502,7 @@ private:
void handleTrialWarning();
};
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header);
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail = true);
} // End of namespace Lab
diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp
index 656595e3e5..46ef1486f0 100644
--- a/engines/lab/savegame.cpp
+++ b/engines/lab/savegame.cpp
@@ -76,7 +76,7 @@ void LabEngine::writeSaveGameHeader(Common::OutSaveFile *out, const Common::Stri
out->writeUint32BE(playTime);
}
-bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+WARN_UNUSED_RESULT bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) {
uint32 id = in->readUint32BE();
// Check if it's a valid ScummVM savegame
@@ -98,7 +98,11 @@ bool readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
header._descr.setDescription(saveName);
// Get the thumbnail
- header._descr.setThumbnail(Graphics::loadThumbnail(*in));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail, skipThumbnail)) {
+ return false;
+ }
+ header._descr.setThumbnail(thumbnail);
uint32 saveDate = in->readUint32BE();
uint16 saveTime = in->readUint16BE();
@@ -174,7 +178,11 @@ bool LabEngine::loadGame(int slot) {
return false;
SaveGameHeader header;
- readSaveGameHeader(file, header);
+ if (!readSaveGameHeader(file, header)) {
+ delete file;
+ return false;
+ }
+
_roomNum = file->readUint16LE();
_music->checkRoomMusic(1, _roomNum);
_direction = file->readUint16LE();
diff --git a/engines/lilliput/detection.cpp b/engines/lilliput/detection.cpp
index a09e5f05de..466c89e362 100644
--- a/engines/lilliput/detection.cpp
+++ b/engines/lilliput/detection.cpp
@@ -233,7 +233,11 @@ SaveStateDescriptor LilliputMetaEngine::querySaveMetaInfos(const char *target, i
SaveStateDescriptor desc(slot, saveName);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
desc.setDeletableFlag(true);
diff --git a/engines/macventure/detection.cpp b/engines/macventure/detection.cpp
index c179647121..5eda420cb2 100644
--- a/engines/macventure/detection.cpp
+++ b/engines/macventure/detection.cpp
@@ -54,7 +54,7 @@ static const PlainGameDescriptor macventureGames[] = {
namespace MacVenture {
-SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot);
+SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool skipThumbnail = true);
class MacVentureMetaEngine : public AdvancedMetaEngine {
public:
@@ -164,7 +164,7 @@ SaveStateDescriptor MacVentureMetaEngine::querySaveMetaInfos(const char *target,
Common::InSaveFile *in = saveFileMan->openForLoading(saveFileName);
if (in) {
- desc = loadMetaData(in, slot);
+ desc = loadMetaData(in, slot, false);
delete in;
return desc;
}
diff --git a/engines/macventure/saveload.cpp b/engines/macventure/saveload.cpp
index 89a6301318..c63b6a6951 100644
--- a/engines/macventure/saveload.cpp
+++ b/engines/macventure/saveload.cpp
@@ -42,7 +42,7 @@ namespace MacVenture {
#define MACVENTURE_SAVE_VERSION 1 //1 BYTE
#define MACVENTURE_DESC_LENGTH 4 //4 BYTE for the metadata length
-SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot) {
+SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot, bool skipThumbnail) {
// Metadata is stored at the end of the file
// |THUMBNAIL |
// | |
@@ -65,8 +65,11 @@ SaveStateDescriptor loadMetaData(Common::SeekableReadStream *s, int slot) {
s->seek(-(5 + MACVENTURE_DESC_LENGTH + metaSize), SEEK_END);
// Load the thumbnail
- Graphics::Surface *thumb = Graphics::loadThumbnail(*s);
- desc.setThumbnail(thumb);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*s, thumbnail, skipThumbnail)) {
+ return desc;
+ }
+ desc.setThumbnail(thumbnail);
// Load the description
Common::String name;
diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp
index 4fb8b82eb3..8eb3b4eee9 100644
--- a/engines/mads/detection.cpp
+++ b/engines/mads/detection.cpp
@@ -203,11 +203,8 @@ SaveStateList MADSMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- MADS::Game::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
+ if (MADS::Game::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
delete in;
}
}
@@ -233,7 +230,10 @@ SaveStateDescriptor MADSMetaEngine::querySaveMetaInfos(const char *target, int s
if (f) {
MADS::MADSSavegameHeader header;
- MADS::Game::readSavegameHeader(f, header);
+ if (!MADS::Game::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
delete f;
// Create the return descriptor
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 0a6741ba7a..bea0ea3bb4 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -485,11 +485,6 @@ void Game::loadGame(int slotNumber) {
if (!readSavegameHeader(_saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Load most of the savegame data with the exception of scene specific info
synchronize(s, true);
@@ -527,9 +522,8 @@ void Game::saveGame(int slotNumber, const Common::String &saveName) {
const char *const SAVEGAME_STR = "MADS";
#define SAVEGAME_STR_SIZE 4
-bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header) {
+WARN_UNUSED_RESULT bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -546,9 +540,9 @@ bool Game::readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
diff --git a/engines/mads/game.h b/engines/mads/game.h
index 9defb58b1a..b979160f3d 100644
--- a/engines/mads/game.h
+++ b/engines/mads/game.h
@@ -237,7 +237,7 @@ public:
/**
* Read in a savegame header
*/
- static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, MADSSavegameHeader &header, bool skipThumbnail = true);
/**
* Creates a temporary thumbnail for use in saving games
diff --git a/engines/mohawk/myst_state.cpp b/engines/mohawk/myst_state.cpp
index 213a976413..20b8ec47ae 100644
--- a/engines/mohawk/myst_state.cpp
+++ b/engines/mohawk/myst_state.cpp
@@ -272,7 +272,12 @@ SaveStateDescriptor MystGameState::querySaveMetaInfos(int slot) {
desc.setSaveDate(metadata.saveYear, metadata.saveMonth, metadata.saveDay);
desc.setSaveTime(metadata.saveHour, metadata.saveMinute);
desc.setPlayTime(metadata.totalPlayTime);
- desc.setThumbnail(Graphics::loadThumbnail(*metadataFile));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*metadataFile, thumbnail)) {
+ delete metadataFile;
+ return SaveStateDescriptor();
+ }
+ desc.setThumbnail(thumbnail);
delete metadataFile;
diff --git a/engines/mohawk/riven_saveload.cpp b/engines/mohawk/riven_saveload.cpp
index 7165166d8f..1d9ae211d9 100644
--- a/engines/mohawk/riven_saveload.cpp
+++ b/engines/mohawk/riven_saveload.cpp
@@ -148,7 +148,11 @@ SaveStateDescriptor RivenSaveLoad::querySaveMetaInfos(const int slot) {
return descriptor;
}
- descriptor.setThumbnail(Graphics::loadThumbnail(*thmbStream));
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*thmbStream, thumbnail)) {
+ return descriptor;
+ }
+ descriptor.setThumbnail(thumbnail);
delete thmbStream;
diff --git a/engines/mortevielle/saveload.cpp b/engines/mortevielle/saveload.cpp
index 3032c96690..078338a0b5 100644
--- a/engines/mortevielle/saveload.cpp
+++ b/engines/mortevielle/saveload.cpp
@@ -92,8 +92,10 @@ bool SavegameManager::loadSavegame(const Common::String &filename) {
if (!strncmp(&buffer[0], &SAVEGAME_ID[0], 4)) {
// Yes, it is, so skip over the savegame header
SavegameHeader header;
- readSavegameHeader(stream, header);
- delete header.thumbnail;
+ if (!readSavegameHeader(stream, header)) {
+ delete stream;
+ return false;
+ }
} else {
stream->seek(0);
}
@@ -208,9 +210,7 @@ void SavegameManager::writeSavegameHeader(Common::OutSaveFile *out, const Common
out->writeSint16LE(td.tm_min);
}
-bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = NULL;
-
+WARN_UNUSED_RESULT bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
@@ -221,9 +221,9 @@ bool SavegameManager::readSavegameHeader(Common::InSaveFile *in, SavegameHeader
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
@@ -263,7 +263,6 @@ SaveStateList SavegameManager::listSaves(const Common::String &target) {
validFlag = readSavegameHeader(in, header);
if (validFlag) {
- delete header.thumbnail;
saveDescription = header.saveName;
}
} else if (file->size() == 497) {
@@ -311,7 +310,10 @@ SaveStateDescriptor SavegameManager::querySaveMetaInfos(const Common::String &fi
} else {
// Get the savegame header information
SavegameHeader header;
- readSavegameHeader(f, header);
+ if (!readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
delete f;
// Create the return descriptor
diff --git a/engines/mortevielle/saveload.h b/engines/mortevielle/saveload.h
index a0de05b920..b401823938 100644
--- a/engines/mortevielle/saveload.h
+++ b/engines/mortevielle/saveload.h
@@ -65,7 +65,7 @@ public:
Common::Error saveGame(int slot);
void writeSavegameHeader(Common::OutSaveFile *out, const Common::String &saveName);
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
static SaveStateList listSaves(const Common::String &target);
static SaveStateDescriptor querySaveMetaInfos(const Common::String &fileName);
};
diff --git a/engines/neverhood/detection.cpp b/engines/neverhood/detection.cpp
index 46605bb2f7..920d149659 100644
--- a/engines/neverhood/detection.cpp
+++ b/engines/neverhood/detection.cpp
@@ -271,7 +271,7 @@ SaveStateList NeverhoodMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Neverhood::NeverhoodEngine::readSaveHeader(in, false, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
+ if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
saveList.push_back(SaveStateDescriptor(slotNum, header.description));
}
delete in;
@@ -302,7 +302,7 @@ SaveStateDescriptor NeverhoodMetaEngine::querySaveMetaInfos(const char *target,
Neverhood::NeverhoodEngine::SaveHeader header;
Neverhood::NeverhoodEngine::kReadSaveHeaderError error;
- error = Neverhood::NeverhoodEngine::readSaveHeader(in, true, header);
+ error = Neverhood::NeverhoodEngine::readSaveHeader(in, header, false);
delete in;
if (error == Neverhood::NeverhoodEngine::kRSHENoError) {
diff --git a/engines/neverhood/menumodule.cpp b/engines/neverhood/menumodule.cpp
index e3996a2507..b64f4dcdd2 100644
--- a/engines/neverhood/menumodule.cpp
+++ b/engines/neverhood/menumodule.cpp
@@ -291,7 +291,7 @@ void MenuModule::loadSavegameList() {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Neverhood::NeverhoodEngine::readSaveHeader(in, false, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
+ if (Neverhood::NeverhoodEngine::readSaveHeader(in, header) == Neverhood::NeverhoodEngine::kRSHENoError) {
SavegameItem savegameItem;
savegameItem.slotNum = slotNum;
savegameItem.description = header.description;
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index 4c5f9c3303..90055eeb9d 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -129,7 +129,7 @@ public:
bool loadgame(const char *filename);
const char *getSavegameFilename(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
- static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
GameState& gameState() { return _gameState; }
GameModule *gameModule() { return _gameModule; }
diff --git a/engines/neverhood/saveload.cpp b/engines/neverhood/saveload.cpp
index 8fe6c9a155..d7e6f1ebfe 100644
--- a/engines/neverhood/saveload.cpp
+++ b/engines/neverhood/saveload.cpp
@@ -32,7 +32,7 @@ namespace Neverhood {
#define NEVERHOOD_SAVEGAME_VERSION 0
-NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
header.version = in->readUint32LE();
if (header.version > NEVERHOOD_SAVEGAME_VERSION)
@@ -43,10 +43,8 @@ NeverhoodEngine::kReadSaveHeaderError NeverhoodEngine::readSaveHeader(Common::Se
while (descriptionLen--)
header.description += (char)in->readByte();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
// Not used yet, reserved for future usage
@@ -110,7 +108,7 @@ bool NeverhoodEngine::loadgame(const char *filename) {
SaveHeader header;
- kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+ kReadSaveHeaderError errorCode = readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
diff --git a/engines/prince/detection.cpp b/engines/prince/detection.cpp
index ce80fe5cab..ef3128ae09 100644
--- a/engines/prince/detection.cpp
+++ b/engines/prince/detection.cpp
@@ -208,10 +208,6 @@ SaveStateList PrinceMetaEngine::listSaves(const char *target) const {
// Valid savegame
if (Prince::PrinceEngine::readSavegameHeader(file, header)) {
saveList.push_back(SaveStateDescriptor(slotNum, header.saveName));
- if (header.thumbnail) {
- header.thumbnail->free();
- delete header.thumbnail;
- }
}
} else {
// Must be an original format savegame
@@ -239,7 +235,7 @@ SaveStateDescriptor PrinceMetaEngine::querySaveMetaInfos(const char *target, int
f->read(buffer, kSavegameStrSize + 1);
bool hasHeader = !strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) &&
- Prince::PrinceEngine::readSavegameHeader(f, header);
+ Prince::PrinceEngine::readSavegameHeader(f, header, false);
delete f;
if (!hasHeader) {
diff --git a/engines/prince/prince.h b/engines/prince/prince.h
index 32e37e0774..c264125895 100644
--- a/engines/prince/prince.h
+++ b/engines/prince/prince.h
@@ -290,7 +290,7 @@ public:
void playVideo(Common::String videoFilename);
- static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail = true);
Common::String generateSaveName(int slot);
void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header);
void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream);
diff --git a/engines/prince/saveload.cpp b/engines/prince/saveload.cpp
index 14f6078910..8832a6d1d2 100644
--- a/engines/prince/saveload.cpp
+++ b/engines/prince/saveload.cpp
@@ -44,9 +44,7 @@ namespace Prince {
class InterpreterFlags;
class Interpreter;
-bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header) {
- header.thumbnail = nullptr;
-
+WARN_UNUSED_RESULT bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &header, bool skipThumbnail) {
// Get the savegame version
header.version = in->readByte();
if (header.version > kSavegameVersion)
@@ -59,9 +57,9 @@ bool PrinceEngine::readSavegameHeader(Common::InSaveFile *in, SavegameHeader &he
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
@@ -416,10 +414,6 @@ bool PrinceEngine::loadGame(int slotNumber) {
delete readStream;
return false;
}
-
- // Delete the thumbnail
- saveHeader.thumbnail->free();
- delete saveHeader.thumbnail;
}
// Get in the savegame
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index 6fe4277c27..fcd78502d9 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -256,7 +256,11 @@ SaveStateDescriptor SagaMetaEngine::querySaveMetaInfos(const char *target, int s
}
if (version >= 6) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
uint32 saveDate = in->readUint32BE();
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index aa7a63d224..bc7241269d 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -871,7 +871,14 @@ SaveStateDescriptor SciMetaEngine::querySaveMetaInfos(const char *target, int sl
descriptor.setDescription(meta.name);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ // invalid
+ delete in;
+
+ descriptor.setDescription("*Invalid*");
+ return descriptor;
+ }
descriptor.setThumbnail(thumbnail);
int day = (meta.saveDate >> 24) & 0xFF;
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index d04b3bb5ad..84dd16efa6 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -706,7 +706,9 @@ bool ScummEngine::querySaveMetaInfos(const char *target, int slot, int heversion
if (hdr.ver > VER(52)) {
if (Graphics::checkThumbnailHeader(*in)) {
- thumbnail = Graphics::loadThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ return false;
+ }
}
if (hdr.ver > VER(57)) {
diff --git a/engines/sherlock/detection.cpp b/engines/sherlock/detection.cpp
index 9184fd8e88..a0598dcb46 100644
--- a/engines/sherlock/detection.cpp
+++ b/engines/sherlock/detection.cpp
@@ -233,7 +233,10 @@ SaveStateDescriptor SherlockMetaEngine::querySaveMetaInfos(const char *target, i
if (f) {
Sherlock::SherlockSavegameHeader header;
- Sherlock::SaveManager::readSavegameHeader(f, header);
+ if (!Sherlock::SaveManager::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
delete f;
// Create the return descriptor
diff --git a/engines/sherlock/saveload.cpp b/engines/sherlock/saveload.cpp
index 9d203a6a27..ca27f57a97 100644
--- a/engines/sherlock/saveload.cpp
+++ b/engines/sherlock/saveload.cpp
@@ -103,13 +103,9 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- if (!readSavegameHeader(in, header))
- continue;
+ if (readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -119,9 +115,8 @@ SaveStateList SaveManager::getSavegameList(const Common::String &target) {
return saveList;
}
-bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -138,9 +133,9 @@ bool SaveManager::readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHea
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
@@ -212,11 +207,6 @@ void SaveManager::loadGame(int slot) {
if (!readSavegameHeader(saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Synchronize the savegame data
Serializer s(saveFile, nullptr);
s.setVersion(header._version);
diff --git a/engines/sherlock/saveload.h b/engines/sherlock/saveload.h
index 59b0b26d6e..6348b0f668 100644
--- a/engines/sherlock/saveload.h
+++ b/engines/sherlock/saveload.h
@@ -105,7 +105,7 @@ public:
/**
* Read in the header information for a savegame
*/
- static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, SherlockSavegameHeader &header, bool skipThumbnail = true);
/**
* Return the index of the button the mouse is over, if any
diff --git a/engines/supernova/detection.cpp b/engines/supernova/detection.cpp
index 8e9db14db4..7fd2da1760 100644
--- a/engines/supernova/detection.cpp
+++ b/engines/supernova/detection.cpp
@@ -200,7 +200,11 @@ SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target,
desc.setPlayTime(playTime * 1000);
if (Graphics::checkThumbnailHeader(*savefile)) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*savefile);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*savefile, thumbnail)) {
+ delete savefile;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
}
diff --git a/engines/sword1/detection.cpp b/engines/sword1/detection.cpp
index d4343c8a9f..0b81690bc5 100644
--- a/engines/sword1/detection.cpp
+++ b/engines/sword1/detection.cpp
@@ -300,7 +300,11 @@ SaveStateDescriptor SwordMetaEngine::querySaveMetaInfos(const char *target, int
in->skip(1);
if (Graphics::checkThumbnailHeader(*in)) {
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ delete in;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
}
diff --git a/engines/teenagent/detection.cpp b/engines/teenagent/detection.cpp
index caa7bdbec9..e35e7033d5 100644
--- a/engines/teenagent/detection.cpp
+++ b/engines/teenagent/detection.cpp
@@ -178,8 +178,11 @@ public:
SaveStateDescriptor ssd(slot, desc);
//checking for the thumbnail
- if (Graphics::Surface *const thumb = Graphics::loadThumbnail(*in))
- ssd.setThumbnail(thumb);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*in, thumbnail)) {
+ return SaveStateDescriptor();
+ }
+ ssd.setThumbnail(thumbnail);
return ssd;
}
diff --git a/engines/titanic/core/project_item.cpp b/engines/titanic/core/project_item.cpp
index b2bd5cd92b..6da891c417 100644
--- a/engines/titanic/core/project_item.cpp
+++ b/engines/titanic/core/project_item.cpp
@@ -190,10 +190,6 @@ void CProjectItem::loadGame(int slotId) {
// Load the savegame header in
TitanicSavegameHeader header;
readSavegameHeader(&file, header);
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
g_vm->_events->setTotalPlayTicks(header._totalFrames);
@@ -488,13 +484,9 @@ SaveStateList CProjectItem::getSavegameList(const Common::String &target) {
if (in) {
SimpleFile f;
f.open(in);
- if (!readSavegameHeader(&f, header))
- continue;
-
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+ if (readSavegameHeader(&f, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -503,7 +495,7 @@ SaveStateList CProjectItem::getSavegameList(const Common::String &target) {
return saveList;
}
-bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header) {
+bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
header._thumbnail = nullptr;
header._totalFrames = 0;
@@ -526,8 +518,7 @@ bool CProjectItem::readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &h
while ((ch = (char)file->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*file);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*file, header._thumbnail, skipThumbnail))
return false;
// Read in save date/time
diff --git a/engines/titanic/core/project_item.h b/engines/titanic/core/project_item.h
index c9fd6f97cb..ef557f7f9d 100644
--- a/engines/titanic/core/project_item.h
+++ b/engines/titanic/core/project_item.h
@@ -155,7 +155,7 @@ public:
/**
* Read in the header information for a savegame
*/
- static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header);
+ static bool readSavegameHeader(SimpleFile *file, TitanicSavegameHeader &header, bool loadThumbnail = false);
public:
CLASSDEF;
CProjectItem();
diff --git a/engines/titanic/detection.cpp b/engines/titanic/detection.cpp
index b33ac51bed..c98fbbdade 100644
--- a/engines/titanic/detection.cpp
+++ b/engines/titanic/detection.cpp
@@ -128,11 +128,6 @@ SaveStateList TitanicMetaEngine::listSaves(const char *target) const {
if (Titanic::CProjectItem::readSavegameHeader(&cf, header))
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
cf.close();
}
}
@@ -161,7 +156,10 @@ SaveStateDescriptor TitanicMetaEngine::querySaveMetaInfos(const char *target, in
file.open(f);
Titanic::TitanicSavegameHeader header;
- Titanic::CProjectItem::readSavegameHeader(&file, header);
+ if (!Titanic::CProjectItem::readSavegameHeader(&file, header, false)) {
+ file.close();
+ return SaveStateDescriptor();
+ }
file.close();
diff --git a/engines/titanic/pet_control/pet_load_save.cpp b/engines/titanic/pet_control/pet_load_save.cpp
index d918478fb1..72770b9eb2 100644
--- a/engines/titanic/pet_control/pet_load_save.cpp
+++ b/engines/titanic/pet_control/pet_load_save.cpp
@@ -135,11 +135,6 @@ void CPetLoadSave::resetSlots() {
_slotNames[idx].setText(header._saveName);
}
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
file.close();
}
}
diff --git a/engines/titanic/titanic.cpp b/engines/titanic/titanic.cpp
index e0e4a07ce6..5daf399b04 100644
--- a/engines/titanic/titanic.cpp
+++ b/engines/titanic/titanic.cpp
@@ -49,7 +49,6 @@
#include "common/translation.h"
#include "engines/util.h"
#include "graphics/scaler.h"
-#include "graphics/thumbnail.h"
#include "graphics/screen.h"
#include "gui/saveload.h"
@@ -256,11 +255,6 @@ CString TitanicEngine::getSavegameName(int slot) {
TitanicSavegameHeader header;
bool isValid = CProjectItem::readSavegameHeader(&file, header);
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
file.close();
if (isValid)
diff --git a/engines/toltecs/detection.cpp b/engines/toltecs/detection.cpp
index 9303760057..0cd9596c8c 100644
--- a/engines/toltecs/detection.cpp
+++ b/engines/toltecs/detection.cpp
@@ -276,7 +276,7 @@ SaveStateList ToltecsMetaEngine::listSaves(const char *target) const {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, header) == Toltecs::ToltecsEngine::kRSHENoError) {
saveList.push_back(SaveStateDescriptor(slotNum, header.description));
}
delete in;
@@ -325,7 +325,7 @@ SaveStateDescriptor ToltecsMetaEngine::querySaveMetaInfos(const char *target, in
Toltecs::ToltecsEngine::SaveHeader header;
Toltecs::ToltecsEngine::kReadSaveHeaderError error;
- error = Toltecs::ToltecsEngine::readSaveHeader(in, true, header);
+ error = Toltecs::ToltecsEngine::readSaveHeader(in, header, false);
delete in;
if (error == Toltecs::ToltecsEngine::kRSHENoError) {
diff --git a/engines/toltecs/menu.cpp b/engines/toltecs/menu.cpp
index 5fc0599c2a..c4373265e6 100644
--- a/engines/toltecs/menu.cpp
+++ b/engines/toltecs/menu.cpp
@@ -525,7 +525,7 @@ int MenuSystem::loadSavegamesList() {
if (slotNum >= 0 && slotNum <= 999) {
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
if (in) {
- if (Toltecs::ToltecsEngine::readSaveHeader(in, false, header) == Toltecs::ToltecsEngine::kRSHENoError) {
+ if (Toltecs::ToltecsEngine::readSaveHeader(in, header) == Toltecs::ToltecsEngine::kRSHENoError) {
_savegames.push_back(SavegameItem(slotNum, header.description));
//debug("%s -> %s", file->c_str(), header.description.c_str());
}
diff --git a/engines/toltecs/saveload.cpp b/engines/toltecs/saveload.cpp
index 409fc97076..1f2198fc35 100644
--- a/engines/toltecs/saveload.cpp
+++ b/engines/toltecs/saveload.cpp
@@ -41,7 +41,7 @@ namespace Toltecs {
#define TOLTECS_SAVEGAME_VERSION 4
-ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header) {
+WARN_UNUSED_RESULT ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail) {
header.version = in->readUint32LE();
if (header.version > TOLTECS_SAVEGAME_VERSION)
@@ -52,10 +52,8 @@ ToltecsEngine::kReadSaveHeaderError ToltecsEngine::readSaveHeader(Common::Seekab
while (descriptionLen--)
header.description += (char)in->readByte();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*in);
- } else {
- Graphics::skipThumbnail(*in);
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
+ return kRSHEIoError;
}
// Not used yet, reserved for future usage
@@ -147,7 +145,7 @@ void ToltecsEngine::loadgame(const char *filename) {
SaveHeader header;
- kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
+ kReadSaveHeaderError errorCode = readSaveHeader(in, header);
if (errorCode != kRSHENoError) {
warning("Error loading savegame '%s'", filename);
diff --git a/engines/toltecs/toltecs.h b/engines/toltecs/toltecs.h
index ece82f4a1a..1c9e9366c7 100644
--- a/engines/toltecs/toltecs.h
+++ b/engines/toltecs/toltecs.h
@@ -225,7 +225,7 @@ public:
const char *getSavegameFilename(int num);
static Common::String getSavegameFilename(const Common::String &target, int num);
- static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, bool loadThumbnail, SaveHeader &header);
+ WARN_UNUSED_RESULT static kReadSaveHeaderError readSaveHeader(Common::SeekableReadStream *in, SaveHeader &header, bool skipThumbnail = true);
};
diff --git a/engines/toon/detection.cpp b/engines/toon/detection.cpp
index e93d676d87..6eb38c4883 100644
--- a/engines/toon/detection.cpp
+++ b/engines/toon/detection.cpp
@@ -232,7 +232,11 @@ SaveStateDescriptor ToonMetaEngine::querySaveMetaInfos(const char *target, int s
SaveStateDescriptor desc(slot, saveName);
- Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(*file, thumbnail)) {
+ delete file;
+ return SaveStateDescriptor();
+ }
desc.setThumbnail(thumbnail);
uint32 saveDate = file->readUint32BE();
diff --git a/engines/tsage/detection.cpp b/engines/tsage/detection.cpp
index e476391f71..5d31cca75e 100644
--- a/engines/tsage/detection.cpp
+++ b/engines/tsage/detection.cpp
@@ -131,9 +131,6 @@ public:
if (in) {
if (TsAGE::Saver::readSavegameHeader(in, header)) {
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
-
- header._thumbnail->free();
- delete header._thumbnail;
}
delete in;
@@ -161,7 +158,11 @@ public:
if (f) {
TsAGE::tSageSavegameHeader header;
- TsAGE::Saver::readSavegameHeader(f, header);
+ if (!TsAGE::Saver::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp
index 03f615db21..81bb973d02 100644
--- a/engines/tsage/saveload.cpp
+++ b/engines/tsage/saveload.cpp
@@ -189,10 +189,10 @@ Common::Error Saver::restore(int slot) {
// Read in the savegame header
tSageSavegameHeader header;
- readSavegameHeader(saveFile, header);
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
+ if (!readSavegameHeader(saveFile, header)) {
+ delete saveFile;
+ return Common::kReadingFailed;
+ }
serializer.setSaveVersion(header._version);
@@ -247,9 +247,8 @@ Common::Error Saver::restore(int slot) {
const char *SAVEGAME_STR = "SCUMMVM_TSAGE";
#define SAVEGAME_STR_SIZE 13
-bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header) {
+WARN_UNUSED_RESULT bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = NULL;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -266,9 +265,9 @@ bool Saver::readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &head
while ((ch = (char)in->readByte()) != '\0') header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._saveYear = in->readSint16LE();
diff --git a/engines/tsage/saveload.h b/engines/tsage/saveload.h
index 04a1e02b28..3de34489fd 100644
--- a/engines/tsage/saveload.h
+++ b/engines/tsage/saveload.h
@@ -221,7 +221,7 @@ public:
Common::Error save(int slot, const Common::String &saveName);
Common::Error restore(int slot);
- static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail = true);
static void writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header);
void addListener(SaveListener *obj);
diff --git a/engines/tucker/detection.cpp b/engines/tucker/detection.cpp
index 7d07edabd3..119d60f23a 100644
--- a/engines/tucker/detection.cpp
+++ b/engines/tucker/detection.cpp
@@ -175,7 +175,7 @@ public:
if (ext && (slot = atoi(ext + 1)) >= 0 && slot <= Tucker::kLastSaveSlot) {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- if (Tucker::TuckerEngine::readSavegameHeader(in, header, false) == Tucker::TuckerEngine::kSavegameNoError) {
+ if (Tucker::TuckerEngine::readSavegameHeader(in, header) == Tucker::TuckerEngine::kSavegameNoError) {
saveList.push_back(SaveStateDescriptor(slot, header.description));
}
@@ -207,7 +207,7 @@ public:
}
Tucker::TuckerEngine::SavegameHeader header;
- Tucker::TuckerEngine::SavegameError savegameError = Tucker::TuckerEngine::readSavegameHeader(file, header, true);
+ Tucker::TuckerEngine::SavegameError savegameError = Tucker::TuckerEngine::readSavegameHeader(file, header, false);
if (savegameError) {
delete file;
return SaveStateDescriptor();
diff --git a/engines/tucker/saveload.cpp b/engines/tucker/saveload.cpp
index a56ced915e..484c47e5da 100644
--- a/engines/tucker/saveload.cpp
+++ b/engines/tucker/saveload.cpp
@@ -141,7 +141,7 @@ Common::Error TuckerEngine::loadGameState(int slot) {
}
-TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, int slot, SavegameHeader &header) {
+WARN_UNUSED_RESULT TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target, int slot, SavegameHeader &header) {
Common::String fileName = generateGameStateFileName(target, slot);
Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
@@ -155,7 +155,7 @@ TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(const char *target,
return savegameError;
}
-TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool loadThumbnail) {
+WARN_UNUSED_RESULT TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool skipThumbnail) {
header.version = -1;
header.flags = 0;
header.description.clear();
@@ -196,10 +196,8 @@ TuckerEngine::SavegameError TuckerEngine::readSavegameHeader(Common::InSaveFile
header.saveTime = file->readUint32LE();
header.playTime = file->readUint32LE();
- if (loadThumbnail) {
- header.thumbnail = Graphics::loadThumbnail(*file);
- } else {
- Graphics::skipThumbnail(*file);
+ if (!Graphics::loadThumbnail(*file, header.thumbnail, skipThumbnail)) {
+ return kSavegameIoError;
}
}
diff --git a/engines/tucker/tucker.h b/engines/tucker/tucker.h
index 4cb427fe35..e3748680fe 100644
--- a/engines/tucker/tucker.h
+++ b/engines/tucker/tucker.h
@@ -452,8 +452,8 @@ public:
virtual bool hasFeature(EngineFeature f) const;
GUI::Debugger *getDebugger() { return _console; }
- static SavegameError readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool loadThumbnail = false);
- static SavegameError readSavegameHeader(const char *target, int slot, SavegameHeader &header);
+ WARN_UNUSED_RESULT static SavegameError readSavegameHeader(Common::InSaveFile *file, SavegameHeader &header, bool skipThumbnail = true);
+ WARN_UNUSED_RESULT static SavegameError readSavegameHeader(const char *target, int slot, SavegameHeader &header);
bool isAutosaveAllowed();
static bool isAutosaveAllowed(const char *target);
protected:
diff --git a/engines/voyeur/detection.cpp b/engines/voyeur/detection.cpp
index eefe174e94..6452e5741f 100644
--- a/engines/voyeur/detection.cpp
+++ b/engines/voyeur/detection.cpp
@@ -132,7 +132,6 @@ SaveStateList VoyeurMetaEngine::listSaves(const char *target) const {
if (in) {
if (header.read(in)) {
saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- header._thumbnail->free();
}
delete in;
}
@@ -159,7 +158,7 @@ SaveStateDescriptor VoyeurMetaEngine::querySaveMetaInfos(const char *target, int
if (f) {
Voyeur::VoyeurSavegameHeader header;
- header.read(f);
+ header.read(f, false);
delete f;
// Create the return descriptor
diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp
index 7f2f0e312e..b7769c1fd4 100644
--- a/engines/voyeur/voyeur.cpp
+++ b/engines/voyeur/voyeur.cpp
@@ -789,9 +789,6 @@ void VoyeurEngine::loadGame(int slot) {
VoyeurSavegameHeader header;
if (!header.read(saveFile))
return;
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
serializer.setVersion(header._version);
synchronize(serializer);
@@ -856,9 +853,7 @@ void VoyeurEngine::synchronize(Common::Serializer &s) {
/*------------------------------------------------------------------------*/
-bool VoyeurSavegameHeader::read(Common::InSaveFile *f) {
- _thumbnail = NULL;
-
+bool VoyeurSavegameHeader::read(Common::InSaveFile *f, bool skipThumbnail) {
uint32 signature = f->readUint32BE();
if (signature != MKTAG('V', 'O', 'Y', 'R')) {
warning("Invalid savegame");
@@ -875,9 +870,9 @@ bool VoyeurSavegameHeader::read(Common::InSaveFile *f) {
_saveName += c;
// Get the thumbnail
- _thumbnail = Graphics::loadThumbnail(*f);
- if (!_thumbnail)
+ if (!Graphics::loadThumbnail(*f, _thumbnail, skipThumbnail)) {
return false;
+ }
// Read in the save datet/ime
_saveYear = f->readSint16LE();
diff --git a/engines/voyeur/voyeur.h b/engines/voyeur/voyeur.h
index dcd82b24a9..a098ba9e62 100644
--- a/engines/voyeur/voyeur.h
+++ b/engines/voyeur/voyeur.h
@@ -312,7 +312,7 @@ struct VoyeurSavegameHeader {
/**
* Read in the header from the specified file
*/
- bool read(Common::InSaveFile *f);
+ bool read(Common::InSaveFile *f, bool skipThumbnail = true);
/**
* Write out header information to the specified file
diff --git a/engines/xeen/detection.cpp b/engines/xeen/detection.cpp
index 49b74b24a2..abf82188a9 100644
--- a/engines/xeen/detection.cpp
+++ b/engines/xeen/detection.cpp
@@ -170,12 +170,9 @@ SaveStateList XeenMetaEngine::listSaves(const char *target) const {
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
if (in) {
- Xeen::SavesManager::readSavegameHeader(in, header);
- saveList.push_back(SaveStateDescriptor(slot, header._saveName));
+ if (Xeen::SavesManager::readSavegameHeader(in, header))
+ saveList.push_back(SaveStateDescriptor(slot, header._saveName));
- if (header._thumbnail)
- header._thumbnail->free();
- delete header._thumbnail;
delete in;
}
}
@@ -200,7 +197,11 @@ SaveStateDescriptor XeenMetaEngine::querySaveMetaInfos(const char *target, int s
if (f) {
Xeen::XeenSavegameHeader header;
- Xeen::SavesManager::readSavegameHeader(f, header);
+ if (!Xeen::SavesManager::readSavegameHeader(f, header, false)) {
+ delete f;
+ return SaveStateDescriptor();
+ }
+
delete f;
// Create the return descriptor
diff --git a/engines/xeen/saves.cpp b/engines/xeen/saves.cpp
index 1f58562bf0..2f290960d3 100644
--- a/engines/xeen/saves.cpp
+++ b/engines/xeen/saves.cpp
@@ -48,9 +48,8 @@ SavesManager::~SavesManager() {
const char *const SAVEGAME_STR = "XEEN";
#define SAVEGAME_STR_SIZE 6
-bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header) {
+WARN_UNUSED_RESULT bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header, bool skipThumbnail) {
char saveIdentBuffer[SAVEGAME_STR_SIZE + 1];
- header._thumbnail = nullptr;
// Validate the header Id
in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1);
@@ -68,9 +67,9 @@ bool SavesManager::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader
header._saveName += ch;
// Get the thumbnail
- header._thumbnail = Graphics::loadThumbnail(*in);
- if (!header._thumbnail)
+ if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header._year = in->readSint16LE();
@@ -168,11 +167,6 @@ Common::Error SavesManager::loadGameState(int slot) {
if (!readSavegameHeader(saveFile, header))
error("Invalid savegame");
- if (header._thumbnail) {
- header._thumbnail->free();
- delete header._thumbnail;
- }
-
// Set the total play time
events.setPlayTime(header._totalFrames);
diff --git a/engines/xeen/saves.h b/engines/xeen/saves.h
index b18e04a822..9b1bea62a3 100644
--- a/engines/xeen/saves.h
+++ b/engines/xeen/saves.h
@@ -65,7 +65,7 @@ public:
/**
* Read in a savegame header
*/
- static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header);
+ WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header, bool skipThumbnail = true);
/**
* Write out a savegame header
diff --git a/engines/zvision/detection.cpp b/engines/zvision/detection.cpp
index 5e535a9954..896ea52344 100644
--- a/engines/zvision/detection.cpp
+++ b/engines/zvision/detection.cpp
@@ -178,7 +178,7 @@ SaveStateDescriptor ZVisionMetaEngine::querySaveMetaInfos(const char *target, in
// We only use readSaveGameHeader() here, which doesn't need an engine callback
ZVision::SaveManager *zvisionSaveMan = new ZVision::SaveManager(NULL);
- bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header);
+ bool successfulRead = zvisionSaveMan->readSaveGameHeader(in, header, false);
delete zvisionSaveMan;
delete in;
diff --git a/engines/zvision/file/save_manager.cpp b/engines/zvision/file/save_manager.cpp
index 4259937a3b..b33d33cdf1 100644
--- a/engines/zvision/file/save_manager.cpp
+++ b/engines/zvision/file/save_manager.cpp
@@ -189,7 +189,7 @@ Common::Error SaveManager::loadGame(int slot) {
return Common::kNoError;
}
-bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header) {
+bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &header, bool skipThumbnail) {
uint32 tag = in->readUint32BE();
// Check if it's original savegame than fill header structure
if (tag == MKTAG('Z', 'N', 'S', 'G')) {
@@ -232,9 +232,9 @@ bool SaveManager::readSaveGameHeader(Common::InSaveFile *in, SaveGameHeader &hea
header.saveName += ch;
// Get the thumbnail
- header.thumbnail = Graphics::loadThumbnail(*in);
- if (!header.thumbnail)
+ if (!Graphics::loadThumbnail(*in, header.thumbnail, skipThumbnail)) {
return false;
+ }
// Read in save date/time
header.saveYear = in->readSint16LE();
diff --git a/engines/zvision/file/save_manager.h b/engines/zvision/file/save_manager.h
index 9e816373ea..94885b650b 100644
--- a/engines/zvision/file/save_manager.h
+++ b/engines/zvision/file/save_manager.h
@@ -94,7 +94,7 @@ public:
Common::Error loadGame(int slot);
Common::SeekableReadStream *getSlotFile(uint slot);
- bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header);
+ bool readSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &header, bool skipThumbnail = true);
void prepareSaveBuffer();
void flushSaveBuffer();
diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp
index a3037e5ad5..72a06f91ec 100644
--- a/graphics/thumbnail.cpp
+++ b/graphics/thumbnail.cpp
@@ -147,7 +147,11 @@ bool skipThumbnail(Common::SeekableReadStream &in) {
return true;
}
-Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail) {
+ if (skipThumbnail) {
+ return Graphics::skipThumbnail(in);
+ }
+
const uint32 position = in.pos();
ThumbnailHeader header;
HeaderState headerState = loadHeader(in, header, true);
@@ -160,32 +164,32 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
// stream at this point then.
if (headerState == kHeaderNone) {
in.seek(position, SEEK_SET);
- return 0;
+ return false;
} else if (headerState == kHeaderUnsupported) {
in.seek(header.size - (in.pos() - position), SEEK_CUR);
- return 0;
+ return false;
}
if (header.format.bytesPerPixel != 2 && header.format.bytesPerPixel != 4) {
warning("trying to load thumbnail with unsupported bit depth %d", header.format.bytesPerPixel);
- return 0;
+ return false;
}
- Graphics::Surface *const to = new Graphics::Surface();
- to->create(header.width, header.height, header.format);
+ thumbnail = new Graphics::Surface();
+ thumbnail->create(header.width, header.height, header.format);
- for (int y = 0; y < to->h; ++y) {
+ for (int y = 0; y < thumbnail->h; ++y) {
switch (header.format.bytesPerPixel) {
case 2: {
- uint16 *pixels = (uint16 *)to->getBasePtr(0, y);
- for (uint x = 0; x < to->w; ++x) {
+ uint16 *pixels = (uint16 *)thumbnail->getBasePtr(0, y);
+ for (uint x = 0; x < thumbnail->w; ++x) {
*pixels++ = in.readUint16BE();
}
} break;
case 4: {
- uint32 *pixels = (uint32 *)to->getBasePtr(0, y);
- for (uint x = 0; x < to->w; ++x) {
+ uint32 *pixels = (uint32 *)thumbnail->getBasePtr(0, y);
+ for (uint x = 0; x < thumbnail->w; ++x) {
*pixels++ = in.readUint32BE();
}
} break;
@@ -194,7 +198,7 @@ Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
assert(0);
}
}
- return to;
+ return true;
}
bool saveThumbnail(Common::WriteStream &out) {
diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h
index cec3d02800..17ce856e23 100644
--- a/graphics/thumbnail.h
+++ b/graphics/thumbnail.h
@@ -52,7 +52,7 @@ bool skipThumbnail(Common::SeekableReadStream &in);
/**
* Loads a thumbnail from the given input stream.
*/
-Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in);
+bool loadThumbnail(Common::SeekableReadStream &in, Graphics::Surface *&thumbnail, bool skipThumbnail = false);
/**
* Saves a thumbnail to the given write stream.