From 7d20913d56bd0e9cf92184b01712cb0bd64f083c Mon Sep 17 00:00:00 2001 From: Kayos Date: Sun, 24 May 2026 12:36:17 -0700 Subject: [PATCH] player: preserve Deobfuscation error class through map_url wrapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Followup to audit CRIT-1. The original audit added Deobfuscation to the switch_client whitelist but missed that map_url re-wraps the cipher_to_url_params error into ExtractionError::InvalidData on line ~727 — InvalidData is NOT switchable, so when a cipher stream appears on Mobile/Desktop (where our sig fn is unavailable), the player chain still died instead of falling through to the next client. Caught by the full integration suite: get_player_from_client::case_2_mobile panicked with InvalidData wrapping our "sig fn unavailable" error. Now stays as Deobfuscation through the wrap so switch_client trips and iOS / Tv handle the request instead. --- src/client/player.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/client/player.rs b/src/client/player.rs index a57558f..927ab1d 100644 --- a/src/client/player.rs +++ b/src/client/player.rs @@ -725,10 +725,19 @@ impl<'a> StreamsMapper<'a> { None => match signature_cipher { Some(signature_cipher) => { self.cipher_to_url_params(signature_cipher).map_err(|e| { - ExtractionError::InvalidData( - format!("Could not deobfuscate signatureCipher `{signature_cipher}`: {e}") - .into(), - ) + // Audit follow-up to CRIT-1: keep the Deobfuscation + // error class through the wrapper so `switch_client` + // still trips when a cipher stream surfaces on a + // client whose deobf is unavailable. The previous + // `InvalidData(...)` wrapping silently demoted this + // to a non-switchable error and killed the whole + // player_from_clients chain on Mobile/Desktop sig paths. + ExtractionError::Deobfuscation( + format!( + "signatureCipher `{signature_cipher}`: {e}" + ) + .into(), + ) }) } None => Err(ExtractionError::InvalidData(