mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-30 19:24:23 +01:00
Savedata: Return errors more correctly on load.
If the buffer isn't large enough, return an error. See #14687, thanks sum2012 and gid15. For many error cases, ensure SFO data and bind are not updated on failure, and that dataSize is forced to zero on data errors.
This commit is contained in:
1 parent
a0515bf5ca
commit
ce80900b75
2 files changed
+35
-21
No files matched your search
@@ -1149,7 +1149,9 @@ void PSPSaveDialog::ExecuteNotVisibleIOAction() {
|
||||
case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
|
||||
case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
|
||||
result = param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE);
|
||||
if(result == SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA)
|
||||
if (result == SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN)
|
||||
result = SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN;
|
||||
if (result == SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA)
|
||||
result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA;
|
||||
break;
|
||||
case SCE_UTILITY_SAVEDATA_TYPE_ERASE:
|
||||
|
||||
@@ -589,15 +589,22 @@ int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveD
|
||||
return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA : SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA;
|
||||
}
|
||||
|
||||
if (fileName != "" && !pspFileSystem.GetFileInfo(filePath).exists) {
|
||||
return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND : SCE_UTILITY_SAVEDATA_ERROR_LOAD_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
// If it wasn't zero, force to zero before loading and especially in case of error.
|
||||
// This isn't reset if the path doesn't even exist.
|
||||
param->dataSize = 0;
|
||||
int result = LoadSaveData(param, saveDirName, dirPath, secureMode);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
// Load sfo
|
||||
if (!LoadSFO(param, dirPath)) {
|
||||
return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_DATA_BROKEN : SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN;
|
||||
}
|
||||
|
||||
if (fileName != "" && !pspFileSystem.GetFileInfo(filePath).exists) {
|
||||
return isRWMode ? SCE_UTILITY_SAVEDATA_ERROR_RW_FILE_NOT_FOUND : SCE_UTILITY_SAVEDATA_ERROR_LOAD_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
// Don't know what it is, but PSP always respond this and this unlock some game
|
||||
param->bind = 1021;
|
||||
|
||||
@@ -612,15 +619,6 @@ int SavedataParam::Load(SceUtilitySavedataParam *param, const std::string &saveD
|
||||
// Load SND0.AT3
|
||||
LoadFile(dirPath, SND0_FILENAME, ¶m->snd0FileData);
|
||||
|
||||
if (fileName == "") {
|
||||
// Don't load savedata but return success.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = LoadSaveData(param, saveDirName, dirPath, secureMode);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -638,6 +636,10 @@ int SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::strin
|
||||
|
||||
std::string filename = GetFileName(param);
|
||||
std::string filePath = dirPath + "/" + filename;
|
||||
// Blank filename always means success, if secureVersion was correct.
|
||||
if (filename == "")
|
||||
return 0;
|
||||
|
||||
s64 readSize;
|
||||
INFO_LOG(SCEUTILITY, "Loading file with size %u in %s", param->dataBufSize, filePath.c_str());
|
||||
u8 *saveData = nullptr;
|
||||
@@ -667,14 +669,18 @@ int SavedataParam::LoadSaveData(SceUtilitySavedataParam *param, const std::strin
|
||||
if (!saveDone) {
|
||||
loadedSize = LoadNotCryptedSave(param, param->dataBuf, saveData, saveSize);
|
||||
}
|
||||
param->dataSize = (SceSize)saveSize;
|
||||
delete[] saveData;
|
||||
|
||||
if (loadedSize != 0) {
|
||||
// Ignore error codes.
|
||||
if (loadedSize != 0 && (loadedSize & 0x80000000) == 0) {
|
||||
std::string tag = "LoadSaveData/" + filePath;
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, param->dataBuf.ptr, loadedSize, tag.c_str(), tag.size());
|
||||
}
|
||||
|
||||
if ((loadedSize & 0x80000000) != 0)
|
||||
return loadedSize;
|
||||
|
||||
param->dataSize = (SceSize)saveSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -760,8 +766,12 @@ u32 SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, con
|
||||
u32 sz = 0;
|
||||
if (err == 0) {
|
||||
if (param->dataBuf.IsValid()) {
|
||||
sz = std::min((u32)saveSize, (u32)param->dataBufSize);
|
||||
memcpy(data, data_base, sz);
|
||||
if ((u32)saveSize > param->dataBufSize || !Memory::IsValidRange(param->dataBuf.ptr, saveSize)) {
|
||||
sz = SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN;
|
||||
} else {
|
||||
sz = (u32)saveSize;
|
||||
memcpy(data, data_base, sz);
|
||||
}
|
||||
}
|
||||
saveDone = true;
|
||||
}
|
||||
@@ -773,9 +783,11 @@ u32 SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, con
|
||||
|
||||
u32 SavedataParam::LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize) {
|
||||
if (param->dataBuf.IsValid()) {
|
||||
u32 sz = std::min((u32)saveSize, (u32)param->dataBufSize);
|
||||
memcpy(data, saveData, sz);
|
||||
return sz;
|
||||
if ((u32)saveSize > param->dataBufSize || !Memory::IsValidRange(param->dataBuf.ptr, saveSize)) {
|
||||
return SCE_UTILITY_SAVEDATA_ERROR_LOAD_DATA_BROKEN;
|
||||
}
|
||||
memcpy(data, saveData, saveSize);
|
||||
return saveSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user