From 042703763863b19b0a0046d8751b3e8908adc23a Mon Sep 17 00:00:00 2001 From: mymyme <137290915+mymyme@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:12:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20sanitize=20system=20proxy=20exceptions?= =?UTF-8?q?=20to=20avoid=20macOS=20ExceptionsList=20b=E2=80=A6=20(#9815)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: sanitize system proxy exceptions to avoid macOS ExceptionsList being dropped On macOS/Linux the exception list is comma-separated and passed to networksetup. It was only stripped of spaces, so a stray newline or a trailing comma left a malformed/empty entry. macOS configd then silently rejects the whole ExceptionsList (scutil --proxy shows no ExceptionsList), so the bypass never takes effect. Split on ',' with TrimEntries + RemoveEmptyEntries and rejoin; behavior-preserving for well-formed input. Windows path (';') is left unchanged. Note: not built locally (no .NET SDK on hand); relying on CI. * Update SysProxyHandler.cs --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com> --- .../Handler/SysProxy/SysProxyHandler.cs | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs b/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs index c525da29..e667937a 100644 --- a/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs +++ b/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs @@ -16,7 +16,6 @@ public static class SysProxyHandler try { var port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks); - var exceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", ""); if (port <= 0) { return false; @@ -24,17 +23,18 @@ public static class SysProxyHandler switch (type) { case ESysProxyType.ForcedChange when Utils.IsWindows(): - { - GetWindowsProxyString(config, port, out var strProxy, out var strExceptions); - ProxySettingWindows.SetProxy(strProxy, strExceptions, 2); - break; - } + var (strProxy, strExceptions) = GetWindowsProxyString(config, port); + ProxySettingWindows.SetProxy(strProxy, strExceptions, 2); + break; + case ESysProxyType.ForcedChange when Utils.IsLinux(): + var exceptions = SanitizeExceptions(config); await ProxySettingLinux.SetProxy(Global.Loopback, port, exceptions); break; case ESysProxyType.ForcedChange when Utils.IsMacOS(): - await ProxySettingOSX.SetProxy(Global.Loopback, port, exceptions); + var exceptions2 = SanitizeExceptions(config); + await ProxySettingOSX.SetProxy(Global.Loopback, port, exceptions2); break; case ESysProxyType.ForcedClear when Utils.IsWindows(): @@ -66,15 +66,31 @@ public static class SysProxyHandler return true; } - private static void GetWindowsProxyString(Config config, int port, out string strProxy, out string strExceptions) + private static string SanitizeExceptions(Config config) { - strExceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", ""); + var exceptions = config.SystemProxyItem.SystemProxyExceptions; + if (exceptions.IsNullOrEmpty()) + { + return string.Empty; + } + + var items = exceptions + .Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(item => item.Replace(" ", string.Empty)) + .Where(item => item.Length > 0); + + return string.Join(',', items); + } + + private static (string strProxy, string strExceptions) GetWindowsProxyString(Config config, int port) + { + var strExceptions = config.SystemProxyItem.SystemProxyExceptions.Replace(" ", ""); if (config.SystemProxyItem.NotProxyLocalAddress) { strExceptions = $";{strExceptions}"; } - strProxy = string.Empty; + var strProxy = string.Empty; if (config.SystemProxyItem.SystemProxyAdvancedProtocol.IsNullOrEmpty()) { strProxy = $"{Global.Loopback}:{port}"; @@ -86,6 +102,8 @@ public static class SysProxyHandler .Replace("{http_port}", port.ToString()) .Replace("{socks_port}", port.ToString()); } + + return (strProxy, strExceptions); } [SupportedOSPlatform("windows")]