From cc5da07eaa10db92529dc2106d390f85cb0b19ed Mon Sep 17 00:00:00 2001 From: J-D-K Date: Thu, 2 Oct 2025 13:09:27 -0400 Subject: [PATCH] Add replacement table for sanitize_string_for_path --- Makefile | 2 +- include/appstates/BackupMenuState.hpp | 20 ++-- include/appstates/TitleOptionState.hpp | 15 ++- include/builddate.hpp | 4 +- source/appstates/BackupMenuState.cpp | 10 +- source/appstates/BlacklistEditState.cpp | 2 +- source/appstates/SettingsState.cpp | 19 ++-- source/appstates/TextTitleSelectState.cpp | 20 ++-- source/appstates/TitleOptionState.cpp | 7 +- source/appstates/TitleSelectState.cpp | 19 ++-- source/config/ConfigContext.cpp | 10 +- source/fs/io.cpp | 2 +- source/fs/zip.cpp | 2 +- source/stringutil.cpp | 54 +++++++--- source/tasks/backup.cpp | 122 +++++++++------------- source/tasks/titleoptions.cpp | 54 ++++------ source/tasks/useroptions.cpp | 10 +- 17 files changed, 193 insertions(+), 179 deletions(-) diff --git a/Makefile b/Makefile index eb054f4..6e4d6cd 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ INCLUDES := include ./Libraries/FsLib/Switch/FsLib/include ./Libraries/SDLLib/SD EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 09.30.2025 +APP_VERSION := 10.02.2025 ROMFS := romfs ICON := icon.jpg diff --git a/include/appstates/BackupMenuState.hpp b/include/appstates/BackupMenuState.hpp index c40dfee..bb79bf3 100644 --- a/include/appstates/BackupMenuState.hpp +++ b/include/appstates/BackupMenuState.hpp @@ -18,19 +18,23 @@ class BackupMenuState final : public BaseState /// @brief Creates a new backup selection state. /// @param user Pointer to currently selected user. /// @param titleInfo Pointer to titleInfo of selected title. - /// @param saveType Save data type we're working with. - BackupMenuState(data::User *user, data::TitleInfo *titleInfo); + /// @param saveInfo Pointer to the target save info. + BackupMenuState(data::User *user, data::TitleInfo *titleInfo, const FsSaveDataInfo *saveInfo); /// @brief Creates and returns a new BackupMenuState. - static inline std::shared_ptr create(data::User *user, data::TitleInfo *titleInfo) + static inline std::shared_ptr create(data::User *user, + data::TitleInfo *titleInfo, + const FsSaveDataInfo *saveInfo) { - return std::make_shared(user, titleInfo); + return std::make_shared(user, titleInfo, saveInfo); } /// @brief Creates and pushes a new BackupMenuState to the vector. - static inline std::shared_ptr create_and_push(data::User *user, data::TitleInfo *titleInfo) + static inline std::shared_ptr create_and_push(data::User *user, + data::TitleInfo *titleInfo, + const FsSaveDataInfo *saveInfo) { - auto newState = BackupMenuState::create(user, titleInfo); + auto newState = BackupMenuState::create(user, titleInfo, saveInfo); StateManager::push_state(newState); return newState; } @@ -65,6 +69,7 @@ class BackupMenuState final : public BaseState { data::User *user{}; data::TitleInfo *titleInfo{}; + const FsSaveDataInfo *saveInfo{}; fslib::Path path{}; // This and std::string remoteName{}; // and this and remote::Item *remoteItem{}; // this are set when needed. @@ -82,6 +87,9 @@ class BackupMenuState final : public BaseState /// @brief Pointer to data for selected title. data::TitleInfo *m_titleInfo{}; + /// @brief Pointer to the save info. This cleans and simplifies code in other places. + const FsSaveDataInfo *m_saveInfo{}; + /// @brief Save data type we're working with. FsSaveDataType m_saveType{}; diff --git a/include/appstates/TitleOptionState.hpp b/include/appstates/TitleOptionState.hpp index 27d8c21..9a874c2 100644 --- a/include/appstates/TitleOptionState.hpp +++ b/include/appstates/TitleOptionState.hpp @@ -13,22 +13,27 @@ class TitleOptionState final : public BaseState /// @brief Constructs a new title option state. /// @param user Target user. /// @param titleInfo Target title. - TitleOptionState(data::User *user, data::TitleInfo *titleInfo, TitleSelectCommon *titleSelect); + TitleOptionState(data::User *user, + data::TitleInfo *titleInfo, + const FsSaveDataInfo *saveInfo, + TitleSelectCommon *titleSelect); /// @brief Returns a new TitleOptionState. See constructor. static inline std::shared_ptr create(data::User *user, data::TitleInfo *titleInfo, + const FsSaveDataInfo *saveInfo, TitleSelectCommon *titleSelect) { - return std::make_shared(user, titleInfo, titleSelect); + return std::make_shared(user, titleInfo, saveInfo, titleSelect); } /// @brief Creates, pushes, and returns a new TitleOptionState static std::shared_ptr create_and_push(data::User *user, data::TitleInfo *titleInfo, + const FsSaveDataInfo *saveInfo, TitleSelectCommon *titleSelect) { - auto newState = TitleOptionState::create(user, titleInfo, titleSelect); + auto newState = TitleOptionState::create(user, titleInfo, saveInfo, titleSelect); StateManager::push_state(newState); return newState; } @@ -53,6 +58,7 @@ class TitleOptionState final : public BaseState { data::User *user{}; data::TitleInfo *titleInfo{}; + const FsSaveDataInfo *saveInfo{}; TitleOptionState *spawningState{}; TitleSelectCommon *titleSelect{}; }; @@ -65,6 +71,9 @@ class TitleOptionState final : public BaseState /// @brief This is the target title. data::TitleInfo *m_titleInfo{}; + /// @brief This makes tasks easier to read and understand. + const FsSaveDataInfo *m_saveInfo{}; + /// @brief Pointer to the title selection being used for updating. TitleSelectCommon *m_titleSelect{}; diff --git a/include/builddate.hpp b/include/builddate.hpp index cb0634b..c0d1c5b 100644 --- a/include/builddate.hpp +++ b/include/builddate.hpp @@ -2,7 +2,7 @@ namespace builddate { - inline constexpr int MONTH = 9; - inline constexpr int DAY = 30; + inline constexpr int MONTH = 10; + inline constexpr int DAY = 2; inline constexpr int YEAR = 2025; } diff --git a/source/appstates/BackupMenuState.cpp b/source/appstates/BackupMenuState.cpp index a488219..54228ea 100644 --- a/source/appstates/BackupMenuState.cpp +++ b/source/appstates/BackupMenuState.cpp @@ -21,9 +21,10 @@ #include -BackupMenuState::BackupMenuState(data::User *user, data::TitleInfo *titleInfo) +BackupMenuState::BackupMenuState(data::User *user, data::TitleInfo *titleInfo, const FsSaveDataInfo *saveInfo) : m_user(user) , m_titleInfo(titleInfo) + , m_saveInfo(saveInfo) , m_saveType(m_user->get_account_save_type()) , m_directoryPath(config::get_working_directory() / m_titleInfo->get_path_safe_title()) , m_dataStruct(std::make_shared()) @@ -168,6 +169,7 @@ void BackupMenuState::initialize_task_data() // The other members are set upon actions being taken. m_dataStruct->user = m_user; m_dataStruct->titleInfo = m_titleInfo; + m_dataStruct->saveInfo = m_saveInfo; m_dataStruct->spawningState = this; } @@ -183,11 +185,7 @@ void BackupMenuState::initialize_info_string() void BackupMenuState::save_data_check() { - const uint64_t applicationID = m_titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = m_user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { return; } - - fs::ScopedSaveMount saveMount{fs::DEFAULT_SAVE_MOUNT, saveInfo}; + fs::ScopedSaveMount saveMount{fs::DEFAULT_SAVE_MOUNT, m_saveInfo}; fslib::Directory saveRoot{fs::DEFAULT_SAVE_ROOT}; m_saveHasData = saveRoot.is_open() && saveRoot.get_count() > 0; } diff --git a/source/appstates/BlacklistEditState.cpp b/source/appstates/BlacklistEditState.cpp index 600e19f..1b66b59 100644 --- a/source/appstates/BlacklistEditState.cpp +++ b/source/appstates/BlacklistEditState.cpp @@ -55,7 +55,7 @@ void BlacklistEditState::refresh_menu() m_blacklistMenu->reset(); config::get_blacklisted_titles(m_blacklist); - for (const uint64_t &applicationID : m_blacklist) + for (const uint64_t applicationID : m_blacklist) { data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); if (error::is_null(titleInfo)) { continue; } diff --git a/source/appstates/SettingsState.cpp b/source/appstates/SettingsState.cpp index 3337ac8..c825021 100644 --- a/source/appstates/SettingsState.cpp +++ b/source/appstates/SettingsState.cpp @@ -119,13 +119,16 @@ void SettingsState::load_extra_strings() void SettingsState::update_menu_options() { - for (int i : {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23}) + static constexpr std::array TOGGLE_INDEXES = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 17, 18, 19, 20, 21, 22, 23}; + + for (const int index : TOGGLE_INDEXES) { - const char *optionFormat = strings::get_by_name(strings::names::SETTINGS_MENU, i); - const uint8_t value = config::get_by_key(CONFIG_KEY_ARRAY[i]); + const char *optionFormat = strings::get_by_name(strings::names::SETTINGS_MENU, index); + const uint8_t value = config::get_by_key(CONFIG_KEY_ARRAY[index]); const char *status = SettingsState::get_status_text(value); const std::string option = stringutil::get_formatted_string(optionFormat, status); - m_settingsMenu->edit_option(i, option); + m_settingsMenu->edit_option(index, option); } { @@ -179,9 +182,7 @@ void SettingsState::change_working_directory() moved = fs::move_directory_recursively(oldPath, newPath); error::fslib(fslib::delete_directory_recursively(oldPath)); } - else { - moved = fslib::rename_directory(oldPath, newPath); - } + else { moved = fslib::rename_directory(oldPath, newPath); } if (!moved) { @@ -273,9 +274,7 @@ void SettingsState::toggle_trash_folder() config::toggle_by_key(config::keys::ENABLE_TRASH_BIN); if (trashEnabled) { error::fslib(fslib::delete_directory_recursively(trashPath)); } - else { - error::fslib(fslib::create_directory(trashPath)); - } + else { error::fslib(fslib::create_directory(trashPath)); } } void SettingsState::cycle_anim_scaling() diff --git a/source/appstates/TextTitleSelectState.cpp b/source/appstates/TextTitleSelectState.cpp index 08eb52b..5bee565 100644 --- a/source/appstates/TextTitleSelectState.cpp +++ b/source/appstates/TextTitleSelectState.cpp @@ -81,22 +81,22 @@ void TextTitleSelectState::refresh() void TextTitleSelectState::create_backup_menu() { - const int selected = m_titleSelectMenu->get_selected(); - const uint64_t applicationID = m_user->get_application_id_at(selected); - data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const int selected = m_titleSelectMenu->get_selected(); + const uint64_t applicationID = m_user->get_application_id_at(selected); + data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const FsSaveDataInfo *saveInfo = m_user->get_save_info_at(selected); - auto backupMenuState = std::make_shared(m_user, titleInfo); - StateManager::push_state(backupMenuState); + BackupMenuState::create_and_push(m_user, titleInfo, saveInfo); } void TextTitleSelectState::create_title_option_menu() { - const int selected = m_titleSelectMenu->get_selected(); - const uint64_t applicationID = m_user->get_application_id_at(selected); - data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const int selected = m_titleSelectMenu->get_selected(); + const uint64_t applicationID = m_user->get_application_id_at(selected); + data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const FsSaveDataInfo *saveInfo = m_user->get_save_info_at(selected); - auto titleOptionState = std::make_shared(m_user, titleInfo, this); - StateManager::push_state(titleOptionState); + TitleOptionState::create_and_push(m_user, titleInfo, saveInfo, this); } void TextTitleSelectState::add_remove_favorite() diff --git a/source/appstates/TitleOptionState.cpp b/source/appstates/TitleOptionState.cpp index 1978aa1..d070e8b 100644 --- a/source/appstates/TitleOptionState.cpp +++ b/source/appstates/TitleOptionState.cpp @@ -40,9 +40,13 @@ namespace }; } // namespace -TitleOptionState::TitleOptionState(data::User *user, data::TitleInfo *titleInfo, TitleSelectCommon *titleSelect) +TitleOptionState::TitleOptionState(data::User *user, + data::TitleInfo *titleInfo, + const FsSaveDataInfo *saveInfo, + TitleSelectCommon *titleSelect) : m_user(user) , m_titleInfo(titleInfo) + , m_saveInfo(saveInfo) , m_titleSelect(titleSelect) , m_dataStruct(std::make_shared()) { @@ -124,6 +128,7 @@ void TitleOptionState::initialize_data_struct() { m_dataStruct->user = m_user; m_dataStruct->titleInfo = m_titleInfo; + m_dataStruct->saveInfo = m_saveInfo; m_dataStruct->spawningState = this; m_dataStruct->titleSelect = m_titleSelect; } diff --git a/source/appstates/TitleSelectState.cpp b/source/appstates/TitleSelectState.cpp index 4ce241b..dbc5e47 100644 --- a/source/appstates/TitleSelectState.cpp +++ b/source/appstates/TitleSelectState.cpp @@ -74,22 +74,23 @@ bool TitleSelectState::title_count_check() void TitleSelectState::create_backup_menu() { - const int selected = m_titleView->get_selected(); - const uint64_t applicationID = m_user->get_application_id_at(selected); - data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const int selected = m_titleView->get_selected(); + const uint64_t applicationID = m_user->get_application_id_at(selected); + data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const FsSaveDataInfo *saveInfo = m_user->get_save_info_at(selected); - auto backupMenu = std::make_shared(m_user, titleInfo); + auto backupMenu = std::make_shared(m_user, titleInfo, saveInfo); StateManager::push_state(backupMenu); } void TitleSelectState::create_title_option_menu() { - const int selected = m_titleView->get_selected(); - const uint64_t applicationID = m_user->get_application_id_at(selected); - data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const int selected = m_titleView->get_selected(); + const uint64_t applicationID = m_user->get_application_id_at(selected); + data::TitleInfo *titleInfo = data::get_title_info_by_id(applicationID); + const FsSaveDataInfo *saveInfo = m_user->get_save_info_at(selected); - auto titleOptions = std::make_shared(m_user, titleInfo, this); - StateManager::push_state(titleOptions); + TitleOptionState::create_and_push(m_user, titleInfo, saveInfo, this); } void TitleSelectState::deactivate_state() diff --git a/source/config/ConfigContext.cpp b/source/config/ConfigContext.cpp index 5fefbbe..7c31405 100644 --- a/source/config/ConfigContext.cpp +++ b/source/config/ConfigContext.cpp @@ -205,6 +205,7 @@ bool config::ConfigContext::load_config_file() json_object_iter_next(&configIter); } + return true; } @@ -227,7 +228,7 @@ void config::ConfigContext::save_config_file() json::add_object(configJSON, config::keys::UI_ANIMATION_SCALE, scaling); json_object *favoritesArray = json_object_new_array(); - for (const uint64_t &applicationID : m_favorites) + for (const uint64_t applicationID : m_favorites) { const std::string appIDHex = stringutil::get_formatted_string(APP_ID_HEX_FORMAT, applicationID); json_object *jsonFavorite = json_object_new_string(appIDHex.c_str()); @@ -237,7 +238,7 @@ void config::ConfigContext::save_config_file() json::add_object(configJSON, config::keys::FAVORITES, favoritesArray); json_object *blacklistArray = json_object_new_array(); - for (const uint64_t &applicationID : m_blacklist) + for (const uint64_t applicationID : m_blacklist) { const std::string appIDHex = stringutil::get_formatted_string(APP_ID_HEX_FORMAT, applicationID); json_object *jsonBlacklist = json_object_new_string(appIDHex.c_str()); @@ -280,8 +281,7 @@ void config::ConfigContext::load_custom_paths() const uint64_t applicationID = std::strtoull(appIDString, nullptr, 16); const char *path = json_object_get_string(pathObject); - - m_paths[applicationID] = path; + m_paths.try_emplace(applicationID, path); json_object_iter_next(&pathsIter); } @@ -292,7 +292,7 @@ void config::ConfigContext::save_custom_paths() json::Object pathsJSON = json::new_object(json_object_new_object); if (!pathsJSON) { return; } - for (auto &[applicationID, path] : m_paths) + for (const auto &[applicationID, path] : m_paths) { const std::string key = stringutil::get_formatted_string(APP_ID_HEX_FORMAT, applicationID); json_object *pathObject = json_object_new_string(path.c_str()); diff --git a/source/fs/io.cpp b/source/fs/io.cpp index 44d9864..1f8ea7b 100644 --- a/source/fs/io.cpp +++ b/source/fs/io.cpp @@ -135,7 +135,7 @@ void fs::copy_file_commit(const fslib::Path &source, } const auto &[buffer, bufferSize] = queuePair; - const bool needsCommit = journalCount + bufferSize >= journalSize; + const bool needsCommit = journalCount + static_cast(bufferSize) >= journalSize; if (needsCommit) { destFile.close(); diff --git a/source/fs/zip.cpp b/source/fs/zip.cpp index 3290f7d..c15a7b8 100644 --- a/source/fs/zip.cpp +++ b/source/fs/zip.cpp @@ -208,7 +208,7 @@ void fs::copy_zip_to_directory(fs::MiniUnzip &unzip, const fslib::Path &dest, in auto &[buffer, bufferSize] = queuePair; - const bool commitNeeded = needCommits && journalCount + bufferSize >= journalSize; + const bool commitNeeded = needCommits && journalCount + static_cast(bufferSize) >= journalSize; if (commitNeeded) { destFile.close(); diff --git a/source/stringutil.cpp b/source/stringutil.cpp index 4b45971..6261834 100644 --- a/source/stringutil.cpp +++ b/source/stringutil.cpp @@ -7,14 +7,31 @@ #include #include #include +#include namespace { // Size limit for formatted strings. constexpr size_t VA_BUFFER_SIZE = 0x1000; + // These characters get replaced by spaces when path is sanitized. constexpr std::array FORBIDDEN_PATH_CHARACTERS = {L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*', L'™', L'©', L'®'}; + + /// @brief This is a table for replacing accented characters and "look alike" unicode characters. + // Note: extra outer braces required to initialize std::array of non-scalar elements (pairs) + constexpr std::array, 78> REPLACEMENT_TABLE{ + {{L'Á', "A"}, {L'À', "A"}, {L'Â', "A"}, {L'Ä', "A"}, {L'Ã', "A"}, {L'Å', "A"}, {L'á', "a"}, {L'à', "a"}, + {L'â', "a"}, {L'ä', "a"}, {L'ã', "a"}, {L'å', "a"}, {L'É', "E"}, {L'È', "E"}, {L'Ê', "E"}, {L'Ë', "E"}, + {L'é', "e"}, {L'è', "e"}, {L'ê', "e"}, {L'ë', "e"}, {L'Í', "I"}, {L'Ì', "I"}, {L'Î', "I"}, {L'Ï', "I"}, + {L'í', "i"}, {L'ì', "i"}, {L'î', "i"}, {L'ï', "i"}, {L'Ó', "O"}, {L'Ò', "O"}, {L'Ô', "O"}, {L'Ö', "O"}, + {L'Õ', "O"}, {L'Ø', "O"}, {L'ó', "o"}, {L'ò', "o"}, {L'ô', "o"}, {L'ö', "o"}, {L'õ', "o"}, {L'ø', "o"}, + {L'Ú', "U"}, {L'Ù', "U"}, {L'Û', "U"}, {L'Ü', "U"}, {L'ú', "u"}, {L'ù', "u"}, {L'û', "u"}, {L'ü', "u"}, + {L'Ñ', "N"}, {L'ñ', "n"}, {L'Ç', "C"}, {L'ç', "c"}, {L'ẞ', "Ss"}, {L'ß', "ss"}, {L'Œ', "OE"}, {L'œ', "oe"}, + {L'Æ', "AE"}, {L'æ', "ae"}, {L'‐', "-"}, {L'–', "-"}, {L'—', "-"}, {L'―', "-"}, {L' ', " "}, {L' ', " "}, + {L' ', " "}, {L'Ⅰ', "I"}, {L'Ⅱ', "II"}, {L'Ⅲ', "III"}, {L'Ⅳ', "IV"}, {L'Ⅴ', "V"}, {L'※', "*"}, {L'×', "x"}, + {L'‘', "'"}, {L'’', "'"}, {L'‛', "'"}, {L'′', ";"}, {L'ʼ', "'"}}}; + } // namespace std::string stringutil::get_formatted_string(const char *format, ...) @@ -57,18 +74,9 @@ bool stringutil::sanitize_string_for_path(const char *stringIn, char *stringOut, { const uint8_t *point = reinterpret_cast(&stringIn[i]); const ssize_t count = decode_utf8(&codepoint, point); - if (count <= 0 || i + count >= static_cast(stringOutSize)) { return false; } - - if (codepoint == L'é') - { - stringOut[outOffset++] = 'e'; - i += count; - continue; - } - - const bool asciiCheck = codepoint < 0x1E || codepoint >= 0x7E; - if (asciiCheck) { return false; } + if (count <= 0 || outOffset + count >= static_cast(stringOutSize)) { return false; } + // If it's forbidden, skip. const bool isForbidden = std::find(FORBIDDEN_PATH_CHARACTERS.begin(), FORBIDDEN_PATH_CHARACTERS.end(), codepoint) != FORBIDDEN_PATH_CHARACTERS.end(); if (isForbidden) @@ -76,12 +84,30 @@ bool stringutil::sanitize_string_for_path(const char *stringIn, char *stringOut, i += count; continue; } - else + + // Check for replacing. + const auto &replace = std::find_if(REPLACEMENT_TABLE.begin(), + REPLACEMENT_TABLE.end(), + [=](const auto &replacePair) { return replacePair.first == codepoint; }); + if (replace != REPLACEMENT_TABLE.end()) { - std::memcpy(&stringOut[outOffset], &stringIn[i], static_cast(count)); - outOffset += count; + const auto &[tablePoint, replacement] = *replace; + const size_t replacementLength = replacement.length(); + + std::copy(replacement.data(), replacement.data() + replacementLength, &stringOut[outOffset]); + + outOffset += replacementLength; + i += count; + continue; } + // Final valid ASCII check. + const bool asciiCheck = codepoint < 0x20 || codepoint >= 0x7F; + if (asciiCheck) { return false; } + + // Just copy it over. + std::copy(&stringIn[i], &stringIn[i] + count, &stringOut[outOffset]); + outOffset += count; i += count; } diff --git a/source/tasks/backup.cpp b/source/tasks/backup.cpp index c60c0f5..ed254c0 100644 --- a/source/tasks/backup.cpp +++ b/source/tasks/backup.cpp @@ -32,19 +32,16 @@ void tasks::backup::create_new_backup_local(sys::threadpool::JobData taskData) sys::ProgressTask *task = static_cast(castData->task); data::User *user = castData->user; data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; const fslib::Path &target = castData->path; BackupMenuState *spawningState = castData->spawningState; const bool killTask = castData->killTask; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } const std::string targetString = target.string(); const bool hasZipExt = std::strstr(targetString.c_str(), STRING_ZIP_EXT); - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } - if (hasZipExt) // At this point, this should have the zip extension appended if needed. { fs::MiniZip zip{target}; @@ -54,7 +51,8 @@ void tasks::backup::create_new_backup_local(sys::threadpool::JobData taskData) auto scopedMount = create_scoped_mount(saveInfo); fs::copy_directory_to_zip(fs::DEFAULT_SAVE_ROOT, zip, task); } - else { + else + { const bool needsDir = !fslib::directory_exists(target); const bool createError = needsDir && error::fslib(fslib::create_directory(target)); if (needsDir && createError) { TASK_FINISH_RETURN(task); } @@ -77,20 +75,19 @@ void tasks::backup::create_new_backup_remote(sys::threadpool::JobData taskData) sys::ProgressTask *task = static_cast(castData->task); data::User *user = castData->user; data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; const fslib::Path &path = castData->path; const std::string &remoteName = castData->remoteName; BackupMenuState *spawningState = castData->spawningState; const bool &killTask = castData->killTask; const bool keepLocal = config::get_by_key(config::keys::KEEP_LOCAL_BACKUPS); + remote::Storage *remote = remote::get_remote_storage(); if (error::is_null(task)) { return; } - - remote::Storage *remote = remote::get_remote_storage(); - if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } - - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(remote) || error::is_null(saveInfo)) + { + TASK_FINISH_RETURN(task); + } const fslib::Path zipPath{keepLocal ? path : PATH_JKSV_TEMP}; const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; @@ -132,14 +129,9 @@ void tasks::backup::overwrite_backup_local(sys::threadpool::JobData taskData) { auto castData = std::static_pointer_cast(taskData); - sys::ProgressTask *task = static_cast(castData->task); - data::User *user = castData->user; - data::TitleInfo *titleInfo = castData->titleInfo; - const fslib::Path &target = castData->path; - BackupMenuState *spawningState = castData->spawningState; - + sys::ProgressTask *task = static_cast(castData->task); + const fslib::Path &target = castData->path; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; const bool isDirectory = fslib::directory_exists(target); @@ -160,19 +152,13 @@ void tasks::backup::overwrite_backup_remote(sys::threadpool::JobData taskData) { auto castData = std::static_pointer_cast(taskData); - sys::ProgressTask *task = static_cast(castData->task); - data::User *user = castData->user; - data::TitleInfo *titleInfo = castData->titleInfo; + sys::ProgressTask *task = static_cast(castData->task); + const FsSaveDataInfo *saveInfo = castData->saveInfo; + remote::Item *target = castData->remoteItem; + remote::Storage *remote = remote::get_remote_storage(); if (error::is_null(task)) { return; } - - remote::Item *target = castData->remoteItem; - remote::Storage *remote = remote::get_remote_storage(); - if (error::is_null(remote) || error::is_null(target)) { TASK_FINISH_RETURN(task); } - - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(remote) || error::is_null(target)) { TASK_FINISH_RETURN(task); } const fslib::Path tempPath{PATH_JKSV_TEMP}; const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; @@ -212,18 +198,18 @@ void tasks::backup::restore_backup_local(sys::threadpool::JobData taskData) sys::ProgressTask *task = static_cast(castData->task); data::User *user = castData->user; data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; const fslib::Path &target = castData->path; BackupMenuState *spawningState = castData->spawningState; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } - - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - const uint8_t saveType = user->get_account_save_type(); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo) || error::is_null(spawningState)) + { + TASK_FINISH_RETURN(task); + } FsSaveDataExtraData extraData{}; + const uint8_t saveType = saveInfo->save_data_type; const bool readExtra = fs::read_save_extra_data(saveInfo, extraData); const int64_t journalSize = readExtra ? extraData.journal_size : titleInfo->get_journal_size(saveType); @@ -261,7 +247,8 @@ void tasks::backup::restore_backup_local(sys::threadpool::JobData taskData) auto scopedMount = create_scoped_mount(saveInfo); fs::copy_directory_commit(target, fs::DEFAULT_SAVE_ROOT, journalSize, task); } - else { + else + { auto scopedMount = create_scoped_mount(saveInfo); fs::copy_file_commit(target, fs::DEFAULT_SAVE_ROOT, journalSize, task); } @@ -282,17 +269,16 @@ void tasks::backup::restore_backup_remote(sys::threadpool::JobData taskData) sys::ProgressTask *task = static_cast(castData->task); data::User *user = castData->user; data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; BackupMenuState *spawningState = castData->spawningState; remote::Storage *remote = remote::get_remote_storage(); + const bool autoBackup = config::get_by_key(config::keys::AUTO_BACKUP_ON_RESTORE); if (error::is_null(task)) { return; } - - if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } - - const bool autoBackup = config::get_by_key(config::keys::AUTO_BACKUP_ON_RESTORE); - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo) || error::is_null(remote)) + { + TASK_FINISH_RETURN(task); + } if (autoBackup) { auto_backup(task, castData); } @@ -371,8 +357,7 @@ void tasks::backup::delete_backup_local(sys::threadpool::JobData taskData) BackupMenuState *spawningState = castData->spawningState; if (error::is_null(task)) { return; } - - if (error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; { @@ -391,7 +376,8 @@ void tasks::backup::delete_backup_local(sys::threadpool::JobData taskData) dirError = isDir && error::fslib(fslib::rename_directory(path, newPath)); fileError = !isDir && error::fslib(fslib::rename_file(path, newPath)); } - else { + else + { dirError = isDir && error::fslib(fslib::delete_directory_recursively(path)); fileError = !isDir && error::fslib(fslib::delete_file(path)); } @@ -416,8 +402,7 @@ void tasks::backup::delete_backup_remote(sys::threadpool::JobData taskData) remote::Storage *remote = remote::get_remote_storage(); if (error::is_null(task)) { return; } - - if (error::is_null(target) || error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(target) || error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; { @@ -448,8 +433,7 @@ void tasks::backup::upload_backup(sys::threadpool::JobData taskData) remote::Storage *remote = remote::get_remote_storage(); if (error::is_null(task)) { return; } - - if (error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } { const char *filename = path.get_filename(); @@ -474,8 +458,10 @@ void tasks::backup::patch_backup(sys::threadpool::JobData taskData) BackupMenuState *spawningState = castData->spawningState; remote::Storage *remote = remote::get_remote_storage(); if (error::is_null(task)) { return; } - - if (error::is_null(spawningState) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(remoteItem) || error::is_null(spawningState) || error::is_null(remote)) + { + TASK_FINISH_RETURN(task); + } { const char *filename = path.get_filename(); @@ -497,6 +483,7 @@ static void auto_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskD data::TitleInfo *titleInfo = taskData->titleInfo; fslib::Path &target = taskData->path; BackupMenuState *spawningState = taskData->spawningState; + if (error::is_null(user) || error::is_null(titleInfo)) { return; } const uint64_t applicationID = titleInfo->get_application_id(); const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); @@ -530,7 +517,8 @@ static void auto_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskD tasks::backup::create_new_backup_remote(tempData); } - else { + else + { // We're going to get the target dir from the path passed. const size_t lastSlash = target.find_last_of('/'); if (lastSlash == target.NOT_FOUND) { return; } @@ -545,15 +533,10 @@ static void auto_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskD static bool read_and_process_meta(const fslib::Path &targetDir, BackupMenuState::TaskData taskData, sys::ProgressTask *task) { - if (error::is_null(task)) { return false; } - data::User *user = taskData->user; data::TitleInfo *titleInfo = taskData->titleInfo; - if (error::is_null(user) || error::is_null(titleInfo)) - { - task->complete(); - return false; - } + if (error::is_null(task)) { return false; } + else if (error::is_null(user) || error::is_null(titleInfo)) { return false; } const uint64_t applicationID = titleInfo->get_application_id(); const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); @@ -591,17 +574,10 @@ static bool read_and_process_meta(fs::MiniUnzip &unzip, BackupMenuState::TaskDat { if (error::is_null(task)) { return false; } - data::User *user = taskData->user; - data::TitleInfo *titleInfo = taskData->titleInfo; - if (error::is_null(user) || error::is_null(titleInfo)) - { - task->complete(); - return false; - } - - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { return false; } + data::User *user = taskData->user; + data::TitleInfo *titleInfo = taskData->titleInfo; + const FsSaveDataInfo *saveInfo = taskData->saveInfo; + if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo)) { return false; } const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; { diff --git a/source/tasks/titleoptions.cpp b/source/tasks/titleoptions.cpp index 38c1ec3..ea73261 100644 --- a/source/tasks/titleoptions.cpp +++ b/source/tasks/titleoptions.cpp @@ -70,7 +70,8 @@ void tasks::titleoptions::delete_all_local_backups_for_title(sys::threadpool::Jo const bool dirExists = fslib::directory_exists(targetPath); const bool deleteFailed = dirExists && error::fslib(fslib::delete_directory_recursively(targetPath)); if (deleteFailed) { ui::PopMessageManager::push_message(popTicks, popFailure); } - else { + else + { const char *title = titleInfo->get_title(); std::string popMessage = stringutil::get_formatted_string(popSuccess, title); ui::PopMessageManager::push_message(popTicks, popMessage); @@ -140,15 +141,12 @@ void tasks::titleoptions::reset_save_data(sys::threadpool::JobData taskData) { auto castData = std::static_pointer_cast(taskData); - sys::Task *task = castData->task; - data::User *user = castData->user; - data::TitleInfo *titleInfo = castData->titleInfo; + sys::Task *task = castData->task; + data::User *user = castData->user; + data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); } - - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; const char *popFailed = strings::get_by_name(strings::names::TITLEOPTION_POPS, 2); @@ -166,9 +164,7 @@ void tasks::titleoptions::reset_save_data(sys::threadpool::JobData taskData) const bool resetFailed = error::fslib(fslib::delete_directory_recursively(fs::DEFAULT_SAVE_ROOT)); const bool commitFailed = error::fslib(fslib::commit_data_to_file_system(fs::DEFAULT_SAVE_MOUNT)); if (resetFailed || commitFailed) { ui::PopMessageManager::push_message(popTicks, popFailed); } - else { - ui::PopMessageManager::push_message(popTicks, popSuccess); - } + else { ui::PopMessageManager::push_message(popTicks, popSuccess); } } task->complete(); @@ -181,18 +177,16 @@ void tasks::titleoptions::delete_save_data_from_system(sys::threadpool::JobData sys::Task *task = castData->task; data::User *user = castData->user; data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; TitleSelectCommon *titleSelect = castData->titleSelect; TitleOptionState *spawningState = castData->spawningState; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(titleSelect) || error::is_null(spawningState)) + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo) || error::is_null(titleSelect) || + error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } - const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; { const char *statusFormat = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 2); @@ -210,6 +204,7 @@ void tasks::titleoptions::delete_save_data_from_system(sys::threadpool::JobData return; } + const uint64_t applicationID = titleInfo->get_application_id(); user->erase_save_info_by_id(applicationID); titleSelect->refresh(); spawningState->close_on_update(); @@ -218,20 +213,15 @@ void tasks::titleoptions::delete_save_data_from_system(sys::threadpool::JobData void tasks::titleoptions::extend_save_data(sys::threadpool::JobData taskData) { - static constexpr int SIZE_MB = 0x100000; - - auto castData = std::static_pointer_cast(taskData); - - sys::Task *task = castData->task; - data::User *user = castData->user; - data::TitleInfo *titleInfo = castData->titleInfo; - if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); } - + static constexpr int SIZE_MB = 0x100000; const int popTicks = ui::PopMessageManager::DEFAULT_TICKS; - const uint64_t applicationID = titleInfo->get_application_id(); - const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); - if (error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } + auto castData = std::static_pointer_cast(taskData); + sys::Task *task = castData->task; + data::User *user = castData->user; + data::TitleInfo *titleInfo = castData->titleInfo; + const FsSaveDataInfo *saveInfo = castData->saveInfo; + if (error::is_null(task)) { return; } + else if (error::is_null(user) || error::is_null(titleInfo) || error::is_null(saveInfo)) { TASK_FINISH_RETURN(task); } std::array sizeBuffer = {0}; FsSaveDataExtraData extraData{}; @@ -262,9 +252,11 @@ void tasks::titleoptions::extend_save_data(sys::threadpool::JobData taskData) const char *popSuccess = strings::get_by_name(strings::names::TITLEOPTION_POPS, 10); ui::PopMessageManager::push_message(popTicks, popSuccess); } - else { + else + { const char *popFailed = strings::get_by_name(strings::names::TITLEOPTION_POPS, 11); ui::PopMessageManager::push_message(popTicks, popFailed); } + task->complete(); } diff --git a/source/tasks/useroptions.cpp b/source/tasks/useroptions.cpp index de2be8e..ff2808f 100644 --- a/source/tasks/useroptions.cpp +++ b/source/tasks/useroptions.cpp @@ -17,7 +17,7 @@ void tasks::useroptions::backup_all_for_user_local(sys::threadpool::JobData task data::User *user = castData->user; if (error::is_null(task)) { return; } - if (error::is_null(user)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user)) { TASK_FINISH_RETURN(task); } auto backupStruct = std::make_shared(); backupStruct->task = task; @@ -71,7 +71,7 @@ void tasks::useroptions::backup_all_for_user_remote(sys::threadpool::JobData tas data::User *user = castData->user; remote::Storage *remote = remote::get_remote_storage(); if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(remote)) { TASK_FINISH_RETURN(task); } auto backupStruct = std::make_shared(); backupStruct->task = task; @@ -120,7 +120,7 @@ void tasks::useroptions::create_all_save_data_for_user(sys::threadpool::JobData data::User *user = castData->user; UserOptionState *spawningState = castData->spawningState; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } + else if (error::is_null(user) || error::is_null(spawningState)) { TASK_FINISH_RETURN(task); } data::TitleInfoList infoList{}; data::get_title_info_list(infoList); @@ -160,7 +160,7 @@ void tasks::useroptions::delete_all_save_data_for_user(sys::threadpool::JobData data::User *user = castData->user; UserOptionState *spawningState = castData->spawningState; if (error::is_null(task)) { return; } - if (error::is_null(user) || error::is_null(spawningState) || user->get_account_save_type() == FsSaveDataType_System) + else if (error::is_null(user) || error::is_null(spawningState) || user->get_account_save_type() == FsSaveDataType_System) { TASK_FINISH_RETURN(task); } @@ -193,7 +193,7 @@ void tasks::useroptions::delete_all_save_data_for_user(sys::threadpool::JobData applicationIDs.push_back(applicationID); } - for (const uint64_t &applicationID : applicationIDs) { user->erase_save_info_by_id(applicationID); } + for (const uint64_t applicationID : applicationIDs) { user->erase_save_info_by_id(applicationID); } spawningState->refresh_required(); task->complete(); }