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.
This commit is contained in:
Eladash 2020-03-12 18:46:50 +02:00 committed by Ivan
parent fdf47f43d8
commit 54af8ec544

View File

@ -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<std::vector<uchar>>();
}
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<std::vector<uchar>>();
}
// 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<std::vector<uchar>>();
}
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<std::vector<uchar>>();
}
// Write to memory file normally
const u64 sr = file.seek(fileSet->fileOffset);
const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, fileSet->fileSize);