refactor: harden tests

This commit is contained in:
zhom
2026-07-21 23:13:17 +04:00
parent f7daf68b52
commit 9624ec846d
81 changed files with 11771 additions and 983 deletions
+28 -41
View File
@@ -1057,6 +1057,23 @@ impl CookieManager {
mod tests {
use super::*;
#[cfg(target_os = "macos")]
const SYNTHETIC_COOKIE_HOST: &str = ".example.test";
#[cfg(target_os = "macos")]
const SYNTHETIC_COOKIE_VALUE: &str = "synthetic-cookie-value";
#[cfg(target_os = "macos")]
const SYNTHETIC_OS_CRYPT_PASSWORD: &[u8] = b"donut-synthetic-cookie-key";
#[cfg(target_os = "macos")]
const SYNTHETIC_ENCRYPTED_COOKIE_HEX: &str = "763130d83b9fd3e6d1b1c793769f55251f5e9d1193be72c0c08ea32e2cf068a85d9d0b97d8b2e6deca93a2b3c290e98e1a851f83d5566f9aa9314befe56dc6bdbd423d";
#[cfg(target_os = "macos")]
fn synthetic_encrypted_cookie() -> Vec<u8> {
(0..SYNTHETIC_ENCRYPTED_COOKIE_HEX.len())
.step_by(2)
.map(|i| u8::from_str_radix(&SYNTHETIC_ENCRYPTED_COOKIE_HEX[i..i + 2], 16).unwrap())
.collect()
}
#[test]
fn test_parse_netscape_cookies_valid() {
let content = "# Netscape HTTP Cookie File\n\
@@ -1482,50 +1499,29 @@ mod tests {
let _ = std::fs::remove_file(&tmp);
}
/// Regression: decrypting a real v10-encrypted Chromium cookie with the
/// correct PBKDF2 iterations and the `SHA-256(host_key)` integrity-prefix
/// strip. Captured from a real Wayfern profile:
/// host_key = ".github.com"
/// name = "_octo"
/// password = "OSfgzI5GUqy/pK4ANrYugw==" (contents of os_crypt_key)
/// value = "GH1.1.2077424036.1774792325"
///
/// If PBKDF2 iterations or the host-hash prefix handling ever regress,
/// this test fails and we instantly know why all copied cookies end up
/// with empty values — which is exactly the bug that shipped and made
/// issue-265-style silent failures reappear.
#[test]
#[cfg(target_os = "macos")]
fn test_decrypt_v10_cookie_with_real_vector() {
fn test_decrypt_v10_cookie_with_synthetic_vector() {
let profile_dir =
std::env::temp_dir().join(format!("donut_decrypt_vector_{}", uuid::Uuid::new_v4()));
std::fs::create_dir_all(&profile_dir).unwrap();
std::fs::write(
profile_dir.join("os_crypt_key"),
b"OSfgzI5GUqy/pK4ANrYugw==",
SYNTHETIC_OS_CRYPT_PASSWORD,
)
.unwrap();
let key = chrome_decrypt::get_encryption_key(&profile_dir)
.expect("should derive key from os_crypt_key file");
let encrypted_hex = "76313077ad5b27e78f685a6ccc7b92a8a242e279e54b8d2ba8e55b433ca7e2421bec52369e29a57b593c02c839f50962245da3ed8617dce142fff67778950a271d2c07";
let encrypted: Vec<u8> = (0..encrypted_hex.len())
.step_by(2)
.map(|i| u8::from_str_radix(&encrypted_hex[i..i + 2], 16).unwrap())
.collect();
let decrypted = chrome_decrypt::decrypt(&encrypted, ".github.com", &key)
.expect("decryption must succeed with correct key and host");
assert_eq!(decrypted, "GH1.1.2077424036.1774792325");
let decrypted =
chrome_decrypt::decrypt(&synthetic_encrypted_cookie(), SYNTHETIC_COOKIE_HOST, &key)
.expect("decryption must succeed with correct key and host");
assert_eq!(decrypted, SYNTHETIC_COOKIE_VALUE);
let _ = std::fs::remove_dir_all(&profile_dir);
}
/// Sanity: decrypting with the wrong host_key (hash mismatch) must not
/// return a half-garbage value — it should fall back to the full
/// decrypted bytes, which for a modern cookie includes the 32-byte hash
/// prefix and therefore won't be valid UTF-8 → `None`.
#[test]
#[cfg(target_os = "macos")]
fn test_decrypt_with_wrong_host_returns_none_or_raw() {
@@ -1534,25 +1530,16 @@ mod tests {
std::fs::create_dir_all(&profile_dir).unwrap();
std::fs::write(
profile_dir.join("os_crypt_key"),
b"OSfgzI5GUqy/pK4ANrYugw==",
SYNTHETIC_OS_CRYPT_PASSWORD,
)
.unwrap();
let key = chrome_decrypt::get_encryption_key(&profile_dir).unwrap();
let encrypted_hex = "76313077ad5b27e78f685a6ccc7b92a8a242e279e54b8d2ba8e55b433ca7e2421bec52369e29a57b593c02c839f50962245da3ed8617dce142fff67778950a271d2c07";
let encrypted: Vec<u8> = (0..encrypted_hex.len())
.step_by(2)
.map(|i| u8::from_str_radix(&encrypted_hex[i..i + 2], 16).unwrap())
.collect();
// Wrong host: the prefix won't match, so we fall through to
// `String::from_utf8(full_decrypted)` which fails on the binary hash
// bytes and returns `None`. Either way, we must NOT return the real
// value "GH1.1.2077424036.1774792325".
let result = chrome_decrypt::decrypt(&encrypted, ".facebook.com", &key);
let result =
chrome_decrypt::decrypt(&synthetic_encrypted_cookie(), ".wrong.example.test", &key);
assert!(
result.as_deref() != Some("GH1.1.2077424036.1774792325"),
"decrypt must not return the real cookie value when host_key is wrong"
result.as_deref() != Some(SYNTHETIC_COOKIE_VALUE),
"decrypt must not return the cookie value when host_key is wrong"
);
let _ = std::fs::remove_dir_all(&profile_dir);