From 190ceb1903eda9ad6434e3c35bc1c0ee3d34ff24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E6=A0=91=E4=BA=BA?= Date: Sun, 4 May 2025 21:00:27 +0900 Subject: [PATCH] qmc: remove use of anyhow --- Cargo.lock | 18 +++++++++++++----- um_crypto/qmc/Cargo.toml | 3 +-- um_crypto/qmc/src/ekey.rs | 9 +++++---- um_crypto/qmc/src/footer/mod.rs | 5 +++-- um_crypto/qmc/src/footer/musicex_v1.rs | 12 ++++++++---- um_crypto/qmc/src/lib.rs | 8 +++++--- um_crypto/qmc/src/v2_map/key.rs | 2 +- um_crypto/qmc/src/v2_map/mod.rs | 4 ++-- 8 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73150b9..c9d627a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,6 +316,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "js-sys" version = "0.3.76" @@ -577,7 +586,7 @@ version = "0.1.9" dependencies = [ "anyhow", "byteorder", - "itertools", + "itertools 0.13.0", "thiserror", "umc_qmc", "umc_utils", @@ -600,7 +609,7 @@ dependencies = [ "byteorder", "cipher", "crc", - "itertools", + "itertools 0.13.0", "thiserror", "umc_utils", ] @@ -609,9 +618,8 @@ dependencies = [ name = "umc_qmc" version = "0.1.9" dependencies = [ - "anyhow", "byteorder", - "itertools", + "itertools 0.14.0", "lazy_static", "tc_tea", "thiserror", @@ -624,7 +632,7 @@ version = "0.1.9" dependencies = [ "byteorder", "hex", - "itertools", + "itertools 0.13.0", "miniz_oxide", "thiserror", "umc_qmc", diff --git a/um_crypto/qmc/Cargo.toml b/um_crypto/qmc/Cargo.toml index 1849947..0117363 100644 --- a/um_crypto/qmc/Cargo.toml +++ b/um_crypto/qmc/Cargo.toml @@ -4,9 +4,8 @@ version = "0.1.9" edition = "2021" [dependencies] -anyhow = "1.0.86" byteorder = "1.5.0" -itertools = "0.13.0" +itertools = "0.14" lazy_static = "1.5.0" tc_tea = { version = "0.2.1", default-features = false } thiserror = "2.0.7" diff --git a/um_crypto/qmc/src/ekey.rs b/um_crypto/qmc/src/ekey.rs index 26e3881..e5b4c1a 100644 --- a/um_crypto/qmc/src/ekey.rs +++ b/um_crypto/qmc/src/ekey.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use itertools::Itertools; use lazy_static::lazy_static; use std::ops::Mul; @@ -27,6 +26,8 @@ pub enum EKeyDecryptError { FailDecryptV1(TcTeaError), #[error("Error when decrypting ekey v2: {0}")] FailDecryptV2(TcTeaError), + #[error("Failed to decode b64 content: {0}")] + Base64Decode(#[from] base64::DecodeError), } fn make_simple_key() -> [u8; N] { @@ -42,7 +43,7 @@ fn make_simple_key() -> [u8; N] { result } -pub fn decrypt_v1(ekey: &[u8]) -> Result> { +pub fn decrypt_v1(ekey: &[u8]) -> Result, EKeyDecryptError> { if ekey.len() < 12 { Err(EKeyDecryptError::EKeyTooShort)?; } @@ -61,7 +62,7 @@ pub fn decrypt_v1(ekey: &[u8]) -> Result> { Ok([header, &plaintext].concat()) } -pub fn decrypt_v2(ekey: &[u8]) -> Result> { +pub fn decrypt_v2(ekey: &[u8]) -> Result, EKeyDecryptError> { let ekey = base64::decode(ekey)?; let ekey = tc_tea::decrypt(ekey, EKEY_V2_KEY1).map_err(EKeyDecryptError::FailDecryptV2)?; let ekey = tc_tea::decrypt(ekey, EKEY_V2_KEY2).map_err(EKeyDecryptError::FailDecryptV2)?; @@ -70,7 +71,7 @@ pub fn decrypt_v2(ekey: &[u8]) -> Result> { decrypt_v1(&ekey) } -pub fn decrypt>(ekey: T) -> Result> { +pub fn decrypt>(ekey: T) -> Result, EKeyDecryptError> { let ekey = ekey.as_ref(); match ekey.strip_prefix(EKEY_V2_PREFIX) { Some(v2_ekey) => decrypt_v2(v2_ekey), diff --git a/um_crypto/qmc/src/footer/mod.rs b/um_crypto/qmc/src/footer/mod.rs index e068693..8af226d 100644 --- a/um_crypto/qmc/src/footer/mod.rs +++ b/um_crypto/qmc/src/footer/mod.rs @@ -26,8 +26,6 @@ pub enum FooterParseError { PCv2InvalidVersion(u32), #[error("PCv2/MusicEx: Invalid `MusicEx` size: {0}")] PCv2MusicExUnsupportedPayloadSize(usize), - #[error("PCv2/MusicEx: Invalid `MusicEx` data: {0}")] - PCv2MusicExInvalidError(anyhow::Error), #[error("Android/STag: Invalid ID field: {0}")] STagInvalidId(String), @@ -45,6 +43,9 @@ pub enum FooterParseError { #[error("Parse: Failed to parse string '{0}' as integer")] StringToIntError(String), + + #[error("Failed to parse MusicExV1: {0}")] + MusicEx1ParseError(std::io::Error), } /// Footer type diff --git a/um_crypto/qmc/src/footer/musicex_v1.rs b/um_crypto/qmc/src/footer/musicex_v1.rs index 378d7f8..c0b6ae0 100644 --- a/um_crypto/qmc/src/footer/musicex_v1.rs +++ b/um_crypto/qmc/src/footer/musicex_v1.rs @@ -36,7 +36,8 @@ impl Default for MusicExV1 { } impl MusicExV1 { - pub fn from_bytes(buffer: &[u8]) -> anyhow::Result { + #[allow(clippy::field_reassign_with_default)] + fn from_bytes_inner(buffer: &[u8]) -> Result { assert_eq!(buffer.len(), 0xC0 - 0x10); let mut cursor = Cursor::new(&buffer); @@ -50,11 +51,15 @@ impl MusicExV1 { Ok(result) } + + pub fn from_bytes(buffer: &[u8]) -> Result { + Self::from_bytes_inner(buffer).map_err(FooterParseError::MusicEx1ParseError) + } } pub fn parse_v1(footer: &[u8]) -> Result, FooterParseError> { let (payload, payload_len) = footer.split_at(footer.len() - 4); - let payload_len = LE::read_u32(&payload_len) as usize; + let payload_len = LE::read_u32(payload_len) as usize; if payload_len != 0xC0 { Err(FooterParseError::PCv2MusicExUnsupportedPayloadSize( payload_len, @@ -62,8 +67,7 @@ pub fn parse_v1(footer: &[u8]) -> Result, FooterParseError> { } let payload = &payload[payload.len() - (payload_len - 0x10)..]; - let payload = - MusicExV1::from_bytes(payload).map_err(FooterParseError::PCv2MusicExInvalidError)?; + let payload = MusicExV1::from_bytes(payload)?; let mid = from_ascii_utf16(&payload.mid); let media_filename = from_ascii_utf16(&payload.media_filename); diff --git a/um_crypto/qmc/src/lib.rs b/um_crypto/qmc/src/lib.rs index 3a70048..1194454 100644 --- a/um_crypto/qmc/src/lib.rs +++ b/um_crypto/qmc/src/lib.rs @@ -1,6 +1,5 @@ use crate::v2_map::QMC2Map; use crate::v2_rc4::cipher::QMC2RC4; -use anyhow::Result; use thiserror::Error; pub mod ekey; @@ -13,6 +12,9 @@ pub mod v2_rc4; pub enum QmcCryptoError { #[error("QMC V2/Map Cipher: Key is empty")] QMCV2MapKeyEmpty, + + #[error("EKey: {0}")] + EKeyParseError(#[from] ekey::EKeyDecryptError), } #[derive(Debug, PartialEq, Clone)] @@ -22,7 +24,7 @@ pub enum QMCv2Cipher { } impl QMCv2Cipher { - pub fn new(key: T) -> Result + pub fn new(key: T) -> Result where T: AsRef<[u8]>, { @@ -35,7 +37,7 @@ impl QMCv2Cipher { Ok(cipher) } - pub fn new_from_ekey>(ekey_str: T) -> Result { + pub fn new_from_ekey>(ekey_str: T) -> Result { let key = ekey::decrypt(ekey_str)?; Self::new(key) } diff --git a/um_crypto/qmc/src/v2_map/key.rs b/um_crypto/qmc/src/v2_map/key.rs index 58b02c9..98ea566 100644 --- a/um_crypto/qmc/src/v2_map/key.rs +++ b/um_crypto/qmc/src/v2_map/key.rs @@ -3,7 +3,7 @@ use crate::QmcCryptoError; const INDEX_OFFSET: usize = 71214; -pub fn key_compress>(long_key: T) -> anyhow::Result<[u8; V1_KEY_SIZE]> { +pub fn key_compress>(long_key: T) -> Result<[u8; V1_KEY_SIZE], QmcCryptoError> { let long_key = long_key.as_ref(); if long_key.is_empty() { Err(QmcCryptoError::QMCV2MapKeyEmpty)?; diff --git a/um_crypto/qmc/src/v2_map/mod.rs b/um_crypto/qmc/src/v2_map/mod.rs index c9b9e8b..32d33de 100644 --- a/um_crypto/qmc/src/v2_map/mod.rs +++ b/um_crypto/qmc/src/v2_map/mod.rs @@ -2,7 +2,7 @@ mod key; use crate::v1::cipher::{qmc1_transform, V1_KEY_SIZE}; use crate::v2_map::key::key_compress; -use anyhow::Result; +use crate::QmcCryptoError; #[derive(Debug, PartialEq, Clone)] pub struct QMC2Map { @@ -10,7 +10,7 @@ pub struct QMC2Map { } impl QMC2Map { - pub fn new>(key: T) -> Result { + pub fn new>(key: T) -> Result { let key = key_compress(key)?; Ok(Self { key }) }