From fbeaff8d886c5eb53a5fc133a1fa72739472155e Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Mon, 3 Jun 2019 16:27:43 -0500 Subject: [PATCH] Make Nca.SectionExists return false for invalid type --- src/LibHac/Fs/NcaUtils/Nca.cs | 86 +++++++++++++++++++++++++++++------ src/LibHac/SwitchFs.cs | 4 +- src/hactoolnet/ProcessNca.cs | 4 +- 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/LibHac/Fs/NcaUtils/Nca.cs b/src/LibHac/Fs/NcaUtils/Nca.cs index 2f86ca53..cf12ed4d 100644 --- a/src/LibHac/Fs/NcaUtils/Nca.cs +++ b/src/LibHac/Fs/NcaUtils/Nca.cs @@ -69,7 +69,15 @@ namespace LibHac.Fs.NcaUtils return Header.HasRightsId ? GetDecryptedTitleKey() : GetDecryptedKey((int)type); } - public bool CanOpenSection(NcaSectionType type) => CanOpenSection(GetSectionIndexFromType(type)); + public bool CanOpenSection(NcaSectionType type) + { + if (!TryGetSectionIndexFromType(type, Header.ContentType, out int index)) + { + return false; + } + + return CanOpenSection(index); + } public bool CanOpenSection(int index) { @@ -87,7 +95,15 @@ namespace LibHac.Fs.NcaUtils return !Keyset.KeyAreaKeys[keyRevision][Header.KeyAreaKeyIndex].IsEmpty(); } - public bool SectionExists(NcaSectionType type) => SectionExists(GetSectionIndexFromType(type)); + public bool SectionExists(NcaSectionType type) + { + if (!TryGetSectionIndexFromType(type, Header.ContentType, out int index)) + { + return false; + } + + return SectionExists(index); + } public bool SectionExists(int index) { @@ -311,30 +327,70 @@ namespace LibHac.Fs.NcaUtils private int GetSectionIndexFromType(NcaSectionType type) { - return SectionIndexFromType(type, Header.ContentType); + return GetSectionIndexFromType(type, Header.ContentType); } - public static int SectionIndexFromType(NcaSectionType type, ContentType contentType) + public static int GetSectionIndexFromType(NcaSectionType type, ContentType contentType) + { + if (!TryGetSectionIndexFromType(type, contentType, out int index)) + { + throw new ArgumentOutOfRangeException(nameof(type), "NCA does not contain this section type."); + } + + return index; + } + + public static bool TryGetSectionIndexFromType(NcaSectionType type, ContentType contentType, out int index) { switch (type) { - case NcaSectionType.Code when contentType == ContentType.Program: return 0; - case NcaSectionType.Data when contentType == ContentType.Program: return 1; - case NcaSectionType.Logo when contentType == ContentType.Program: return 2; - case NcaSectionType.Data: return 0; - default: throw new ArgumentOutOfRangeException(nameof(type), "NCA does not contain this section type."); + case NcaSectionType.Code when contentType == ContentType.Program: + index = 0; + return true; + case NcaSectionType.Data when contentType == ContentType.Program: + index = 1; + return true; + case NcaSectionType.Logo when contentType == ContentType.Program: + index = 2; + return true; + case NcaSectionType.Data: + index = 0; + return true; + default: + index = 0; + return false; } } - public static NcaSectionType SectionTypeFromIndex(int index, ContentType contentType) + public static NcaSectionType GetSectionTypeFromIndex(int index, ContentType contentType) + { + if (!TryGetSectionTypeFromIndex(index, contentType, out NcaSectionType type)) + { + throw new ArgumentOutOfRangeException(nameof(type), "NCA type does not contain this index."); + } + + return type; + } + + public static bool TryGetSectionTypeFromIndex(int index, ContentType contentType, out NcaSectionType type) { switch (index) { - case 0 when contentType == ContentType.Program: return NcaSectionType.Code; - case 1 when contentType == ContentType.Program: return NcaSectionType.Data; - case 2 when contentType == ContentType.Program: return NcaSectionType.Logo; - case 0: return NcaSectionType.Data; - default: throw new ArgumentOutOfRangeException(nameof(index), "NCA type does not contain this index."); + case 0 when contentType == ContentType.Program: + type = NcaSectionType.Code; + return true; + case 1 when contentType == ContentType.Program: + type = NcaSectionType.Data; + return true; + case 2 when contentType == ContentType.Program: + type = NcaSectionType.Logo; + return true; + case 0: + type = NcaSectionType.Data; + return true; + default: + type = default; + return false; } } diff --git a/src/LibHac/SwitchFs.cs b/src/LibHac/SwitchFs.cs index d38d818b..77e2aada 100644 --- a/src/LibHac/SwitchFs.cs +++ b/src/LibHac/SwitchFs.cs @@ -264,12 +264,12 @@ namespace LibHac public IStorage OpenStorage(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel) { - return OpenStorage(Nca.SectionIndexFromType(type, Nca.Header.ContentType), integrityCheckLevel); + return OpenStorage(Nca.GetSectionIndexFromType(type, Nca.Header.ContentType), integrityCheckLevel); } public IFileSystem OpenFileSystem(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel) { - return OpenFileSystem(Nca.SectionIndexFromType(type, Nca.Header.ContentType), integrityCheckLevel); + return OpenFileSystem(Nca.GetSectionIndexFromType(type, Nca.Header.ContentType), integrityCheckLevel); } public Validity VerifyNca(IProgressReport logger = null, bool quiet = false) diff --git a/src/hactoolnet/ProcessNca.cs b/src/hactoolnet/ProcessNca.cs index 16674476..fda5aabb 100644 --- a/src/hactoolnet/ProcessNca.cs +++ b/src/hactoolnet/ProcessNca.cs @@ -166,12 +166,12 @@ namespace hactoolnet IStorage OpenStorageByType(NcaSectionType type) { - return OpenStorage(Nca.SectionIndexFromType(type, nca.Header.ContentType)); + return OpenStorage(Nca.GetSectionIndexFromType(type, nca.Header.ContentType)); } IFileSystem OpenFileSystemByType(NcaSectionType type) { - return OpenFileSystem(Nca.SectionIndexFromType(type, nca.Header.ContentType)); + return OpenFileSystem(Nca.GetSectionIndexFromType(type, nca.Header.ContentType)); } } }