mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 13:20:03 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									353780e1c9
								
							
						
					
					
						commit
						902cc1eb49
					
				
					 6 changed files with 32 additions and 31 deletions
				
			
		|  | @ -206,10 +206,10 @@ u64 CIAContainer::GetMetadataOffset() const { | ||||||
|     return offset; |     return offset; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u64 CIAContainer::GetContentOffset(u16 index) const { | u64 CIAContainer::GetContentOffset(std::size_t index) const { | ||||||
|     u64 offset = |     u64 offset = | ||||||
|         Common::AlignUp(GetTitleMetadataOffset() + cia_header.tmd_size, CIA_SECTION_ALIGNMENT); |         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); |         offset += GetContentSize(i); | ||||||
|     } |     } | ||||||
|     return offset; |     return offset; | ||||||
|  | @ -235,10 +235,11 @@ u64 CIAContainer::GetTotalContentSize() const { | ||||||
|     return cia_header.content_size; |     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 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 0; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return cia_tmd.GetContentSizeByIndex(index); |     return cia_tmd.GetContentSizeByIndex(index); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -58,14 +58,14 @@ public: | ||||||
|     u64 GetTicketOffset() const; |     u64 GetTicketOffset() const; | ||||||
|     u64 GetTitleMetadataOffset() const; |     u64 GetTitleMetadataOffset() const; | ||||||
|     u64 GetMetadataOffset() const; |     u64 GetMetadataOffset() const; | ||||||
|     u64 GetContentOffset(u16 index = 0) const; |     u64 GetContentOffset(std::size_t index = 0) const; | ||||||
| 
 | 
 | ||||||
|     u32 GetCertificateSize() const; |     u32 GetCertificateSize() const; | ||||||
|     u32 GetTicketSize() const; |     u32 GetTicketSize() const; | ||||||
|     u32 GetTitleMetadataSize() const; |     u32 GetTitleMetadataSize() const; | ||||||
|     u32 GetMetadataSize() const; |     u32 GetMetadataSize() const; | ||||||
|     u64 GetTotalContentSize() const; |     u64 GetTotalContentSize() const; | ||||||
|     u64 GetContentSize(u16 index = 0) const; |     u64 GetContentSize(std::size_t index = 0) const; | ||||||
| 
 | 
 | ||||||
|     void Print() const; |     void Print() const; | ||||||
| 
 | 
 | ||||||
|  | @ -81,11 +81,11 @@ private: | ||||||
|         u64_le content_size; |         u64_le content_size; | ||||||
|         std::array<u8, CIA_CONTENT_BITS_SIZE> content_present; |         std::array<u8, CIA_CONTENT_BITS_SIZE> 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
 |             // 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.
 |             // 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.
 |             // 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; | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -165,19 +165,19 @@ u32 TitleMetadata::GetDLPContentID() const { | ||||||
|     return tmd_chunks[TMDContentIndex::DLP].id; |     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; |     return tmd_chunks[index].id; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u16 TitleMetadata::GetContentTypeByIndex(u16 index) const { | u16 TitleMetadata::GetContentTypeByIndex(std::size_t index) const { | ||||||
|     return tmd_chunks[index].type; |     return tmd_chunks[index].type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u64 TitleMetadata::GetContentSizeByIndex(u16 index) const { | u64 TitleMetadata::GetContentSizeByIndex(std::size_t index) const { | ||||||
|     return tmd_chunks[index].size; |     return tmd_chunks[index].size; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::array<u8, 16> TitleMetadata::GetContentCTRByIndex(u16 index) const { | std::array<u8, 16> TitleMetadata::GetContentCTRByIndex(std::size_t index) const { | ||||||
|     std::array<u8, 16> ctr{}; |     std::array<u8, 16> ctr{}; | ||||||
|     std::memcpy(ctr.data(), &tmd_chunks[index].index, sizeof(u16)); |     std::memcpy(ctr.data(), &tmd_chunks[index].index, sizeof(u16)); | ||||||
|     return ctr; |     return ctr; | ||||||
|  |  | ||||||
|  | @ -96,10 +96,10 @@ public: | ||||||
|     u32 GetBootContentID() const; |     u32 GetBootContentID() const; | ||||||
|     u32 GetManualContentID() const; |     u32 GetManualContentID() const; | ||||||
|     u32 GetDLPContentID() const; |     u32 GetDLPContentID() const; | ||||||
|     u32 GetContentIDByIndex(u16 index) const; |     u32 GetContentIDByIndex(std::size_t index) const; | ||||||
|     u16 GetContentTypeByIndex(u16 index) const; |     u16 GetContentTypeByIndex(std::size_t index) const; | ||||||
|     u64 GetContentSizeByIndex(u16 index) const; |     u64 GetContentSizeByIndex(std::size_t index) const; | ||||||
|     std::array<u8, 16> GetContentCTRByIndex(u16 index) const; |     std::array<u8, 16> GetContentCTRByIndex(std::size_t index) const; | ||||||
| 
 | 
 | ||||||
|     void SetTitleID(u64 title_id); |     void SetTitleID(u64 title_id); | ||||||
|     void SetTitleType(u32 type); |     void SetTitleType(u32 type); | ||||||
|  |  | ||||||
|  | @ -151,21 +151,22 @@ ResultVal<std::size_t> CIAFile::WriteContentData(u64 offset, std::size_t length, | ||||||
|     // Data is not being buffered, so we have to keep track of how much of each <ID>.app
 |     // Data is not being buffered, so we have to keep track of how much of each <ID>.app
 | ||||||
|     // has been written since we might get a written buffer which contains multiple .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.
 |     // contents or only part of a larger .app's contents.
 | ||||||
|     u64 offset_max = offset + length; |     const u64 offset_max = offset + length; | ||||||
|     for (int i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) { |     for (std::size_t i = 0; i < container.GetTitleMetadata().GetContentCount(); i++) { | ||||||
|         if (content_written[i] < container.GetContentSize(i)) { |         if (content_written[i] < container.GetContentSize(i)) { | ||||||
|             // The size, minimum unwritten offset, and maximum unwritten offset of this content
 |             // The size, minimum unwritten offset, and maximum unwritten offset of this content
 | ||||||
|             u64 size = container.GetContentSize(i); |             const u64 size = container.GetContentSize(i); | ||||||
|             u64 range_min = container.GetContentOffset(i) + content_written[i]; |             const u64 range_min = container.GetContentOffset(i) + content_written[i]; | ||||||
|             u64 range_max = container.GetContentOffset(i) + size; |             const u64 range_max = container.GetContentOffset(i) + size; | ||||||
| 
 | 
 | ||||||
|             // The unwritten range for this content is beyond the buffered data we have
 |             // 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.
 |             // 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; |                 continue; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             // Figure out how much of this content ID we have just recieved/can write out
 |             // 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
 |             // Since the incoming TMD has already been written, we can use GetTitleContentPath
 | ||||||
|             // to get the content paths to write to.
 |             // to get the content paths to write to.
 | ||||||
|  | @ -173,14 +174,14 @@ ResultVal<std::size_t> CIAFile::WriteContentData(u64 offset, std::size_t length, | ||||||
|             FileUtil::IOFile file(GetTitleContentPath(media_type, tmd.GetTitleID(), i, is_update), |             FileUtil::IOFile file(GetTitleContentPath(media_type, tmd.GetTitleID(), i, is_update), | ||||||
|                                   content_written[i] ? "ab" : "wb"); |                                   content_written[i] ? "ab" : "wb"); | ||||||
| 
 | 
 | ||||||
|             if (!file.IsOpen()) |             if (!file.IsOpen()) { | ||||||
|                 return FileSys::ERROR_INSUFFICIENT_SPACE; |                 return FileSys::ERROR_INSUFFICIENT_SPACE; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             std::vector<u8> temp(buffer + (range_min - offset), |             std::vector<u8> temp(buffer + (range_min - offset), | ||||||
|                                  buffer + (range_min - offset) + available_to_write); |                                  buffer + (range_min - offset) + available_to_write); | ||||||
| 
 | 
 | ||||||
|             if (tmd.GetContentTypeByIndex(static_cast<u16>(i)) & |             if ((tmd.GetContentTypeByIndex(i) & FileSys::TMDContentTypeFlag::Encrypted) != 0) { | ||||||
|                 FileSys::TMDContentTypeFlag::Encrypted) { |  | ||||||
|                 decryption_state->content[i].ProcessData(temp.data(), temp.data(), temp.size()); |                 decryption_state->content[i].ProcessData(temp.data(), temp.data(), temp.size()); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -194,7 +195,7 @@ ResultVal<std::size_t> CIAFile::WriteContentData(u64 offset, std::size_t length, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return MakeResult<std::size_t>(length); |     return MakeResult(length); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ResultVal<std::size_t> CIAFile::Write(u64 offset, std::size_t length, bool flush, | ResultVal<std::size_t> 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)); |     return content_path + fmt::format("{:08x}.tmd", (update ? update_id : base_id)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index, | std::string GetTitleContentPath(FS::MediaType media_type, u64 tid, std::size_t index, bool update) { | ||||||
|                                 bool update) { |  | ||||||
|     std::string content_path = GetTitlePath(media_type, tid) + "content/"; |     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?
 |         // TODO(shinyquagsire23): get current app file if TID matches?
 | ||||||
|         LOG_ERROR(Service_AM, "Request for gamecard partition {} content path unimplemented!", |         LOG_ERROR(Service_AM, "Request for gamecard partition {} content path unimplemented!", | ||||||
|                   static_cast<u32>(index)); |                   static_cast<u32>(index)); | ||||||
|  |  | ||||||
|  | @ -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 |  * @param update set true if the incoming TMD should be used instead of the current TMD | ||||||
|  * @returns string path to the .app file |  * @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); |                                 bool update = false); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue