From c067672083124e6e841b9670e1bbb3039a74e814 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=8B=82=E7=94=B7=E9=A3=8E?= <CrazyBoyFeng@Live.com>
Date: Thu, 12 May 2022 02:17:17 +0800
Subject: [PATCH] bpo-42627: Fix incorrect parsing of Windows registry proxy
 settings (GH-26307) (cherry picked from commit
 b69297ea23c0ab9866ae8bd26a347a9b5df567a6)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: 狂男风 <CrazyBoyFeng@Live.com>
---
 Lib/urllib/request.py                         | 36 ++++++++++---------
 .../2021-05-22-07-58-59.bpo-42627.EejtD0.rst  |  1 +
 2 files changed, 21 insertions(+), 16 deletions(-)
 create mode 100644 Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst

diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py
index 84997f268c9304..6d580a434a7bea 100644
--- a/Lib/urllib/request.py
+++ b/Lib/urllib/request.py
@@ -2679,22 +2679,26 @@ def getproxies_registry():
                 # Returned as Unicode but problems if not converted to ASCII
                 proxyServer = str(winreg.QueryValueEx(internetSettings,
                                                        'ProxyServer')[0])
-                if '=' in proxyServer:
-                    # Per-protocol settings
-                    for p in proxyServer.split(';'):
-                        protocol, address = p.split('=', 1)
-                        # See if address has a type:// prefix
-                        if not re.match('(?:[^/:]+)://', address):
-                            address = '%s://%s' % (protocol, address)
-                        proxies[protocol] = address
-                else:
-                    # Use one setting for all protocols
-                    if proxyServer[:5] == 'http:':
-                        proxies['http'] = proxyServer
-                    else:
-                        proxies['http'] = 'http://%s' % proxyServer
-                        proxies['https'] = 'https://%s' % proxyServer
-                        proxies['ftp'] = 'ftp://%s' % proxyServer
+                if '=' not in proxyServer and ';' not in proxyServer:
+                    # Use one setting for all protocols.
+                    proxyServer = 'http={0};https={0};ftp={0}'.format(proxyServer)
+                for p in proxyServer.split(';'):
+                    protocol, address = p.split('=', 1)
+                    # See if address has a type:// prefix
+                    if not re.match('(?:[^/:]+)://', address):
+                        # Add type:// prefix to address without specifying type
+                        if protocol in ('http', 'https', 'ftp'):
+                            # The default proxy type of Windows is HTTP
+                            address = 'http://' + address
+                        elif protocol == 'socks':
+                            address = 'socks://' + address
+                    proxies[protocol] = address
+                # Use SOCKS proxy for HTTP(S) protocols
+                if proxies.get('socks'):
+                    # The default SOCKS proxy type of Windows is SOCKS4
+                    address = re.sub(r'^socks://', 'socks4://', proxies['socks'])
+                    proxies['http'] = proxies.get('http') or address
+                    proxies['https'] = proxies.get('https') or address
             internetSettings.Close()
         except (OSError, ValueError, TypeError):
             # Either registry key not found etc, or the value in an
diff --git a/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst b/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst
new file mode 100644
index 00000000000000..f165b9ced05d90
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-05-22-07-58-59.bpo-42627.EejtD0.rst
@@ -0,0 +1 @@
+Fix incorrect parsing of Windows registry proxy settings