Correct lots of weak warnings, fix CI

This commit is contained in:
2026-02-22 23:46:49 -05:00
parent 836d5e912a
commit 7c8484edaa
11 changed files with 73 additions and 69 deletions

View File

@@ -1,4 +1,4 @@
name: Build rustii name: Build rustwii
on: on:
push: push:
@@ -19,18 +19,18 @@ jobs:
# Not sure if this is the best choice, but I'm building in release mode to produce more effective nightly binaries. # Not sure if this is the best choice, but I'm building in release mode to produce more effective nightly binaries.
- name: Update Toolchain - name: Update Toolchain
run: rustup update run: rustup update
- name: Build rustii - name: Build rustwii
run: cargo build --verbose --release run: cargo build --verbose --release
- name: Package rustii for Upload - name: Package rustwii for Upload
run: | run: |
mv target/release/rustii ~/rustii mv target/release/rustwii ~/rustwii
cd ~ cd ~
tar cvf rustii.tar rustii tar cvf rustwii.tar rustwii
- name: Upload rustii - name: Upload rustwii
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
path: ~/rustii.tar path: ~/rustwii.tar
name: rustii-Linux-bin name: rustwii-Linux-bin
build-macos-arm64: build-macos-arm64:
@@ -42,18 +42,18 @@ jobs:
run: rustup update run: rustup update
- name: Add ARM64 Target - name: Add ARM64 Target
run: rustup target add aarch64-apple-darwin run: rustup target add aarch64-apple-darwin
- name: Build rustii - name: Build rustwii
run: cargo build --verbose --release --target aarch64-apple-darwin run: cargo build --verbose --release --target aarch64-apple-darwin
- name: Package rustii for Upload - name: Package rustwii for Upload
run: | run: |
mv target/aarch64-apple-darwin/release/rustii ~/rustii mv target/aarch64-apple-darwin/release/rustwii ~/rustwii
cd ~ cd ~
tar cvf rustii.tar rustii tar cvf rustwii.tar rustwii
- name: Upload rustii - name: Upload rustwii
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
path: ~/rustii.tar path: ~/rustwii.tar
name: rustii-macOS-arm64-bin name: rustwii-macOS-arm64-bin
build-macos-x86_64: build-macos-x86_64:
@@ -65,18 +65,18 @@ jobs:
run: rustup update run: rustup update
- name: Add x86_64 Target - name: Add x86_64 Target
run: rustup target add x86_64-apple-darwin run: rustup target add x86_64-apple-darwin
- name: Build rustii - name: Build rustwii
run: cargo build --verbose --release --target x86_64-apple-darwin run: cargo build --verbose --release --target x86_64-apple-darwin
- name: Package rustii for Upload - name: Package rustwii for Upload
run: | run: |
mv target/x86_64-apple-darwin/release/rustii ~/rustii mv target/x86_64-apple-darwin/release/rustwii ~/rustwii
cd ~ cd ~
tar cvf rustii.tar rustii tar cvf rustwii.tar rustwii
- name: Upload rustii - name: Upload rustwii
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
path: ~/rustii.tar path: ~/rustwii.tar
name: rustii-macOS-x86_64-bin name: rustwii-macOS-x86_64-bin
build-windows-x86_64: build-windows-x86_64:
@@ -86,12 +86,12 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Update Toolchain - name: Update Toolchain
run: rustup update run: rustup update
- name: Build rustii - name: Build rustwii
run: cargo build --verbose --release run: cargo build --verbose --release
- name: Upload rustii - name: Upload rustwii
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
path: D:\a\rustii\rustii\target\release\rustii.exe path: D:\a\rustwii\rustwii\target\release\rustwii.exe
name: rustii-Windows-bin name: rustwii-Windows-bin

View File

@@ -45,7 +45,7 @@ fn ash_bit_reader_feed_word(reader: &mut ASHBitReader) -> Result<(), ASHError> {
Ok(()) Ok(())
} }
fn ash_bit_reader_init(src: &[u8], size: u32, startpos: u32) -> Result<ASHBitReader, ASHError> { fn ash_bit_reader_init(src: &'_ [u8], size: u32, startpos: u32) -> Result<ASHBitReader<'_>, ASHError> {
// Load data into a bit reader, then have it read its first word. // Load data into a bit reader, then have it read its first word.
let mut reader = ASHBitReader { let mut reader = ASHBitReader {
src, src,

View File

@@ -20,8 +20,8 @@ fn print_tid(title_id: [u8; 8]) -> Result<()> {
} else { } else {
None None
}; };
if ascii_tid.is_some() { if let Some(ascii_tid) = ascii_tid {
println!(" Title ID: {} ({})", hex::encode(title_id).to_uppercase(), ascii_tid.unwrap()); println!(" Title ID: {} ({})", hex::encode(title_id).to_uppercase(), ascii_tid);
} else { } else {
println!(" Title ID: {}", hex::encode(title_id).to_uppercase()); println!(" Title ID: {}", hex::encode(title_id).to_uppercase());
} }
@@ -74,7 +74,7 @@ fn print_tmd_info(tmd: tmd::TMD, cert: Option<cert::Certificate>) -> Result<()>
println!(" Certificate Info: {} (Unknown)", signature_issuer); println!(" Certificate Info: {} (Unknown)", signature_issuer);
} }
let region = if hex::encode(tmd.title_id()).eq("0000000100000002") { let region = if hex::encode(tmd.title_id()).eq("0000000100000002") {
match versions::dec_to_standard(tmd.title_version(), &hex::encode(tmd.title_id()), Some(tmd.is_vwii() != false)) match versions::dec_to_standard(tmd.title_version(), &hex::encode(tmd.title_id()), Some(tmd.is_vwii()))
.unwrap_or_default().chars().last() { .unwrap_or_default().chars().last() {
Some('U') => "USA", Some('U') => "USA",
Some('E') => "EUR", Some('E') => "EUR",
@@ -89,11 +89,11 @@ fn print_tmd_info(tmd: tmd::TMD, cert: Option<cert::Certificate>) -> Result<()>
}; };
println!(" Region: {}", region); println!(" Region: {}", region);
println!(" Title Type: {}", tmd.title_type()?); println!(" Title Type: {}", tmd.title_type()?);
println!(" vWii Title: {}", tmd.is_vwii() != false); println!(" vWii Title: {}", tmd.is_vwii());
println!(" DVD Video Access: {}", tmd.check_access_right(tmd::AccessRight::DVDVideo)); println!(" DVD Video Access: {}", tmd.check_access_right(tmd::AccessRight::DVDVideo));
println!(" AHB Access: {}", tmd.check_access_right(tmd::AccessRight::AHB)); println!(" AHB Access: {}", tmd.check_access_right(tmd::AccessRight::AHB));
if cert.is_some() { if let Some(cert) = cert {
let signing_str = match cert::verify_tmd(&cert.unwrap(), &tmd) { let signing_str = match cert::verify_tmd(&cert, &tmd) {
Ok(result) => match result { Ok(result) => match result {
true => "Valid (Unmodified TMD)", true => "Valid (Unmodified TMD)",
false => { false => {
@@ -161,8 +161,8 @@ fn print_ticket_info(ticket: ticket::Ticket, cert: Option<cert::Certificate>) ->
println!(" Decryption Key: {}", key); println!(" Decryption Key: {}", key);
println!(" Title Key (Encrypted): {}", hex::encode(ticket.title_key())); println!(" Title Key (Encrypted): {}", hex::encode(ticket.title_key()));
println!(" Title Key (Decrypted): {}", hex::encode(ticket.title_key_dec())); println!(" Title Key (Decrypted): {}", hex::encode(ticket.title_key_dec()));
if cert.is_some() { if let Some(cert) = cert {
let signing_str = match cert::verify_ticket(&cert.unwrap(), &ticket) { let signing_str = match cert::verify_ticket(&cert, &ticket) {
Ok(result) => match result { Ok(result) => match result {
true => "Valid (Unmodified Ticket)", true => "Valid (Unmodified Ticket)",
false => { false => {

View File

@@ -162,8 +162,8 @@ pub fn info(emunand: &str) -> Result<()> {
} else { } else {
None None
}; };
if ascii_tid.is_some() { if let Some(ascii_tid) = ascii_tid {
println!(" {} ({})", title.to_uppercase(), ascii_tid.unwrap()); println!(" {} ({})", title.to_uppercase(), ascii_tid);
} else { } else {
println!(" {}", title.to_uppercase()); println!(" {}", title.to_uppercase());
} }
@@ -192,8 +192,8 @@ pub fn info(emunand: &str) -> Result<()> {
} else { } else {
None None
}; };
if ascii_tid.is_some() { if let Some(ascii_tid) = ascii_tid {
println!(" {} ({})", title.to_uppercase(), ascii_tid.unwrap()); println!(" {} ({})", title.to_uppercase(), ascii_tid);
} else { } else {
println!(" {}", title.to_uppercase()); println!(" {}", title.to_uppercase());
} }

View File

@@ -214,7 +214,7 @@ pub fn download_title(tid: &str, version: &Option<u16>, output: &TitleOutputType
bail!("The specified Title ID is invalid!"); bail!("The specified Title ID is invalid!");
} }
if version.is_some() { if version.is_some() {
println!("Downloading title {} v{}, please wait...", tid, version.clone().unwrap()); println!("Downloading title {} v{}, please wait...", tid, version.unwrap());
} else { } else {
println!("Downloading title {} vLatest, please wait...", tid); println!("Downloading title {} vLatest, please wait...", tid);
} }
@@ -245,9 +245,9 @@ pub fn download_title(tid: &str, version: &Option<u16>, output: &TitleOutputType
let content_region = content::ContentRegion::from_contents(contents, tmd.content_records().clone())?; let content_region = content::ContentRegion::from_contents(contents, tmd.content_records().clone())?;
println!(" - Building certificate chain..."); println!(" - Building certificate chain...");
let cert_chain = cert::CertificateChain::from_bytes(&nus::download_cert_chain(true).with_context(|| "Certificate chain could not be built.")?)?; let cert_chain = cert::CertificateChain::from_bytes(&nus::download_cert_chain(true).with_context(|| "Certificate chain could not be built.")?)?;
if tik.is_some() { if let Some(tik) = tik {
// If we have a Ticket, then build a Title and jump to the output method. // If we have a Ticket, then build a Title and jump to the output method.
let title = title::Title::from_parts(cert_chain, None, tik.unwrap(), tmd, content_region, None)?; let title = title::Title::from_parts(cert_chain, None, tik, tmd, content_region, None)?;
if output.wad.is_some() { if output.wad.is_some() {
download_title_wad(title, output.wad.clone().unwrap())?; download_title_wad(title, output.wad.clone().unwrap())?;
} else { } else {

View File

@@ -327,8 +327,8 @@ pub fn edit_wad(input: &str, output: &Option<String>, edits: &WadModifications)
let new_tid: Vec<u8> = tid_high.iter().chain(&tid_low).copied().collect(); let new_tid: Vec<u8> = tid_high.iter().chain(&tid_low).copied().collect();
title.set_title_id(new_tid.try_into().unwrap())?; title.set_title_id(new_tid.try_into().unwrap())?;
} }
if edits.ios.is_some() { if let Some(ios) = edits.ios {
let new_ios = edits.ios.unwrap(); let new_ios = ios;
if new_ios < 3 { if new_ios < 3 {
bail!("The specified IOS version is not valid! The new IOS version must be between 3 and 255.") bail!("The specified IOS version is not valid! The new IOS version must be between 3 and 255.")
} }
@@ -428,12 +428,12 @@ pub fn remove_wad(input: &str, output: &Option<String>, identifier: &ContentIden
let mut title = title::Title::from_bytes(&fs::read(in_path)?).with_context(|| "The provided WAD file could not be parsed, and is likely invalid.")?; let mut title = title::Title::from_bytes(&fs::read(in_path)?).with_context(|| "The provided WAD file could not be parsed, and is likely invalid.")?;
// Parse the identifier passed to choose how to find and remove the target. // Parse the identifier passed to choose how to find and remove the target.
// ...maybe don't take the above comment out of context // ...maybe don't take the above comment out of context
if identifier.index.is_some() { if let Some(index) = identifier.index {
title.content.remove_content(identifier.index.unwrap()).with_context(|| "The specified index does not exist in the provided WAD!")?; title.content.remove_content(index).with_context(|| "The specified index does not exist in the provided WAD!")?;
println!("{:?}", title.tmd); println!("{:?}", title.tmd);
title.fakesign().with_context(|| "An unknown error occurred while fakesigning the modified WAD.")?; title.fakesign().with_context(|| "An unknown error occurred while fakesigning the modified WAD.")?;
fs::write(&out_path, title.to_wad()?.to_bytes()?).with_context(|| "Could not open output file for writing.")?; fs::write(&out_path, title.to_wad()?.to_bytes()?).with_context(|| "Could not open output file for writing.")?;
println!("Successfully removed content at index {} in WAD file \"{}\".", identifier.index.unwrap(), out_path.display()); println!("Successfully removed content at index {} in WAD file \"{}\".", index, out_path.display());
} else if identifier.cid.is_some() { } else if identifier.cid.is_some() {
let cid = u32::from_str_radix(identifier.cid.clone().unwrap().as_str(), 16).with_context(|| "The specified Content ID is invalid!")?; let cid = u32::from_str_radix(identifier.cid.clone().unwrap().as_str(), 16).with_context(|| "The specified Content ID is invalid!")?;
let index = match title.content.get_index_from_cid(cid) { let index = match title.content.get_index_from_cid(cid) {
@@ -476,8 +476,8 @@ pub fn set_wad(input: &str, content: &str, output: &Option<String>, identifier:
}; };
} }
// Parse the identifier passed to choose how to do the find and replace. // Parse the identifier passed to choose how to do the find and replace.
if identifier.index.is_some() { if let Some(index) = identifier.index {
match title.set_content(&new_content, identifier.index.unwrap(), None, target_type) { match title.set_content(&new_content, index, None, target_type) {
Err(title::TitleError::Content(content::ContentError::IndexOutOfRange { index, max })) => { Err(title::TitleError::Content(content::ContentError::IndexOutOfRange { index, max })) => {
bail!("The specified index {} does not exist in this WAD! The maximum index is {}.", index, max) bail!("The specified index {} does not exist in this WAD! The maximum index is {}.", index, max)
}, },

View File

@@ -81,9 +81,9 @@ impl ContentRegion {
return Err(ContentError::MissingContents { required: content_records.len(), found: contents.len()}); return Err(ContentError::MissingContents { required: content_records.len(), found: contents.len()});
} }
let mut content_region = Self::new(content_records)?; let mut content_region = Self::new(content_records)?;
for i in 0..contents.len() { for (index, content) in contents.iter().enumerate() {
let target_index = content_region.content_records[i].index; let target_index = content_region.content_records[index].index;
content_region.load_enc_content(&contents[i], target_index as usize)?; content_region.load_enc_content(content, target_index as usize)?;
} }
Ok(content_region) Ok(content_region)
} }
@@ -213,15 +213,15 @@ impl ContentRegion {
} }
self.content_records[index].content_size = content_size; self.content_records[index].content_size = content_size;
self.content_records[index].content_hash = content_hash; self.content_records[index].content_hash = content_hash;
if cid.is_some() { if let Some(cid) = cid {
// Make sure that the new CID isn't already in use. // Make sure that the new CID isn't already in use.
if self.content_records.iter().any(|record| record.content_id == cid.unwrap()) { if self.content_records.iter().any(|record| record.content_id == cid) {
return Err(ContentError::CIDAlreadyExists(cid.unwrap())); return Err(ContentError::CIDAlreadyExists(cid));
} }
self.content_records[index].content_id = cid.unwrap(); self.content_records[index].content_id = cid;
} }
if content_type.is_some() { if let Some(content_type) = content_type {
self.content_records[index].content_type = content_type.unwrap(); self.content_records[index].content_type = content_type;
} }
self.contents[index] = content.to_vec(); self.contents[index] = content.to_vec();
Ok(()) Ok(())
@@ -320,12 +320,18 @@ pub struct SharedContentMap {
pub records: Vec<ContentMapEntry>, pub records: Vec<ContentMapEntry>,
} }
impl Default for SharedContentMap {
fn default() -> Self {
Self::new()
}
}
impl SharedContentMap { impl SharedContentMap {
/// Creates a new SharedContentMap instance from the binary data of a content.map file. /// Creates a new SharedContentMap instance from the binary data of a content.map file.
pub fn from_bytes(data: &[u8]) -> Result<SharedContentMap, ContentError> { pub fn from_bytes(data: &[u8]) -> Result<SharedContentMap, ContentError> {
// The uid.sys file must be divisible by a multiple of 28, or something is wrong, since each // The uid.sys file must be divisible by a multiple of 28, or something is wrong, since each
// entry is 28 bytes long. // entry is 28 bytes long.
if (data.len() % 28) != 0 { if !data.len().is_multiple_of(28) {
return Err(ContentError::InvalidSharedContentMapLength); return Err(ContentError::InvalidSharedContentMapLength);
} }
let record_count = data.len() / 28; let record_count = data.len() / 28;

View File

@@ -190,8 +190,8 @@ impl Title {
/// Sets a new Title ID for the Title. This will re-encrypt the Title Key in the Ticket, since /// Sets a new Title ID for the Title. This will re-encrypt the Title Key in the Ticket, since
/// the Title ID is used as the IV for decrypting the Title Key. /// the Title ID is used as the IV for decrypting the Title Key.
pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TitleError> { pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TitleError> {
self.tmd.set_title_id(title_id)?; self.tmd.set_title_id(title_id);
self.ticket.set_title_id(title_id)?; self.ticket.set_title_id(title_id);
Ok(()) Ok(())
} }

View File

@@ -126,8 +126,8 @@ pub fn download_tmd(title_id: [u8; 8], title_version: Option<u16>, wiiu_endpoint
} else { } else {
WII_NUS_ENDPOINT.to_owned() WII_NUS_ENDPOINT.to_owned()
}; };
let tmd_url = if title_version.is_some() { let tmd_url = if let Some(title_version) = title_version {
format!("{}{}/tmd.{}", endpoint_url, &hex::encode(title_id), title_version.unwrap()) format!("{}{}/tmd.{}", endpoint_url, &hex::encode(title_id), title_version)
} else { } else {
format!("{}{}/tmd", endpoint_url, &hex::encode(title_id)) format!("{}{}/tmd", endpoint_url, &hex::encode(title_id))
}; };

View File

@@ -320,10 +320,9 @@ impl Ticket {
/// Sets a new Title ID for the Ticket. This will re-encrypt the Title Key, since the Title ID /// Sets a new Title ID for the Ticket. This will re-encrypt the Title Key, since the Title ID
/// is used as the IV for decrypting the Title Key. /// is used as the IV for decrypting the Title Key.
pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TicketError> { pub fn set_title_id(&mut self, title_id: [u8; 8]) {
let new_enc_title_key = crypto::encrypt_title_key(self.title_key_dec(), self.common_key_index, title_id, self.is_dev()); let new_enc_title_key = crypto::encrypt_title_key(self.title_key_dec(), self.common_key_index, title_id, self.is_dev());
self.title_key = new_enc_title_key; self.title_key = new_enc_title_key;
self.title_id = title_id; self.title_id = title_id;
Ok(())
} }
} }

View File

@@ -322,8 +322,8 @@ impl TMD {
} }
/// Sets the content records in the TMD. /// Sets the content records in the TMD.
pub fn set_content_records(&mut self, content_records: &Vec<ContentRecord>) { pub fn set_content_records(&mut self, content_records: &[ContentRecord]) {
self.content_records = content_records.clone() self.content_records = content_records.to_vec();
} }
/// Gets whether a TMD is fakesigned using the strncmp (trucha) bug or not. /// Gets whether a TMD is fakesigned using the strncmp (trucha) bug or not.
@@ -449,9 +449,8 @@ impl TMD {
} }
/// Sets a new Title ID for a TMD. /// Sets a new Title ID for a TMD.
pub fn set_title_id(&mut self, title_id: [u8; 8]) -> Result<(), TMDError> { pub fn set_title_id(&mut self, title_id: [u8; 8]) {
self.title_id = title_id; self.title_id = title_id;
Ok(())
} }
/// Gets the Title ID of the IOS required by a TMD. /// Gets the Title ID of the IOS required by a TMD.