From 902cc1eb495953274360914c016320e62a971c91 Mon Sep 17 00:00:00 2001 From: LC Date: Sat, 20 Jun 2020 14:09:56 -0400 Subject: [PATCH] am: Resolve truncation and sign conversion warnings in WriteContentData() (#5397) We can adjust the API to allow std::size_t indices, which simplifies operating with standard container types. It also prevents truncation warnings from occurring in these cases as well. --- src/core/file_sys/cia_container.cpp | 9 +++++---- src/core/file_sys/cia_container.h | 8 ++++---- src/core/file_sys/title_metadata.cpp | 8 ++++---- src/core/file_sys/title_metadata.h | 8 ++++---- src/core/hle/service/am/am.cpp | 28 ++++++++++++++-------------- src/core/hle/service/am/am.h | 2 +- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/core/file_sys/cia_container.cpp b/src/core/file_sys/cia_container.cpp index 09d815c30..64ed8bbb0 100644 --- a/src/core/file_sys/cia_container.cpp +++ b/src/core/file_sys/cia_container.cpp @@ -206,10 +206,10 @@ u64 CIAContainer::GetMetadataOffset() const { return offset; } -u64 CIAContainer::GetContentOffset(u16 index) const { +u64 CIAContainer::GetContentOffset(std::size_t index) const { u64 offset = Common::AlignUp(GetTitleMetadataOffset() + cia_header.tmd_size, CIA_SECTION_ALIGNMENT); - for (u16 i = 0; i < index; i++) { + for (std::size_t i = 0; i < index; i++) { offset += GetContentSize(i); } return offset; @@ -235,10 +235,11 @@ u64 CIAContainer::GetTotalContentSize() const { return cia_header.content_size; } -u64 CIAContainer::GetContentSize(u16 index) const { +u64 CIAContainer::GetContentSize(std::size_t index) const { // If the content doesn't exist in the CIA, it doesn't have a size. - if (!cia_header.isContentPresent(index)) + if (!cia_header.IsContentPresent(index)) { return 0; + } return cia_tmd.GetContentSizeByIndex(index); } diff --git a/src/core/file_sys/cia_container.h b/src/core/file_sys/cia_container.h index 09bb1fcf5..332f2715f 100644 --- a/src/core/file_sys/cia_container.h +++ b/src/core/file_sys/cia_container.h @@ -58,14 +58,14 @@ public: u64 GetTicketOffset() const; u64 GetTitleMetadataOffset() const; u64 GetMetadataOffset() const; - u64 GetContentOffset(u16 index = 0) const; + u64 GetContentOffset(std::size_t index = 0) const; u32 GetCertificateSize() const; u32 GetTicketSize() const; u32 GetTitleMetadataSize() const; u32 GetMetadataSize() const; u64 GetTotalContentSize() const; - u64 GetContentSize(u16 index = 0) const; + u64 GetContentSize(std::size_t index = 0) const; void Print() const; @@ -81,11 +81,11 @@ private: u64_le content_size; std::array content_present; - bool isContentPresent(u16 index) const { + bool IsContentPresent(std::size_t index) const { // The content_present is a bit array which defines which content in the TMD // is included in the CIA, so check the bit for this index and add if set. // The bits in the content index are arranged w/ index 0 as the MSB, 7 as the LSB, etc. - return (content_present[index >> 3] & (0x80 >> (index & 7))); + return (content_present[index >> 3] & (0x80 >> (index & 7))) != 0; } }; diff --git a/src/core/file_sys/title_metadata.cpp b/src/core/file_sys/title_metadata.cpp index 96bd3f0e6..e25d2d238 100644 --- a/src/core/file_sys/title_metadata.cpp +++ b/src/core/file_sys/title_metadata.cpp @@ -165,19 +165,19 @@ u32 TitleMetadata::GetDLPContentID() const { return tmd_chunks[TMDContentIndex::DLP].id; } -u32 TitleMetadata::GetContentIDByIndex(u16 index) const { +u32 TitleMetadata::GetContentIDByIndex(std::size_t index) const { return tmd_chunks[index].id; } -u16 TitleMetadata::GetContentTypeByIndex(u16 index) const { +u16 TitleMetadata::GetContentTypeByIndex(std::size_t index) const { return tmd_chunks[index].type; } -u64 TitleMetadata::GetContentSizeByIndex(u16 index) const { +u64 TitleMetadata::GetContentSizeByIndex(std::size_t index) const { return tmd_chunks[index].size; } -std::array TitleMetadata::GetContentCTRByIndex(u16 index) const { +std::array TitleMetadata::GetContentCTRByIndex(std::size_t index) const { std::array ctr{}; std::memcpy(ctr.data(), &tmd_chunks[index].index, sizeof(u16)); return ctr; diff --git a/src/core/file_sys/title_metadata.h b/src/core/file_sys/title_metadata.h index 1f746f900..6b3623ff7 100644 --- a/src/core/file_sys/title_metadata.h +++ b/src/core/file_sys/title_metadata.h @@ -96,10 +96,10 @@ public: u32 GetBootContentID() const; u32 GetManualContentID() const; u32 GetDLPContentID() const; - u32 GetContentIDByIndex(u16 index) const; - u16 GetContentTypeByIndex(u16 index) const; - u64 GetContentSizeByIndex(u16 index) const; - std::array GetContentCTRByIndex(u16 index) const; + u32 GetContentIDByIndex(std::size_t index) const; + u16 GetContentTypeByIndex(std::size_t index) const; + u64 GetContentSizeByIndex(std::size_t index) const; + std::array GetContentCTRByIndex(std::size_t index) const; void SetTitleID(u64 title_id); void SetTitleType(u32 type); diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 09cc22b36..295269c27 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -151,21 +151,22 @@ ResultVal CIAFile::WriteContentData(u64 offset, std::size_t length, // Data is not being buffered, so we have to keep track of how much of each .app // has been written since we might get a written buffer which contains multiple .app // contents or only part of a larger .app's contents. - u64 offset_max = offset + length; - for (int i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) { + const u64 offset_max = offset + length; + for (std::size_t i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) { if (content_written[i] < container.GetContentSize(i)) { // The size, minimum unwritten offset, and maximum unwritten offset of this content - u64 size = container.GetContentSize(i); - u64 range_min = container.GetContentOffset(i) + content_written[i]; - u64 range_max = container.GetContentOffset(i) + size; + const u64 size = container.GetContentSize(i); + const u64 range_min = container.GetContentOffset(i) + content_written[i]; + const u64 range_max = container.GetContentOffset(i) + size; // The unwritten range for this content is beyond the buffered data we have // or comes before the buffered data we have, so skip this content ID. - if (range_min > offset_max || range_max < offset) + if (range_min > offset_max || range_max < offset) { continue; + } // Figure out how much of this content ID we have just recieved/can write out - u64 available_to_write = std::min(offset_max, range_max) - range_min; + const u64 available_to_write = std::min(offset_max, range_max) - range_min; // Since the incoming TMD has already been written, we can use GetTitleContentPath // to get the content paths to write to. @@ -173,14 +174,14 @@ ResultVal CIAFile::WriteContentData(u64 offset, std::size_t length, FileUtil::IOFile file(GetTitleContentPath(media_type, tmd.GetTitleID(), i, is_update), content_written[i] ? "ab" : "wb"); - if (!file.IsOpen()) + if (!file.IsOpen()) { return FileSys::ERROR_INSUFFICIENT_SPACE; + } std::vector temp(buffer + (range_min - offset), buffer + (range_min - offset) + available_to_write); - if (tmd.GetContentTypeByIndex(static_cast(i)) & - FileSys::TMDContentTypeFlag::Encrypted) { + if ((tmd.GetContentTypeByIndex(i) & FileSys::TMDContentTypeFlag::Encrypted) != 0) { decryption_state->content[i].ProcessData(temp.data(), temp.data(), temp.size()); } @@ -194,7 +195,7 @@ ResultVal CIAFile::WriteContentData(u64 offset, std::size_t length, } } - return MakeResult(length); + return MakeResult(length); } ResultVal CIAFile::Write(u64 offset, std::size_t length, bool flush, @@ -464,11 +465,10 @@ std::string GetTitleMetadataPath(Service::FS::MediaType media_type, u64 tid, boo return content_path + fmt::format("{:08x}.tmd", (update ? update_id : base_id)); } -std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index, - bool update) { +std::string GetTitleContentPath(FS::MediaType media_type, u64 tid, std::size_t index, bool update) { std::string content_path = GetTitlePath(media_type, tid) + "content/"; - if (media_type == Service::FS::MediaType::GameCard) { + if (media_type == FS::MediaType::GameCard) { // TODO(shinyquagsire23): get current app file if TID matches? LOG_ERROR(Service_AM, "Request for gamecard partition {} content path unimplemented!", static_cast(index)); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 25bd58265..6e2dae6fc 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -134,7 +134,7 @@ std::string GetTitleMetadataPath(Service::FS::MediaType media_type, u64 tid, boo * @param update set true if the incoming TMD should be used instead of the current TMD * @returns string path to the .app file */ -std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index = 0, +std::string GetTitleContentPath(FS::MediaType media_type, u64 tid, std::size_t index = 0, bool update = false); /**