[tor-commits] [tor-browser] 09/311: Bug 1749501 - Revert bug 1392272, r=dragana a=RyanVM, dsmith

gitolite role git at cupani.torproject.org
Tue Apr 26 15:26:49 UTC 2022


This is an automated email from the git hooks/post-receive script.

pierov pushed a commit to branch geckoview-99.0.1-11.0-1
in repository tor-browser.

commit fff38e7acb7916c7e9113eae5b52d2ab816a21db
Author: Kershaw Chang <kershaw at mozilla.com>
AuthorDate: Thu Jan 13 01:24:49 2022 +0000

    Bug 1749501 - Revert bug 1392272, r=dragana a=RyanVM,dsmith
    
    Differential Revision: https://phabricator.services.mozilla.com/D135702
---
 .../windowsproxy/nsWindowsSystemProxySettings.cpp  | 475 ++++-----------------
 1 file changed, 93 insertions(+), 382 deletions(-)

diff --git a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
index 8ac245f09ee8e..7921cb60a242f 100644
--- a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
+++ b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
@@ -6,52 +6,30 @@
 #include <windows.h>
 #include <ras.h>
 #include <wininet.h>
-#include <functional>
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/Atomics.h"
 #include "nsISystemProxySettings.h"
 #include "mozilla/Components.h"
-#include "mozilla/Mutex.h"
-#include "mozilla/Services.h"
 #include "mozilla/ProfilerLabels.h"
-#include "mozilla/StaticPrefs_network.h"
-#include "mozilla/Tokenizer.h"
-#include "mozilla/Unused.h"
-#include "nsComponentManagerUtils.h"
-#include "nsIObserver.h"
-#include "nsIObserverService.h"
-#include "nsIWindowsRegKey.h"
 #include "nsPrintfCString.h"
 #include "nsNetCID.h"
 #include "nsThreadUtils.h"
 #include "prnetdb.h"
 #include "ProxyUtils.h"
-#include "ProxyConfig.h"
 
-using namespace mozilla::net;
-
-class nsWindowsSystemProxySettings : public nsISystemProxySettings {
+class nsWindowsSystemProxySettings final : public nsISystemProxySettings {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSISYSTEMPROXYSETTINGS
 
   nsWindowsSystemProxySettings(){};
-  virtual nsresult Init() { return NS_OK; }
 
- protected:
-  virtual ~nsWindowsSystemProxySettings() = default;
+ private:
+  ~nsWindowsSystemProxySettings(){};
 
   bool MatchOverride(const nsACString& aHost);
-  bool MatchOverrideInternal(const nsACString& aHost,
-                             const nsACString& aOverrideRule);
   bool PatternMatch(const nsACString& aHost, const nsACString& aOverride);
-  nsresult ReadProxyRules(
-      uint32_t aOptions,
-      const std::function<bool(uint32_t aFlags)>& aFlagsHandler,
-      const std::function<void(const nsACString& aRule, bool& aContinue)>&
-          aRuleHandler);
 };
 
 NS_IMPL_ISUPPORTS(nsWindowsSystemProxySettings, nsISystemProxySettings)
@@ -65,6 +43,18 @@ nsWindowsSystemProxySettings::GetMainThreadOnly(bool* aMainThreadOnly) {
   return NS_OK;
 }
 
+static void SetProxyResult(const char* aType, const nsACString& aHostPort,
+                           nsACString& aResult) {
+  aResult.AssignASCII(aType);
+  aResult.Append(' ');
+  aResult.Append(aHostPort);
+}
+
+static void SetProxyResultDirect(nsACString& aResult) {
+  // For whatever reason, a proxy is not to be used.
+  aResult.AssignLiteral("DIRECT");
+}
+
 static nsresult ReadInternetOption(uint32_t aOption, uint32_t& aFlags,
                                    nsAString& aValue) {
   // Bug 1366133: InternetGetConnectedStateExW() may cause hangs
@@ -103,82 +93,47 @@ static nsresult ReadInternetOption(uint32_t aOption, uint32_t& aFlags,
   return NS_OK;
 }
 
-bool nsWindowsSystemProxySettings::MatchOverrideInternal(
-    const nsACString& aHost, const nsACString& aOverrideRule) {
-  // Windows formats its proxy override list in the form:
-  // server;server;server where 'server' is a server name pattern or IP
-  // address, or "<local>". "<local>" must be translated to
-  // "localhost;127.0.0.1".
-  // In a server name pattern, a '*' character matches any substring and
-  // all other characters must match themselves; the whole pattern must match
-  // the whole hostname.
-  nsAutoCString host(aHost);
-  if (aOverrideRule.EqualsLiteral("<local>")) {
-    PRNetAddr addr;
-    bool isIpAddr = (PR_StringToNetAddr(host.get(), &addr) == PR_SUCCESS);
-
-    // Don't use proxy for local hosts (plain hostname, no dots)
-    if (!isIpAddr && !host.Contains('.')) {
-      return true;
-    }
-
-    if (host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1")) {
-      return true;
-    }
-  } else if (PatternMatch(host, aOverrideRule)) {
-    return true;
-  }
-
-  return false;
-}
-
 bool nsWindowsSystemProxySettings::MatchOverride(const nsACString& aHost) {
-  nsAutoCString host(aHost);
-  bool foundMatch = false;
-
-  auto flagHandler = [](uint32_t aFlags) { return true; };
-  auto ruleHandler = [&](const nsACString& aOverrideRule, bool& aContinue) {
-    foundMatch = MatchOverrideInternal(aHost, aOverrideRule);
-    if (foundMatch) {
-      aContinue = false;
-    }
-  };
-
-  ReadProxyRules(INTERNET_PER_CONN_PROXY_BYPASS, flagHandler, ruleHandler);
-  return foundMatch;
-}
-
-nsresult nsWindowsSystemProxySettings::ReadProxyRules(
-    uint32_t aOptions,
-    const std::function<bool(uint32_t aFlags)>& aFlagsHandler,
-    const std::function<void(const nsACString& aRule, bool& aContinue)>&
-        aRuleHandler) {
+  nsresult rv;
   uint32_t flags = 0;
   nsAutoString buf;
 
-  nsresult rv = ReadInternetOption(aOptions, flags, buf);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (!aFlagsHandler(flags)) {
-    return NS_ERROR_FAILURE;
-  }
+  rv = ReadInternetOption(INTERNET_PER_CONN_PROXY_BYPASS, flags, buf);
+  if (NS_FAILED(rv)) return false;
 
   NS_ConvertUTF16toUTF8 cbuf(buf);
 
+  nsAutoCString host(aHost);
   int32_t start = 0;
   int32_t end = cbuf.Length();
+
+  // Windows formats its proxy override list in the form:
+  // server;server;server where 'server' is a server name pattern or IP
+  // address, or "<local>". "<local>" must be translated to
+  // "localhost;127.0.0.1".
+  // In a server name pattern, a '*' character matches any substring and
+  // all other characters must match themselves; the whole pattern must match
+  // the whole hostname.
   while (true) {
     int32_t delimiter = cbuf.FindCharInSet(" ;", start);
     if (delimiter == -1) delimiter = end;
 
     if (delimiter != start) {
-      const nsAutoCString rule(Substring(cbuf, start, delimiter - start));
-      bool continueProcessing = false;
-      aRuleHandler(rule, continueProcessing);
-      if (!continueProcessing) {
-        return NS_OK;
+      const nsAutoCString override(Substring(cbuf, start, delimiter - start));
+      if (override.EqualsLiteral("<local>")) {
+        PRNetAddr addr;
+        bool isIpAddr = (PR_StringToNetAddr(host.get(), &addr) == PR_SUCCESS);
+
+        // Don't use proxy for local hosts (plain hostname, no dots)
+        if (!isIpAddr && !host.Contains('.')) {
+          return true;
+        }
+
+        if (host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1")) {
+          return true;
+        }
+      } else if (PatternMatch(host, override)) {
+        return true;
       }
     }
 
@@ -186,7 +141,7 @@ nsresult nsWindowsSystemProxySettings::ReadProxyRules(
     start = ++delimiter;
   }
 
-  return NS_OK;
+  return false;
 }
 
 bool nsWindowsSystemProxySettings::PatternMatch(const nsACString& aHost,
@@ -215,322 +170,78 @@ nsresult nsWindowsSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
                                                       const nsACString& aHost,
                                                       const int32_t aPort,
                                                       nsACString& aResult) {
-  auto flagHandler = [&](uint32_t aFlags) {
-    if (!(aFlags & PROXY_TYPE_PROXY)) {
-      ProxyConfig::SetProxyResultDirect(aResult);
-      return false;
-    }
+  nsresult rv;
+  uint32_t flags = 0;
+  nsAutoString buf;
 
-    if (MatchOverride(aHost)) {
-      ProxyConfig::SetProxyResultDirect(aResult);
-      return false;
-    }
+  rv = ReadInternetOption(INTERNET_PER_CONN_PROXY_SERVER, flags, buf);
+  if (NS_FAILED(rv) || !(flags & PROXY_TYPE_PROXY)) {
+    SetProxyResultDirect(aResult);
+    return NS_OK;
+  }
 
-    return true;
-  };
+  if (MatchOverride(aHost)) {
+    SetProxyResultDirect(aResult);
+    return NS_OK;
+  }
+
+  NS_ConvertUTF16toUTF8 cbuf(buf);
 
   constexpr auto kSocksPrefix = "socks="_ns;
   nsAutoCString prefix;
   ToLowerCase(aScheme, prefix);
+
   prefix.Append('=');
 
   nsAutoCString specificProxy;
   nsAutoCString defaultProxy;
   nsAutoCString socksProxy;
+  int32_t start = 0;
+  int32_t end = cbuf.Length();
 
-  auto ruleHandler = [&](const nsACString& aRule, bool& aContinue) {
-    const nsCString proxy(aRule);
-    aContinue = true;
-    if (proxy.FindChar('=') == -1) {
-      // If a proxy name is listed by itself, it is used as the
-      // default proxy for any protocols that do not have a specific
-      // proxy specified.
-      // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
-      defaultProxy = proxy;
-    } else if (proxy.Find(prefix) == 0) {
-      // To list a proxy for a specific protocol, the string must
-      // follow the format "<protocol>=<protocol>://<proxy_name>".
-      // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
-      specificProxy = Substring(proxy, prefix.Length());
-      aContinue = false;
-    } else if (proxy.Find(kSocksPrefix) == 0) {
-      // SOCKS proxy.
-      socksProxy = Substring(proxy, kSocksPrefix.Length());  // "socks=" length.
-    }
-  };
-
-  nsresult rv =
-      ReadProxyRules(INTERNET_PER_CONN_PROXY_SERVER, flagHandler, ruleHandler);
-  if (NS_FAILED(rv)) {
-    ProxyConfig::SetProxyResultDirect(aResult);
-    return rv;
-  }
-
-  ProxyConfig::ProxyStrToResult(specificProxy, defaultProxy, socksProxy,
-                                aResult);
-  return NS_OK;
-}
-
-class WindowsSystemProxySettingsAsync final
-    : public nsWindowsSystemProxySettings,
-      public nsIObserver {
- public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSISYSTEMPROXYSETTINGS
-  NS_DECL_NSIOBSERVER
-
-  WindowsSystemProxySettingsAsync();
-  nsresult Init() override;
-
- private:
-  virtual ~WindowsSystemProxySettingsAsync();
-  void ThreadFunc();
-  void OnProxyConfigChangedInternal();
-
-  ProxyConfig mConfig;
-  nsCOMPtr<nsIThread> mBackgroundThread;
-  mozilla::Mutex mLock{"WindowsSystemProxySettingsAsync"};
-  mozilla::Atomic<bool> mInited{false};
-  mozilla::Atomic<bool> mTerminated{false};
-};
-
-NS_IMPL_ISUPPORTS_INHERITED(WindowsSystemProxySettingsAsync,
-                            nsWindowsSystemProxySettings, nsIObserver);
-
-WindowsSystemProxySettingsAsync::WindowsSystemProxySettingsAsync() = default;
-
-WindowsSystemProxySettingsAsync::~WindowsSystemProxySettingsAsync() = default;
-
-nsresult WindowsSystemProxySettingsAsync::Init() {
-  nsCOMPtr<nsIObserverService> observerService =
-      mozilla::services::GetObserverService();
-  if (!observerService) {
-    return NS_ERROR_FAILURE;
-  }
-  observerService->AddObserver(this, "xpcom-shutdown-threads", false);
-
-  nsCOMPtr<nsIThread> thread;
-  if (NS_FAILED(NS_NewNamedThread("System Proxy", getter_AddRefs(thread)))) {
-    NS_WARNING("NS_NewNamedThread failed!");
-    return NS_ERROR_FAILURE;
-  }
-
-  mBackgroundThread = std::move(thread);
-
-  nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
-      "WindowsSystemProxySettingsAsync::ThreadFunc", this,
-      &WindowsSystemProxySettingsAsync::ThreadFunc);
-  return mBackgroundThread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-}
-
-NS_IMETHODIMP
-WindowsSystemProxySettingsAsync::Observe(nsISupports* aSubject,
-                                         const char* aTopic,
-                                         const char16_t* aData) {
-  if (!strcmp(aTopic, "xpcom-shutdown-threads")) {
-    if (mBackgroundThread) {
-      mTerminated = true;
-      nsCOMPtr<nsIThread> thread;
-      {
-        mozilla::MutexAutoLock lock(mLock);
-        thread = mBackgroundThread.get();
-        mBackgroundThread = nullptr;
-      }
-      MOZ_ALWAYS_SUCCEEDS(thread->Shutdown());
-    }
-  }
-  return NS_OK;
-}
-
-void WindowsSystemProxySettingsAsync::ThreadFunc() {
-  nsresult rv;
-  nsCOMPtr<nsIWindowsRegKey> regKey =
-      do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  rv = regKey->Open(
-      nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
-      u"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"_ns,
-      nsIWindowsRegKey::ACCESS_READ);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  OnProxyConfigChangedInternal();
-
-  rv = regKey->StartWatching(true);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  mInited = true;
-
-  while (!mTerminated) {
-    bool changed = false;
-    regKey->HasChanged(&changed);
-    if (changed) {
-      OnProxyConfigChangedInternal();
-    }
-  }
-}
-
-void WindowsSystemProxySettingsAsync::OnProxyConfigChangedInternal() {
-  ProxyConfig config;
-
-  // PAC
-  nsAutoCString pacUrl;
-  if (NS_SUCCEEDED(GetPACURI(pacUrl))) {
-    config.SetPACUrl(pacUrl);
-  }
+  while (true) {
+    int32_t delimiter = cbuf.FindCharInSet(" ;", start);
+    if (delimiter == -1) delimiter = end;
 
-  // proxies
-  auto flagHandler = [&](uint32_t aFlags) {
-    if (!(aFlags & PROXY_TYPE_PROXY)) {
-      return false;
-    }
-    return true;
-  };
-
-  // The format of input string is like: scheme=host:port, e.g.
-  // "http=127.0.0.1:3128".
-  auto processProxyStr = [](const nsCString& aInput,
-                            ProxyServer::ProxyType& aOutType,
-                            nsACString& aOutHost, int32_t& aOutPort) {
-    aOutType = ProxyServer::ProxyType::DEFAULT;
-    aOutHost = EmptyCString();
-    aOutPort = -1;
-
-    mozilla::Tokenizer t(aInput);
-    mozilla::Tokenizer::Token token;
-    // skip over spaces
-    t.SkipWhites();
-    t.Record();
-
-    bool parsingIPv6 = false;
-    bool parsingPort = false;
-    while (t.Next(token)) {
-      if (token.Equals(mozilla::Tokenizer::Token::EndOfFile())) {
-        if (aOutHost.IsEmpty()) {
-          t.Claim(aOutHost);
-        }
+    if (delimiter != start) {
+      const nsAutoCString proxy(Substring(cbuf, start, delimiter - start));
+      if (proxy.FindChar('=') == -1) {
+        // If a proxy name is listed by itself, it is used as the
+        // default proxy for any protocols that do not have a specific
+        // proxy specified.
+        // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
+        defaultProxy = proxy;
+      } else if (proxy.Find(prefix) == 0) {
+        // To list a proxy for a specific protocol, the string must
+        // follow the format "<protocol>=<protocol>://<proxy_name>".
+        // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
+        specificProxy = Substring(proxy, prefix.Length());
         break;
-      }
-
-      if (token.Equals(mozilla::Tokenizer::Token::Char('='))) {
-        nsAutoCString typeStr;
-        t.Claim(typeStr);
-        aOutType = ProxyConfig::ToProxyType(typeStr.get());
-        t.Record();
-      }
-
-      if (token.Equals(mozilla::Tokenizer::Token::Char('['))) {
-        parsingIPv6 = true;
-        continue;
-      }
-
-      if (!parsingIPv6 && token.Equals(mozilla::Tokenizer::Token::Char(':'))) {
-        // Port is starting. Claim the previous as host.
-        t.Claim(aOutHost);
-        t.Record();
-        parsingPort = true;
-        continue;
-      }
-
-      if (token.Equals(mozilla::Tokenizer::Token::Char(']'))) {
-        parsingIPv6 = false;
-        continue;
+      } else if (proxy.Find(kSocksPrefix) == 0) {
+        // SOCKS proxy.
+        socksProxy =
+            Substring(proxy, kSocksPrefix.Length());  // "socks=" length.
       }
     }
 
-    if (parsingPort) {
-      nsAutoCString portStr;
-      t.Claim(portStr);
-      nsresult rv = NS_OK;
-      aOutPort = portStr.ToInteger(&rv);
-      if (NS_FAILED(rv)) {
-        aOutPort = -1;
-      }
-    }
-  };
-
-  auto ruleHandler = [&](const nsACString& aRule, bool& aContinue) {
-    const nsCString proxy(aRule);
-    aContinue = true;
-    ProxyServer::ProxyType type;
-    nsCString host;
-    int32_t port = -1;
-    processProxyStr(proxy, type, host, port);
-    if (!host.IsEmpty()) {
-      ProxyServer server(type, host, port);
-      config.Rules().mProxyServers[server.Type()] = std::move(server);
-    }
-  };
-
-  // Note that reading the proxy settings from registry directly is not
-  // documented by Microsoft, so doing it could be risky. We still use system
-  // API to read proxy settings for safe.
-  ReadProxyRules(INTERNET_PER_CONN_PROXY_SERVER, flagHandler, ruleHandler);
-
-  auto bypassRuleHandler = [&](const nsACString& aOverrideRule,
-                               bool& aContinue) {
-    aContinue = true;
-    config.ByPassRules().mExceptions.AppendElement(aOverrideRule);
-  };
-
-  auto dummyHandler = [](uint32_t aFlags) { return true; };
-  ReadProxyRules(INTERNET_PER_CONN_PROXY_BYPASS, dummyHandler,
-                 bypassRuleHandler);
-
-  {
-    mozilla::MutexAutoLock lock(mLock);
-    mConfig = std::move(config);
-  }
-}
-
-NS_IMETHODIMP
-WindowsSystemProxySettingsAsync::GetMainThreadOnly(bool* aMainThreadOnly) {
-  return nsWindowsSystemProxySettings::GetMainThreadOnly(aMainThreadOnly);
-}
-
-NS_IMETHODIMP WindowsSystemProxySettingsAsync::GetPACURI(nsACString& aResult) {
-  AUTO_PROFILER_LABEL("WindowsSystemProxySettingsAsync::GetPACURI", OTHER);
-  mozilla::MutexAutoLock lock(mLock);
-  aResult.Assign(mConfig.PACUrl());
-  return NS_OK;
-}
-
-NS_IMETHODIMP WindowsSystemProxySettingsAsync::GetProxyForURI(
-    const nsACString& aSpec, const nsACString& aScheme, const nsACString& aHost,
-    const int32_t aPort, nsACString& aResult) {
-  // Fallback to nsWindowsSystemProxySettings::GetProxyForURI if we failed to
-  // monitor the change of registry keys.
-  if (!mInited) {
-    return nsWindowsSystemProxySettings::GetProxyForURI(aSpec, aScheme, aHost,
-                                                        aPort, aResult);
+    if (delimiter == end) break;
+    start = ++delimiter;
   }
 
-  mozilla::MutexAutoLock lock(mLock);
+  if (!specificProxy.IsEmpty())
+    SetProxyResult("PROXY", specificProxy,
+                   aResult);  // Protocol-specific proxy.
+  else if (!defaultProxy.IsEmpty())
+    SetProxyResult("PROXY", defaultProxy, aResult);  // Default proxy.
+  else if (!socksProxy.IsEmpty())
+    SetProxyResult("SOCKS", socksProxy, aResult);  // SOCKS proxy.
+  else
+    SetProxyResultDirect(aResult);  // Direct connection.
 
-  for (const auto& bypassRule : mConfig.ByPassRules().mExceptions) {
-    if (MatchOverrideInternal(aHost, bypassRule)) {
-      ProxyConfig::SetProxyResultDirect(aResult);
-      return NS_OK;
-    }
-  }
-
-  mConfig.GetProxyString(aScheme, aResult);
   return NS_OK;
 }
 
 NS_IMPL_COMPONENT_FACTORY(nsWindowsSystemProxySettings) {
-  auto settings =
-      mozilla::StaticPrefs::network_proxy_detect_system_proxy_changes()
-          ? mozilla::MakeRefPtr<WindowsSystemProxySettingsAsync>()
-          : mozilla::MakeRefPtr<nsWindowsSystemProxySettings>();
-  if (NS_SUCCEEDED(settings->Init())) {
-    return settings.forget().downcast<nsISupports>();
-  }
-  return nullptr;
+  return mozilla::MakeAndAddRef<nsWindowsSystemProxySettings>()
+      .downcast<nsISupports>();
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list