cellSaveData: refactor param error 70 checks

Also extend the check to check empty name.
This commit is contained in:
Eladash 2020-03-09 20:18:03 +02:00 committed by Ivan
parent 2ae83782e1
commit fdf47f43d8

View file

@ -11,6 +11,7 @@
#include "Loader/PSF.h" #include "Loader/PSF.h"
#include "Utilities/StrUtil.h" #include "Utilities/StrUtil.h"
#include "Utilities/span.h"
#include <thread> #include <thread>
#include <mutex> #include <mutex>
@ -1400,64 +1401,75 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
break; break;
} }
const auto fileName = fileSet->fileName.get_ptr(); const char* fileName = fileSet->fileName.get_ptr();
const auto termpos = std::find(fileName, fileName + CELL_SAVEDATA_FILENAME_SIZE, '\0'); if (const auto termpos = std::memchr(fileName, '\0', CELL_SAVEDATA_FILENAME_SIZE))
{
if (termpos == fileName + CELL_SAVEDATA_FILENAME_SIZE) file_path.assign(fileName, static_cast<const char*>(termpos));
}
else
{ {
// ****** sysutil savedata parameter error : 71 ****** // ****** sysutil savedata parameter error : 71 ******
savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "71"}; savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "71"};
break; break;
} }
char name[10]; auto dotpos = file_path.find_last_of('.');
name[0] = '.';
const auto dotpos = std::find_end(fileName, termpos, name, name + 1); if (dotpos == umax)
if (dotpos > fileName + 8 || termpos - dotpos > 4)
{ {
// Point to end of string instead
dotpos = file_path.size();
}
if (file_path.empty() || dotpos > 8u || file_path.size() - dotpos > 4u)
{
cellSaveData.error("savedata_op(): fileSet->fileName is illegal ('%s')", file_path);
// ****** sysutil savedata parameter error : 70 ****** // ****** sysutil savedata parameter error : 70 ******
savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "70"}; savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "70"};
break; break;
} }
if (dotpos != fileName) char name[10];
if (dotpos)
{ {
// Reset for filename // Copy file name
std::memset(name, 0, 10); gsl::span dst(name, dotpos + 1);
std::copy(fileName, dotpos, name); strcpy_trunc(dst, file_path);
// Allow multiple '.' even though sysutil_check_name_string does not // Allow multiple '.' even though sysutil_check_name_string does not
std::replace(name, name + 9, '.', '-'); std::replace(name, name + dotpos, '.', '-');
// Check filename // Check filename
if (sysutil_check_name_string(name, 1, 9) == -1) if (sysutil_check_name_string(name, 1, 9) == -1)
{ {
cellSaveData.error("savedata_op(): fileSet->fileName is illegal due to file name ('%s')", file_path);
// ****** sysutil savedata parameter error : 70 ****** // ****** sysutil savedata parameter error : 70 ******
savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "70"}; savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "70"};
break; break;
} }
} }
if (dotpos < termpos - 1) if (file_path.size() > dotpos + 1)
{ {
// Reset for file extension // Copy file extension
std::memset(name, 0, 5); gsl::span dst(name, file_path.size() - dotpos);
std::copy(dotpos + 1, termpos, name); strcpy_trunc(dst, file_path.operator std::string_view().substr(dotpos + 1));
// Check file extension // Check file extension
if (sysutil_check_name_string(name, 1, 4) == -1) if (sysutil_check_name_string(name, 1, 4) == -1)
{ {
cellSaveData.error("savedata_op(): fileSet->fileName is illegal due to file extension ('%s')", file_path);
// ****** sysutil savedata parameter error : 70 ****** // ****** sysutil savedata parameter error : 70 ******
savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "70"}; savedata_result = {CELL_SAVEDATA_ERROR_PARAM, "70"};
break; break;
} }
} }
file_path = fileName;
if (type == CELL_SAVEDATA_FILETYPE_SECUREFILE) if (type == CELL_SAVEDATA_FILETYPE_SECUREFILE)
{ {
cellSaveData.notice("SECUREFILE: %s -> %s", file_path, fileSet->secureFileId); cellSaveData.notice("SECUREFILE: %s -> %s", file_path, fileSet->secureFileId);
@ -1501,8 +1513,6 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
psf.emplace("*" + file_path, fileSet->fileType == CELL_SAVEDATA_FILETYPE_SECUREFILE); psf.emplace("*" + file_path, fileSet->fileType == CELL_SAVEDATA_FILETYPE_SECUREFILE);
const u32 access_size = std::min<u32>(fileSet->fileSize, fileSet->fileBufSize);
// clang-format off // clang-format off
auto add_to_blist = [&](const std::string& to_add) auto add_to_blist = [&](const std::string& to_add)
{ {
@ -1558,7 +1568,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
// Read from memory file to vm // Read from memory file to vm
const u64 sr = file.seek(fileSet->fileOffset); const u64 sr = file.seek(fileSet->fileOffset);
const u64 rr = lv2_file::op_read(file, fileSet->fileBuf, access_size); const u64 rr = lv2_file::op_read(file, fileSet->fileBuf, fileSet->fileSize);
fileGet->excSize = ::narrow<u32>(rr); fileGet->excSize = ::narrow<u32>(rr);
break; break;
} }
@ -1593,7 +1603,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
// Write to memory file and truncate // Write to memory file and truncate
const u64 sr = file.seek(fileSet->fileOffset); const u64 sr = file.seek(fileSet->fileOffset);
const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, access_size); const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, fileSet->fileSize);
file.trunc(sr + wr); file.trunc(sr + wr);
fileGet->excSize = ::narrow<u32>(wr); fileGet->excSize = ::narrow<u32>(wr);
all_times.erase(file_path); all_times.erase(file_path);
@ -1644,7 +1654,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
// Write to memory file normally // Write to memory file normally
const u64 sr = file.seek(fileSet->fileOffset); const u64 sr = file.seek(fileSet->fileOffset);
const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, access_size); const u64 wr = lv2_file::op_write(file, fileSet->fileBuf, fileSet->fileSize);
fileGet->excSize = ::narrow<u32>(wr); fileGet->excSize = ::narrow<u32>(wr);
all_times.erase(file_path); all_times.erase(file_path);
add_to_blist(file_path); add_to_blist(file_path);