From 349c635de0ca7fe525f4f2bab8052e1037edf3de Mon Sep 17 00:00:00 2001 From: ayanamislover <104753598+ayanamislover@users.noreply.github.com> Date: Wed, 19 Aug 2026 13:55:40 +0000 Subject: [PATCH] fix(sysproxy): use platform-specific bypass separator (#7559) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(sysproxy): use platform bypass separator * refactor: squash conditional compilation logic - Share a single `BYPASS_SEPERATOR` definition between both Linux and macOS --------- Co-authored-by: Ayanami Co-authored-by: ❤是纱雾酱哟~ <49941141+Dragon1573@users.noreply.github.com> Co-authored-by: oomeow --- src-tauri/src/core/sysopt.rs | 56 +++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src-tauri/src/core/sysopt.rs b/src-tauri/src/core/sysopt.rs index 852805e70..13dfe0012 100644 --- a/src-tauri/src/core/sysopt.rs +++ b/src-tauri/src/core/sysopt.rs @@ -255,24 +255,32 @@ impl Default for Sysopt { #[cfg(target_os = "windows")] static DEFAULT_BYPASS: &str = "localhost;127.*;192.168.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;"; +#[cfg(target_os = "windows")] +static BYPASS_SEPARATOR: &str = ";"; #[cfg(target_os = "linux")] static DEFAULT_BYPASS: &str = "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,::1"; +#[cfg(any(target_os = "linux", target_os = "macos"))] +static BYPASS_SEPARATOR: &str = ","; #[cfg(target_os = "macos")] static DEFAULT_BYPASS: &str = "127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,localhost,*.local,*.crashlytics.com,"; +fn format_bypass(use_default: bool, custom_bypass: &str) -> String { + if custom_bypass.is_empty() { + DEFAULT_BYPASS.into() + } else if use_default { + format!("{DEFAULT_BYPASS}{BYPASS_SEPARATOR}{custom_bypass}").into() + } else { + custom_bypass.into() + } +} + async fn get_bypass() -> String { let verge = Config::verge().await.latest_arc(); let use_default = verge.use_default_bypass.unwrap_or(true); let custom_bypass = verge.system_proxy_bypass.as_deref().unwrap_or(""); - if custom_bypass.is_empty() { - DEFAULT_BYPASS.into() - } else if use_default { - format!("{DEFAULT_BYPASS},{custom_bypass}").into() - } else { - custom_bypass.into() - } + format_bypass(use_default, custom_bypass) } singleton!(Sysopt, SYSOPT); @@ -560,14 +568,42 @@ impl Sysopt { #[cfg(test)] mod tests { use super::{ - AuthoritativeState, OsProxyState, ProxyApplyStep, SystemProxyStateUnknown, authoritative_state, - authoritative_state_from, classify_os_proxy_state, disable_both, disable_until_the_last_write_is_ours, - first_failure, proxy_apply_steps, recover_from_failed_write, target_is_already_in_place, + AuthoritativeState, BYPASS_SEPARATOR, DEFAULT_BYPASS, OsProxyState, ProxyApplyStep, SystemProxyStateUnknown, + authoritative_state, authoritative_state_from, classify_os_proxy_state, disable_both, + disable_until_the_last_write_is_ours, first_failure, format_bypass, proxy_apply_steps, + recover_from_failed_write, target_is_already_in_place, }; use parking_lot::Mutex; use std::collections::VecDeque; use sysproxy::{Autoproxy, Sysproxy}; + #[test] + fn empty_custom_bypass_uses_defaults() { + assert_eq!(format_bypass(false, ""), DEFAULT_BYPASS); + } + + #[test] + fn custom_bypass_can_replace_defaults() { + assert_eq!(format_bypass(false, "example.com"), "example.com"); + } + + #[test] + fn default_and_custom_bypass_use_platform_separator() { + assert_eq!( + format_bypass(true, "example.com"), + format!("{DEFAULT_BYPASS}{BYPASS_SEPARATOR}example.com") + ); + } + + #[cfg(target_os = "windows")] + #[test] + fn windows_default_and_custom_bypass_use_semicolon() { + assert_eq!( + format_bypass(true, "example.com"), + format!("{DEFAULT_BYPASS};example.com") + ); + } + async fn record_disable_sequence( drained: bool, second_drain: bool,