From bad297b824c266b46bac0c1e04e313aaa8010d98 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Sat, 2 Mar 2024 18:41:31 +0100 Subject: [PATCH] Prevent app from crashing when importing a newer firmware with outdated keys --- app/src/main/cpp/loader_jni.cpp | 26 ++++++++------- .../preference/FirmwareImportPreference.kt | 33 +++++++++++-------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/app/src/main/cpp/loader_jni.cpp b/app/src/main/cpp/loader_jni.cpp index 8a8922d91..491b18ac5 100644 --- a/app/src/main/cpp/loader_jni.cpp +++ b/app/src/main/cpp/loader_jni.cpp @@ -94,23 +94,27 @@ extern "C" JNIEXPORT jstring Java_org_stratoemu_strato_preference_FirmwareImport auto systemArchives{systemArchivesFileSystem->OpenDirectory("")}; auto keyStore{std::make_shared(skyline::JniString(env, keysPathJstring))}; - for (const auto &entry : systemArchives->Read()) { - std::shared_ptr backing{systemArchivesFileSystem->OpenFile(entry.name)}; - auto nca{skyline::vfs::NCA(backing, keyStore)}; - - if (nca.header.programId == systemVersionProgramId && nca.romFs != nullptr) { - auto controlRomFs{std::make_shared(nca.romFs)}; - auto file{controlRomFs->OpenFile("file")}; - SystemVersion systemVersion; - file->Read(systemVersion); - return env->NewStringUTF(reinterpret_cast(systemVersion.displayVersion)); + try { + for (const auto &entry : systemArchives->Read()) { + std::shared_ptr backing{systemArchivesFileSystem->OpenFile(entry.name)}; + auto nca{skyline::vfs::NCA(backing, keyStore)}; + + if (nca.header.programId == systemVersionProgramId && nca.romFs != nullptr) { + auto controlRomFs{std::make_shared(nca.romFs)}; + auto file{controlRomFs->OpenFile("file")}; + SystemVersion systemVersion; + file->Read(systemVersion); + return env->NewStringUTF(reinterpret_cast(systemVersion.displayVersion)); + } } + } catch (skyline::loader::loader_exception &e) { + return env->NewStringUTF("-1"); } return env->NewStringUTF(""); } -std::vector decodeBfttfFont(const std::shared_ptr bfttfFile){ +std::vector decodeBfttfFont(const std::shared_ptr bfttfFile) { constexpr skyline::u32 fontKey{0x06186249}; constexpr skyline::u32 BFTTFMagic{0x18029a7f}; diff --git a/app/src/main/java/org/stratoemu/strato/preference/FirmwareImportPreference.kt b/app/src/main/java/org/stratoemu/strato/preference/FirmwareImportPreference.kt index 80cff75fc..9d9b98cc6 100644 --- a/app/src/main/java/org/stratoemu/strato/preference/FirmwareImportPreference.kt +++ b/app/src/main/java/org/stratoemu/strato/preference/FirmwareImportPreference.kt @@ -25,7 +25,8 @@ import java.io.FilenameFilter import java.io.IOException class FirmwareImportPreference @JvmOverloads constructor(context : Context, attrs : AttributeSet? = null, defStyleAttr : Int = androidx.preference.R.attr.preferenceStyle) : Preference(context, attrs, defStyleAttr) { - private class Firmware(val valid : Boolean, val version : String) + private enum class FirmwareStatus { VALID, INVALID, KEYS_OUTDATED } + private class Firmware(val status : FirmwareStatus, val version : String?) private val firmwarePath = File(context.getPublicFilesDir().canonicalPath + "/switch/nand/system/Contents/registered/") private val keysPath = "${context.filesDir.canonicalPath}/keys/" @@ -49,17 +50,19 @@ class FirmwareImportPreference @JvmOverloads constructor(context : Context, attr ZipUtils.unzip(inputZip, cacheFirmwareDir) val firmware = isFirmwareValid(cacheFirmwareDir) - messageToShow = if (!firmware.valid) { - R.string.import_firmware_invalid_contents - } else { - firmwarePath.deleteRecursively() - cacheFirmwareDir.copyRecursively(firmwarePath, true) - persistString(firmware.version) - extractFonts(firmwarePath.path, keysPath, fontsPath) - CoroutineScope(Dispatchers.Main).launch { - notifyChanged() + messageToShow = when (firmware.status) { + FirmwareStatus.INVALID -> R.string.import_firmware_invalid_contents + FirmwareStatus.KEYS_OUTDATED -> R.string.import_firmware_outdated_keys + else -> { + firmwarePath.deleteRecursively() + cacheFirmwareDir.copyRecursively(firmwarePath, true) + persistString(firmware.version) + extractFonts(firmwarePath.path, keysPath, fontsPath) + CoroutineScope(Dispatchers.Main).launch { + notifyChanged() + } + R.string.import_firmware_success } - R.string.import_firmware_success } } catch (e : IOException) { messageToShow = R.string.error @@ -104,8 +107,12 @@ class FirmwareImportPreference @JvmOverloads constructor(context : Context, attr return if (unfilteredNumOfFiles == filteredNumOfFiles) { val version = fetchFirmwareVersion(cacheFirmwareDir.path, keysPath) - Firmware(version.isNotEmpty(), version) - } else Firmware(false, "") + when { + version.isEmpty() -> Firmware(FirmwareStatus.INVALID, null) + version == "-1" -> Firmware(FirmwareStatus.KEYS_OUTDATED, null) + else -> Firmware(FirmwareStatus.VALID, version) + } + } else Firmware(FirmwareStatus.INVALID, null) } private external fun fetchFirmwareVersion(systemArchivesPath : String, keysPath : String) : String diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c8b866924..d6595394b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,6 +52,7 @@ Firmware was successfully imported Firmware installation failed The supplied firmware package does not contain a valid firmware + The supplied firmware package version is newer than the currently installed keys Valid keys are required for firmware installation No firmware installed