arch codereview

This commit is contained in:
2026-04-25 09:55:34 +03:00
parent 3e19149cb4
commit 7515e0334b
12 changed files with 579 additions and 487 deletions
+29 -12
View File
@@ -178,24 +178,31 @@ std::tuple<bool, Result, std::string> io::backup(size_t index, AccountUid uid)
std::string dstPath = title.path() + "/" + suggestion;
if (io::directoryExists(dstPath)) {
int rc = io::deleteFolderRecursively((dstPath + "/").c_str());
if (rc != 0) {
FileSystem::unmount();
Logger::getInstance().log(Logger::ERROR, "Failed to recursively delete directory " + dstPath + " with result %d.", rc);
return std::make_tuple(false, (Result)rc, "Failed to delete the existing backup\ndirectory recursively.");
}
// Write to a temp dir first; rename on success so the existing backup
// is never destroyed if the copy is interrupted mid-way.
std::string tmpPath = dstPath + ".tmp";
if (io::directoryExists(tmpPath)) {
io::deleteFolderRecursively((tmpPath + "/").c_str());
}
io::createDirectory(dstPath);
res = io::copyDirectory("save:/", dstPath + "/");
io::createDirectory(tmpPath);
res = io::copyDirectory("save:/", tmpPath + "/");
if (R_FAILED(res)) {
FileSystem::unmount();
io::deleteFolderRecursively((dstPath + "/").c_str());
Logger::getInstance().log(Logger::ERROR, "Failed to copy directory " + dstPath + " with result 0x%08lX. Skipping...", res);
io::deleteFolderRecursively((tmpPath + "/").c_str());
Logger::getInstance().log(Logger::ERROR, "Failed to copy directory to " + tmpPath + " with result 0x%08lX.", res);
return std::make_tuple(false, res, "Failed to backup save.");
}
// Swap: delete old backup only after new one is fully written.
if (io::directoryExists(dstPath)) {
io::deleteFolderRecursively((dstPath + "/").c_str());
}
if (rename(tmpPath.c_str(), dstPath.c_str()) != 0) {
FileSystem::unmount();
Logger::getInstance().log(Logger::ERROR, "Failed to rename temp backup to " + dstPath);
return std::make_tuple(false, (Result)-1, "Failed to finalise backup.");
}
refreshDirectories(title.id());
FileSystem::unmount();
@@ -266,6 +273,16 @@ std::tuple<bool, Result, std::string> io::restore(size_t index, AccountUid uid,
std::string srcPath = title.path() + "/" + suggestion + "/";
std::string dstPath = "save:/";
// Validate source exists and is non-empty before touching live save data.
{
Directory srcCheck(srcPath);
if (!srcCheck.good() || srcCheck.size() == 0) {
FileSystem::unmount();
Logger::getInstance().log(Logger::ERROR, "Restore source is empty or missing: " + srcPath);
return std::make_tuple(false, (Result)-1, "Restore source is empty or missing.");
}
}
{
Directory saveRoot(dstPath);
for (size_t i = 0, sz = saveRoot.size(); i < sz; i++) {