diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index ecd88c25..7b741203 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -10,13 +10,13 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" -version = "0.8.4" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +checksum = "fc0fc36d7440d015b45468ba08a21e80e056ebbd014c611c6298bb7503e04bd1" dependencies = [ - "cfg-if", "cipher", - "cpufeatures", + "cpubits", + "cpufeatures 0.3.1", ] [[package]] @@ -58,15 +58,6 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" -[[package]] -name = "arbitrary" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bc62ac97cc33321f50863d514c3bc38a453947a8f9e781137e47c7401020aed" -dependencies = [ - "derive_arbitrary", -] - [[package]] name = "atk" version = "0.18.2" @@ -168,6 +159,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", + "zeroize", +] + [[package]] name = "block2" version = "0.6.2" @@ -236,21 +237,11 @@ dependencies = [ [[package]] name = "bzip2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47" -dependencies = [ - "bzip2-sys", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ - "cc", - "pkg-config", + "libbz2-rs-sys", ] [[package]] @@ -366,6 +357,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + [[package]] name = "chrono" version = "0.4.45" @@ -380,14 +377,20 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common", + "crypto-common 0.2.2", "inout", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "combine" version = "4.6.9" @@ -398,11 +401,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "const-oid" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be95d4a884358a21a199689323c29e9256b4a1b315e22f183d155422041d3a9a" + [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "9eb6feb175df65d0a3ccd3e73484e940d0ac664e8034f0519fd49a93db3071d9" +dependencies = [ + "rustversion", +] [[package]] name = "cookie" @@ -476,6 +488,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -485,6 +503,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.4.0" @@ -534,6 +561,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "cssparser" version = "0.37.0" @@ -563,6 +599,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" +[[package]] +name = "ctutils" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "261af4dc7a06ea8a527a8717d8cbba3417530d6ea14e1edb3de6b67806be474f" +dependencies = [ + "cmov", +] + [[package]] name = "darling" version = "0.24.1" @@ -623,17 +668,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "derive_arbitrary" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b034bd7d5f032402a2479444dcc6f74e36a03f31854d41680fb240ef682a1ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.9", -] - [[package]] name = "derive_more" version = "2.1.1" @@ -661,9 +695,21 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", - "subtle", + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", + "ctutils", + "zeroize", ] [[package]] @@ -1163,11 +1209,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] @@ -1177,8 +1221,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", + "wasm-bindgen", ] [[package]] @@ -1361,11 +1407,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest", + "digest 0.11.3", ] [[package]] @@ -1417,6 +1463,15 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.12.0" @@ -1638,11 +1693,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "3a580c13f0ffc335ef42dd3f6b1a41b726051c5e1656d9a3aa6fddb3c5dfbbf9" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -1853,6 +1908,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "libbz2-rs-sys" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f454fd6831a29c0e827ed075bca2a15be201bd57f4168f0fd1041124eab17e" + [[package]] name = "libc" version = "0.2.191" @@ -1920,16 +1981,6 @@ version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d15f86d12da44cd8d4ec3c73984537eb7f4cadcb9776a575a0a8a05ca11005c" -[[package]] -name = "lzma-rs" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" -dependencies = [ - "byteorder", - "crc", -] - [[package]] name = "lzma-rust" version = "0.1.7" @@ -1940,14 +1991,12 @@ dependencies = [ ] [[package]] -name = "lzma-sys" -version = "0.1.20" +name = "lzma-rust2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +checksum = "7277c9742229dc25243236d578b6471a798c554512c6f6a04365ec2e87c2a3bb" dependencies = [ - "cc", - "libc", - "pkg-config", + "sha2 0.11.1", ] [[package]] @@ -2076,6 +2125,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nt-time" version = "0.8.1" @@ -2330,7 +2391,7 @@ dependencies = [ "serde", "serde_json", "sevenz-rust", - "sha2", + "sha2 0.10.9", "tar", "tauri", "tauri-build", @@ -2402,11 +2463,11 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" dependencies = [ - "digest", + "digest 0.11.3", "hmac", ] @@ -2537,6 +2598,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" +[[package]] +name = "ppmd-rust" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd4acc8d264ea385db64ccfdcdfd5909ee9eda0975666723d59f3bfec80b3611" + [[package]] name = "precomputed-hash" version = "0.1.1" @@ -3093,19 +3160,19 @@ dependencies = [ "js-sys", "lzma-rust", "nt-time", - "sha2", + "sha2 0.10.9", "wasm-bindgen", ] [[package]] name = "sha1" -version = "0.10.7" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] @@ -3115,8 +3182,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d7069beb7d6ac7b9acd1039986e73443f24234f41074da099d6f994ac9ad19" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] @@ -3496,7 +3574,7 @@ dependencies = [ "semver", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "syn 2.0.119", "tauri-utils", "thiserror 2.0.21", @@ -3688,6 +3766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", + "js-sys", "num-conv", "powerfmt", "serde_core", @@ -3942,6 +4021,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typed-path" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54ec2755506471f54baf5e4bb5499d8e510cc1caf271270e778a736bd2d7336c" + [[package]] name = "typeid" version = "1.0.3" @@ -4696,7 +4781,7 @@ dependencies = [ "objc2-web-kit", "percent-encoding", "raw-window-handle", - "sha2", + "sha2 0.10.9", "soup3", "tao-macros", "thiserror 2.0.21", @@ -4741,15 +4826,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "xz2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" -dependencies = [ - "lzma-sys", -] - [[package]] name = "yoke" version = "0.8.4" @@ -4799,20 +4875,6 @@ name = "zeroize" version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] [[package]] name = "zerotrie" @@ -4849,27 +4911,27 @@ dependencies = [ [[package]] name = "zip" -version = "2.6.1" +version = "9.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dcb24d0152526ae49b9b96c1dcf71850ca1e0b882e4e28ed898a93c41334744" +checksum = "6e04976da629d3b04204ba8105b396a193af8ad2583b2c79bfb3ab8af580a11e" dependencies = [ "aes", - "arbitrary", "bzip2", "constant_time_eq", "crc32fast", - "crossbeam-utils", "deflate64", "flate2", - "getrandom 0.3.4", + "getrandom 0.4.3", "hmac", "indexmap 2.14.2", - "lzma-rs", + "lzma-rust2", "memchr", + "nix", "pbkdf2", + "ppmd-rust", "sha1", "time", - "xz2", + "typed-path", "zeroize", "zopfli", "zstd", @@ -4901,18 +4963,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.4" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb02c3132d251ab1606e9fc913a7da6c6ed08cc263df15edf082e1dc497d157" +checksum = "db3ae9bf90af6e40197bef767eeefc46ad6397420fe873830bd85e5fbbfb3c70" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.4.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c8ea04668f5de8d8d51051714ba560c9536519cadcdb8829bba4fe2ad159b03" +checksum = "ded520f16b29e1a9b771c722221b2b0a0398c2316d9bb3c42b458a5414d7434b" dependencies = [ "zstd-sys", ] diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index a657e5fe..da0ab88d 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -18,7 +18,7 @@ url = "2.5.8" base64 = "0.23" sevenz-rust = "0.6.1" ureq = { version = "3.5.1", default-features = false, features = ["rustls", "cookies"] } -zip = "2.4" +zip = "9.0" flate2 = "1" tar = "0.4" diff --git a/desktop/src-tauri/src/player.rs b/desktop/src-tauri/src/player.rs index 493a04b2..3a258073 100644 --- a/desktop/src-tauri/src/player.rs +++ b/desktop/src-tauri/src/player.rs @@ -532,7 +532,9 @@ fn extract_mpv_zip(archive: &Path, data_dir: &Path) -> Result { let mut entry = zip .by_index(index) .map_err(|_| "mpv archive open failed".to_string())?; - let name = entry.name().to_string(); + let name = entry + .name() + .map_err(|_| "mpv archive path rejected".to_string())?; if !safe_archive_name(&name) { return Err("mpv archive path rejected".to_string()); } diff --git a/desktop/src-tauri/src/player/tests.rs b/desktop/src-tauri/src/player/tests.rs index cee5f3d2..ead441d3 100644 --- a/desktop/src-tauri/src/player/tests.rs +++ b/desktop/src-tauri/src/player/tests.rs @@ -598,3 +598,99 @@ fn player_smoke_codecs() { }); assert_eq!(status.state, PlayerState::Error); } + +fn gzip_tar(entries: &[(&str, &[u8])]) -> Vec { + let mut raw = tar::Builder::new(Vec::new()); + for (name, bytes) in entries { + let mut header = tar::Header::new_gnu(); + header.set_size(bytes.len() as u64); + header.set_mode(0o644); + header.set_entry_type(tar::EntryType::Regular); + let name_bytes = name.as_bytes(); + assert!(name_bytes.len() < 100, "tar name fits the ustar field"); + header.as_mut_bytes()[..name_bytes.len()].copy_from_slice(name_bytes); + header.set_cksum(); + raw.append(&header, *bytes).unwrap(); + } + let raw = raw.into_inner().unwrap(); + let mut gzip = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default()); + std::io::Write::write_all(&mut gzip, &raw).unwrap(); + gzip.finish().unwrap() +} + +fn zip_archive(entries: &[(&str, &[u8])]) -> Vec { + let mut cursor = std::io::Cursor::new(Vec::new()); + { + let mut writer = zip::ZipWriter::new(&mut cursor); + let options = zip::write::SimpleFileOptions::default() + .compression_method(zip::CompressionMethod::Stored); + for (name, bytes) in entries { + writer.start_file(*name, options).unwrap(); + std::io::Write::write_all(&mut writer, bytes).unwrap(); + } + writer.finish().unwrap(); + } + cursor.into_inner() +} + +fn archive_file(bytes: &[u8]) -> (tempfile::TempDir, std::path::PathBuf) { + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("mpv.zip"); + std::fs::write(&path, bytes).unwrap(); + (dir, path) +} + +#[test] +fn extract_mpv_zip_unpacks_the_bundled_binary() { + let payload = b"mpv-binary"; + let packed = gzip_tar(&[("mpv.app/Contents/MacOS/mpv", payload)]); + let archive = zip_archive(&[("payload/mpv.tar.gz", packed.as_slice())]); + let (dir, path) = archive_file(&archive); + let data = dir.path().join("data"); + + let executable = super::extract_mpv(&path, &data).unwrap(); + + assert_eq!(executable, data.join("mpv.app/Contents/MacOS/mpv")); + assert_eq!(std::fs::read(&executable).unwrap(), payload); +} + +#[test] +fn extract_mpv_zip_rejects_a_parent_directory_entry() { + let packed = gzip_tar(&[("mpv.app/Contents/MacOS/mpv", b"mpv-binary")]); + let archive = zip_archive(&[ + ("../mpv.tar.gz", packed.as_slice()), + ("payload/mpv.tar.gz", packed.as_slice()), + ]); + let (dir, path) = archive_file(&archive); + let data = dir.path().join("data"); + + let error = super::extract_mpv(&path, &data).unwrap_err(); + + assert_eq!(error, "mpv archive path rejected"); + assert!(!dir.path().join("mpv.tar.gz").exists()); +} + +#[test] +fn extract_mpv_zip_rejects_an_absolute_entry() { + let packed = gzip_tar(&[("mpv.app/Contents/MacOS/mpv", b"mpv-binary")]); + let archive = zip_archive(&[("/mpv.tar.gz", packed.as_slice())]); + let (dir, path) = archive_file(&archive); + let data = dir.path().join("data"); + + let error = super::extract_mpv(&path, &data).unwrap_err(); + + assert_eq!(error, "mpv archive path rejected"); +} + +#[test] +fn extract_mpv_zip_rejects_a_parent_path_inside_the_tar() { + let packed = gzip_tar(&[("../escaped", b"nope")]); + let archive = zip_archive(&[("mpv.tar.gz", packed.as_slice())]); + let (dir, path) = archive_file(&archive); + let data = dir.path().join("data"); + + let error = super::extract_mpv(&path, &data).unwrap_err(); + + assert_eq!(error, "mpv archive path rejected"); + assert!(!dir.path().join("escaped").exists()); +}