From 77edd99749c04dd43d6dd168f4897716cd28d711 Mon Sep 17 00:00:00 2001 From: Pk11 Date: Tue, 23 Mar 2021 04:47:49 -0500 Subject: [PATCH] Make JSON reading safer - Check that the file actually opened before reading it - If the JSON was discarded, then make just use an empty object --- include/store/meta.hpp | 6 ------ source/overlays/storeSelect.cpp | 27 +++++++++++++++++++++------ source/store/meta.cpp | 25 +++++++++++++++---------- source/store/store.cpp | 2 ++ source/utils/config.cpp | 16 +++++++--------- source/utils/fileBrowse.cpp | 12 ++++++++---- source/utils/lang.cpp | 16 ++++++++++++---- 7 files changed, 65 insertions(+), 39 deletions(-) diff --git a/include/store/meta.hpp b/include/store/meta.hpp index 1a667a6..e0f47af 100644 --- a/include/store/meta.hpp +++ b/include/store/meta.hpp @@ -50,19 +50,15 @@ public: std::vector GetInstalled(const std::string &unistoreName, const std::string &entry) const; void SetUpdated(const std::string &unistoreName, const std::string &entry, const std::string &updated) { - if (this->metadataJson.is_discarded()) return; this->metadataJson[unistoreName][entry]["updated"] = updated; }; void SetMarks(const std::string &unistoreName, const std::string &entry, int marks) { - if (this->metadataJson.is_discarded()) return; this->metadataJson[unistoreName][entry]["marks"] = marks; }; /* TODO: Handle this better. */ void SetInstalled(const std::string &unistoreName, const std::string &entry, const std::string &name) { - if (this->metadataJson.is_discarded()) return; - const std::vector installs = this->GetInstalled(unistoreName, entry); bool write = true; @@ -82,8 +78,6 @@ public: /* Remove installed state from a download list entry. */ void RemoveInstalled(const std::string &unistoreName, const std::string &entry, const std::string &name) { - if (this->metadataJson.is_discarded()) return; - const std::vector installs = this->GetInstalled(unistoreName, entry); int idx = -1; diff --git a/source/overlays/storeSelect.cpp b/source/overlays/storeSelect.cpp index ebd73ba..995c6e5 100644 --- a/source/overlays/storeSelect.cpp +++ b/source/overlays/storeSelect.cpp @@ -59,9 +59,14 @@ static const std::vector mainButtons = { const std::string &file: The file of the UniStore. */ static void DeleteStore(const std::string &file) { + nlohmann::json storeJson; FILE *temp = fopen((std::string(_STORE_PATH) + file).c_str(), "rt"); - nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false); - fclose(temp); + if (temp) { + storeJson = nlohmann::json::parse(temp, nullptr, false); + fclose(temp); + } + if (storeJson.is_discarded()) + storeJson = {}; /* Check, if Spritesheet exist on UniStore. */ if (storeJson["storeInfo"].contains("sheet") && storeJson["storeInfo"]["sheet"].is_array()) { @@ -105,9 +110,14 @@ static bool DownloadStore() { if (URL != "") doSheet = DownloadUniStore(URL, -1, file, true); if (doSheet) { + nlohmann::json storeJson; FILE *temp = fopen(file.c_str(), "rt"); - nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false); - fclose(temp); + if (temp) { + storeJson = nlohmann::json::parse(temp, nullptr, false); + fclose(temp); + } + if (storeJson.is_discarded()) + storeJson = { }; if (doSheet) { if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_array()) { @@ -158,9 +168,14 @@ static bool UpdateStore(const std::string &URL) { if (URL != "") doSheet = DownloadUniStore(URL, -1, file, false); if (doSheet) { + nlohmann::json storeJson; FILE *temp = fopen(file.c_str(), "rt"); - nlohmann::json storeJson = nlohmann::json::parse(temp, nullptr, false); - fclose(temp); + if (temp) { + storeJson = nlohmann::json::parse(temp, nullptr, false); + fclose(temp); + } + if (storeJson.is_discarded()) + storeJson = { }; if (doSheet) { if (storeJson["storeInfo"].contains("sheetURL") && storeJson["storeInfo"]["sheetURL"].is_array()) { diff --git a/source/store/meta.cpp b/source/store/meta.cpp index 35b910a..930676d 100644 --- a/source/store/meta.cpp +++ b/source/store/meta.cpp @@ -43,8 +43,12 @@ Meta::Meta() { } FILE *temp = fopen(_META_PATH, "rt"); - this->metadataJson = nlohmann::json::parse(temp, nullptr, false); - fclose(temp); + if (temp) { + this->metadataJson = nlohmann::json::parse(temp, nullptr, false); + fclose(temp); + } + if (this->metadataJson.is_discarded()) + this->metadataJson = { }; if (config->metadata()) this->ImportMetadata(); } @@ -59,9 +63,15 @@ void Meta::ImportMetadata() { } Msg::DisplayMsg(Lang::get("FETCHING_METADATA")); - FILE *old = fopen("sdmc:/3ds/Universal-Updater/updates.json", "r"); - nlohmann::json oldJson = nlohmann::json::parse(old, nullptr, false); - fclose(old); + + nlohmann::json oldJson; + FILE *old = fopen("sdmc:/3ds/Universal-Updater/updates.json", "rt"); + if (old) { + oldJson = nlohmann::json::parse(old, nullptr, false); + fclose(old); + } + if (oldJson.is_discarded()) + oldJson = { }; std::vector info = GetUniStoreInfo(_STORE_PATH); // Fetch UniStores. @@ -83,7 +93,6 @@ void Meta::ImportMetadata() { const std::string &entry: The Entry name. */ std::string Meta::GetUpdated(const std::string &unistoreName, const std::string &entry) const { - if (this->metadataJson.is_discarded()) return ""; if (!this->metadataJson.contains(unistoreName)) return ""; // UniStore Name does not exist. if (!this->metadataJson[unistoreName].contains(entry)) return ""; // Entry does not exist. @@ -103,8 +112,6 @@ std::string Meta::GetUpdated(const std::string &unistoreName, const std::string int Meta::GetMarks(const std::string &unistoreName, const std::string &entry) const { int temp = 0; - if (this->metadataJson.is_discarded()) return temp; - if (!this->metadataJson.contains(unistoreName)) return temp; // UniStore Name does not exist. if (!this->metadataJson[unistoreName].contains(entry)) return temp; // Entry does not exist. @@ -137,8 +144,6 @@ bool Meta::UpdateAvailable(const std::string &unistoreName, const std::string &e const std::string &entry: The Entry name. */ std::vector Meta::GetInstalled(const std::string &unistoreName, const std::string &entry) const { - if (this->metadataJson.is_discarded()) return { }; - if (!this->metadataJson.contains(unistoreName)) return { }; // UniStore Name does not exist. if (!this->metadataJson[unistoreName].contains(entry)) return { }; // Entry does not exist. diff --git a/source/store/store.cpp b/source/store/store.cpp index df2758e..1d8d6fc 100644 --- a/source/store/store.cpp +++ b/source/store/store.cpp @@ -231,6 +231,8 @@ void Store::LoadFromFile(const std::string &file) { this->storeJson = nlohmann::json::parse(in, nullptr, false); fclose(in); + if (this->storeJson.is_discarded()) + this->storeJson = { }; /* Check, if valid. */ if (this->storeJson.contains("storeInfo") && this->storeJson.contains("storeContent")) { diff --git a/source/utils/config.cpp b/source/utils/config.cpp index 66f275c..84d3664 100644 --- a/source/utils/config.cpp +++ b/source/utils/config.cpp @@ -110,9 +110,13 @@ Config::Config() { this->initialize(); } - FILE *file = fopen("sdmc:/3ds/Universal-Updater/Config.json", "r"); - this->json = nlohmann::json::parse(file, nullptr, false); - fclose(file); + FILE *file = fopen("sdmc:/3ds/Universal-Updater/Config.json", "rt"); + if (file) { + this->json = nlohmann::json::parse(file, nullptr, false); + fclose(file); + } + if (this->json.is_discarded()) + this->json = { }; /* Let us create a new one. */ if (!this->json.contains("Version")) this->initialize(); @@ -174,34 +178,28 @@ void Config::save() { /* Helper functions. */ bool Config::getBool(const std::string &key) { - if (this->json.is_discarded()) return false; if (!this->json.contains(key)) return false; return this->json.at(key).get_ref(); } void Config::setBool(const std::string &key, bool v) { - if (this->json.is_discarded()) return; this->json[key] = v; }; int Config::getInt(const std::string &key) { - if (this->json.is_discarded()) return 0; if (!this->json.contains(key)) return 0; return this->json.at(key).get_ref(); } void Config::setInt(const std::string &key, int v) { - if (this->json.is_discarded()) return; this->json[key] = v; }; std::string Config::getString(const std::string &key) { - if (this->json.is_discarded()) return ""; if (!this->json.contains(key)) return ""; return this->json.at(key).get_ref(); } void Config::setString(const std::string &key, const std::string &v) { - if (this->json.is_discarded()) return; this->json[key] = v; }; diff --git a/source/utils/fileBrowse.cpp b/source/utils/fileBrowse.cpp index d0eddc5..6203724 100644 --- a/source/utils/fileBrowse.cpp +++ b/source/utils/fileBrowse.cpp @@ -113,11 +113,15 @@ UniStoreInfo GetInfo(const std::string &file, const std::string &fileName) { if(*(u32*)(fileName.c_str() + fileName.length() - 4) == (1886349435 & ~(1 << 3))) return Temp; } - nlohmann::json JSON = nullptr; + nlohmann::json JSON; + FILE *temp = fopen(file.c_str(), "rt"); + if(temp) { + JSON = nlohmann::json::parse(temp, nullptr, false); + fclose(temp); + } + if (JSON.is_discarded()) + JSON = { }; - FILE *temp = fopen(file.c_str(), "r"); - JSON = nlohmann::json::parse(temp, nullptr, false); - fclose(temp); if (!JSON.contains("storeInfo")) return Temp; // storeInfo does not exist. diff --git a/source/utils/lang.cpp b/source/utils/lang.cpp index bdc6ceb..70136f4 100644 --- a/source/utils/lang.cpp +++ b/source/utils/lang.cpp @@ -42,14 +42,22 @@ void Lang::load(const std::string &lang) { /* Check if exist. */ if (access(("romfs:/lang/" + lang + "/app.json").c_str(), F_OK) == 0) { values = fopen(("romfs:/lang/" + lang + "/app.json").c_str(), "rt"); - appJson = nlohmann::json::parse(values, nullptr, false); - fclose(values); + if (values) { + appJson = nlohmann::json::parse(values, nullptr, false); + fclose(values); + } + if (appJson.is_discarded()) + appJson = { }; return; } else { values = fopen("romfs:/lang/en/app.json", "rt"); - appJson = nlohmann::json::parse(values, nullptr, false); - fclose(values); + if (values) { + appJson = nlohmann::json::parse(values, nullptr, false); + fclose(values); + } + if (appJson.is_discarded()) + appJson = { }; return; } } \ No newline at end of file