mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-11 08:39:28 +01:00
Savedata: Keep the list count at 0 when a name in the list is rejected
The multi-name path counted names straight into saveDataListCount, so returning on a path traversal name left a count behind with the list already freed by Clear(). The next savestate then serialized that many entries from a null list and crashed in Do(std::string). Count on the side, and don't write entries for a list that isn't there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
476d020c58
commit
e10ebbeb44
1 file changed
+10
-5
@@ -1557,18 +1557,20 @@ int SavedataParam::SetPspParam(SceUtilitySavedataParam *param) {
|
||||
|
||||
saveNameListData = param->saveNameList;
|
||||
|
||||
// Get number of fileName in array
|
||||
saveDataListCount = 0;
|
||||
while (saveNameListData[saveDataListCount][0] != 0) {
|
||||
// Get number of fileName in array. Counted on the side, so a rejected name leaves the
|
||||
// count at 0 to match the list Clear() freed (a savestate walks that many entries).
|
||||
int count = 0;
|
||||
while (saveNameListData[count][0] != 0) {
|
||||
// saveName entries become part of host filesystem paths; reject
|
||||
// path separators and bare dot components (path traversal).
|
||||
const std::string_view entry = StringViewFromFixedSizeField(saveNameListData[saveDataListCount]);
|
||||
const std::string_view entry = StringViewFromFixedSizeField(saveNameListData[count]);
|
||||
if (HasPathTraversal(entry)) {
|
||||
ERROR_LOG(Log::sceUtility, "SavedataParam: invalid saveName in list: %s", std::string(entry).c_str());
|
||||
return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE;
|
||||
}
|
||||
saveDataListCount++;
|
||||
count++;
|
||||
}
|
||||
saveDataListCount = count;
|
||||
|
||||
if (saveDataListCount > 0) {
|
||||
hasMultipleFileName = true;
|
||||
@@ -2015,6 +2017,9 @@ void SavedataParam::DoState(PointerWrap &p) {
|
||||
|
||||
// pspParam is handled in PSPSaveDialog.
|
||||
Do(p, selectedSave);
|
||||
if (p.mode != p.MODE_READ && !saveDataList) {
|
||||
saveDataListCount = 0;
|
||||
}
|
||||
Do(p, saveDataListCount);
|
||||
Do(p, saveNameListDataCount);
|
||||
if (p.mode == p.MODE_READ) {
|
||||
|
||||
Reference in new issue
Block a user