From 54af8ec54483b11c4b17c8bac6fbbc28fa46d6a8 Mon Sep 17 00:00:00 2001 From: Eladash Date: Thu, 12 Mar 2020 18:46:50 +0200 Subject: [PATCH] cellSaveData: funcFile fixes * Allow '_' at filenames start and extension. * Check if reading offset is valid, fix error code to CELL_SAVEDATA_ERROR_FAILURE. * Don't create empty file on error of write ops. * Don't allow "." and ".." filenames on funcFile, return CELL_SAVEDATA_ERROR_BROKEN. --- rpcs3/Emu/Cell/Modules/cellSaveData.cpp | 81 +++++++++++++------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index 4b9f1e8ac3..d842a828d8 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -1442,6 +1442,12 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v // Allow multiple '.' even though sysutil_check_name_string does not std::replace(name, name + dotpos, '.', '-'); + // Allow '_' at start even though sysutil_check_name_string does not + if (name[0] == '_') + { + name[0] = '-'; + } + // Check filename if (sysutil_check_name_string(name, 1, 9) == -1) { @@ -1459,6 +1465,12 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v gsl::span dst(name, file_path.size() - dotpos); strcpy_trunc(dst, file_path.operator std::string_view().substr(dotpos + 1)); + // Allow '_' at start even though sysutil_check_name_string does not + if (name[0] == '_') + { + name[0] = '-'; + } + // Check file extension if (sysutil_check_name_string(name, 1, 4) == -1) { @@ -1532,26 +1544,16 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v }; // clang-format on + if ((file_path == "." || file_path == "..") && fileSet->fileOperation <= CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC) + { + savedata_result = CELL_SAVEDATA_ERROR_BROKEN; + break; + } + switch (const u32 op = fileSet->fileOperation) { case CELL_SAVEDATA_FILEOP_READ: { - fs::file& file = all_files[file_path]; - - // TODO: Check this - //if (!fileSet->fileSize) - //{ - // break; - //} - - if (!file) - { - // ****** sysutil savedata parameter error : 22 ****** - cellSaveData.error("Failed to open file %s%s", dir_path, file_path); - savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "22"}; - break; - } - if (fileSet->fileBufSize < fileSet->fileSize) { // ****** sysutil savedata parameter error : 72 ****** @@ -1566,6 +1568,15 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v break; } + const fs::file& file = all_files[file_path]; + + if (!file || file.size() <= fileSet->fileOffset) + { + cellSaveData.error("Failed to open file %s%s", dir_path, file_path); + savedata_result = CELL_SAVEDATA_ERROR_FAILURE; + break; + } + // Read from memory file to vm const u64 sr = file.seek(fileSet->fileOffset); const u64 rr = lv2_file::op_read(file, fileSet->fileBuf, fileSet->fileSize); @@ -1575,18 +1586,6 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v case CELL_SAVEDATA_FILEOP_WRITE: { - fs::file& file = all_files[file_path]; - - //if (!fileSet->fileSize) - //{ - // break; - //} - - if (!file) - { - file = fs::make_stream>(); - } - if (fileSet->fileBufSize < fileSet->fileSize) { // ****** sysutil savedata parameter error : 72 ****** @@ -1601,6 +1600,13 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v break; } + fs::file& file = all_files[file_path]; + + if (!file) + { + file = fs::make_stream>(); + } + // Write to memory file and truncate const u64 sr = file.seek(fileSet->fileOffset); const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, fileSet->fileSize); @@ -1626,18 +1632,6 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC: { - fs::file& file = all_files[file_path]; - - //if (!fileSet->fileSize) - //{ - // break; - //} - - if (!file) - { - file = fs::make_stream>(); - } - if (fileSet->fileBufSize < fileSet->fileSize) { // ****** sysutil savedata parameter error : 72 ****** @@ -1652,6 +1646,13 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v break; } + fs::file& file = all_files[file_path]; + + if (!file) + { + file = fs::make_stream>(); + } + // Write to memory file normally const u64 sr = file.seek(fileSet->fileOffset); const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, fileSet->fileSize);