From f65dbe84372c2f50eb236a366d2cfe13409b1857 Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Wed, 12 Oct 2022 14:18:24 +0200 Subject: [PATCH] Fix encoding error in input profile filenames - Controller profile filenames now encode unicode characters correctly - Removed dependency on boost::filesystem. There is still an indirect dependency on it from another boost module it seems - Refactored some code to use FileStream instead of ifstream/ofstream --- src/Cafe/GameProfile/GameProfile.cpp | 11 ++------ src/Common/precompiled.h | 1 - src/input/InputManager.cpp | 41 +++++++++++++++------------- src/util/helpers/helpers.h | 20 ++++++++++++++ 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/Cafe/GameProfile/GameProfile.cpp b/src/Cafe/GameProfile/GameProfile.cpp index d8c735ce..a1184362 100644 --- a/src/Cafe/GameProfile/GameProfile.cpp +++ b/src/Cafe/GameProfile/GameProfile.cpp @@ -277,10 +277,8 @@ bool GameProfile::Load(uint64_t title_id) void GameProfile::Save(uint64_t title_id) { auto gameProfileDir = ActiveSettings::GetConfigPath("gameProfiles"); - if (std::error_code ex_ec; !fs::exists(gameProfileDir, ex_ec) && !ex_ec) { - std::error_code cr_ec; - fs::create_directories(gameProfileDir, cr_ec); - } + if (std::error_code ex_ec; !fs::exists(gameProfileDir, ex_ec)) + fs::create_directories(gameProfileDir, ex_ec); auto gameProfilePath = gameProfileDir / fmt::format("{:016x}.ini", title_id); FileStream* fs = FileStream::createFile2(gameProfilePath); if (!fs) @@ -309,16 +307,11 @@ void GameProfile::Save(uint64_t title_id) fs->writeLine(""); fs->writeLine("[Graphics]"); - //WRITE_OPTIONAL_ENTRY(gpuBufferCacheAccuracy); WRITE_ENTRY(accurateShaderMul); WRITE_OPTIONAL_ENTRY(precompiledShaders); WRITE_OPTIONAL_ENTRY(graphics_api); fs->writeLine(""); - /*stream_writeLine(stream_gameProfile, "[Audio]"); - WRITE_ENTRY(disableAudio); - stream_writeLine(stream_gameProfile, "");*/ - fs->writeLine("[Controller]"); for (int i = 0; i < 8; ++i) { diff --git a/src/Common/precompiled.h b/src/Common/precompiled.h index bd956657..898a6883 100644 --- a/src/Common/precompiled.h +++ b/src/Common/precompiled.h @@ -69,7 +69,6 @@ #include #include #include -#include #include #include diff --git a/src/input/InputManager.cpp b/src/input/InputManager.cpp index 0861ba28..5d775c74 100644 --- a/src/input/InputManager.cpp +++ b/src/input/InputManager.cpp @@ -92,12 +92,12 @@ bool InputManager::load(size_t player_index, std::string_view filename) try { - std::ifstream file(file_path); - if (!file.is_open()) + auto xmlData = FileStream::LoadIntoMemory(file_path); + if (!xmlData || xmlData->empty()) return false; - + pugi::xml_document doc; - if (!doc.load(file)) + if (!doc.load_buffer(xmlData->data(), xmlData->size())) return false; const pugi::xml_node root = doc.document_element(); @@ -216,12 +216,15 @@ bool InputManager::migrate_config(const fs::path& file_path) { try { - std::ifstream file(file_path); - if (!file.is_open()) + auto xmlData = FileStream::LoadIntoMemory(file_path); + if (!xmlData || xmlData->empty()) return false; + std::string iniDataStr((const char*)xmlData->data(), xmlData->size()); + + std::stringstream iniData(iniDataStr); boost::property_tree::ptree m_data; - read_ini(file, m_data); + read_ini(iniData, m_data); const auto emulate_string = m_data.get("General.emulate"); const auto api_string = m_data.get("General.api"); @@ -455,7 +458,7 @@ bool InputManager::save(size_t player_index, std::string_view filename) if (is_default_file) file_path /= fmt::format("controller{}", player_index); else - file_path /= filename; + file_path /= _utf8ToPath(filename); file_path.replace_extension(".xml"); // force .xml extension @@ -540,15 +543,15 @@ bool InputManager::save(size_t player_index, std::string_view filename) } } } - - - std::ofstream file(file_path, std::ios::out | std::ios::trunc); - if (file.is_open()) - { - doc.save(file); - return true; - } - return false; + FileStream* fs = FileStream::createFile2(file_path); + if (!fs) + return false; + std::stringstream xmlData; + doc.save(xmlData); + std::string xmlStr = xmlData.str(); + fs->writeData(xmlStr.data(), xmlStr.size()); + delete fs; + return true; } bool InputManager::is_gameprofile_set(size_t player_index) const @@ -792,7 +795,7 @@ std::vector InputManager::get_profiles() const auto& p = entry.path(); if (p.has_extension() && (p.extension() == ".xml" || p.extension() == ".txt")) { - auto stem = p.filename().stem().string(); + auto stem = _pathToUtf8(p.filename().stem()); if (is_valid_profilename(stem)) { tmp.emplace(stem); @@ -808,7 +811,7 @@ std::vector InputManager::get_profiles() bool InputManager::is_valid_profilename(const std::string& name) { - if (!boost::filesystem::windows_name(name)) + if (!IsValidFilename(name)) return false; // dont allow default profile names diff --git a/src/util/helpers/helpers.h b/src/util/helpers/helpers.h index f81e5964..09b80fed 100644 --- a/src/util/helpers/helpers.h +++ b/src/util/helpers/helpers.h @@ -231,6 +231,26 @@ inline uint64 MakeU64(uint32 high, uint32 low) return ((uint64)high << 32) | ((uint64)low); } +static bool IsValidFilename(std::string_view sv) +{ + for (auto& it : sv) + { + uint8 c = (uint8)it; + if (c < 0x20) + return false; + if (c == '.' || c == '#' || c == '/' || c == '\\' || + c == '<' || c == '>' || c == '|' || c == ':' || + c == '\"') + return false; + } + if (!sv.empty()) + { + if (sv.back() == ' ' || sv.back() == '.') + return false; + } + return true; +} + // MAJOR; MINOR std::pair GetWindowsVersion(); bool IsWindows81OrGreater();