@@ -68,24 +68,42 @@ def is_wsl():
6868
6969def _browse (auth_uri , browser_name = None ): # throws ImportError, webbrowser.Error
7070 """Browse uri with named browser. Default browser is customizable by $BROWSER"""
71+ try :
72+ parsed_uri = urlparse (auth_uri )
73+ if parsed_uri .scheme not in ("http" , "https" ):
74+ logger .warning ("Invalid URI scheme for browser: %s" , parsed_uri .scheme )
75+ return False
76+ except ValueError :
77+ logger .warning ("Invalid URI: %s" , auth_uri )
78+ return False
79+ if any (c in auth_uri for c in "\n \r \t " ):
80+ logger .warning ("Invalid characters in URI" )
81+ return False
82+
7183 import webbrowser # Lazy import. Some distro may not have this.
7284 if browser_name :
7385 browser_opened = webbrowser .get (browser_name ).open (auth_uri )
7486 else :
7587 # This one can survive BROWSER=nonexist, while get(None).open(...) can not
7688 browser_opened = webbrowser .open (auth_uri )
7789
78- # In WSL which doesn't have www-browser, try launching browser with PowerShell
90+ # In WSL which doesn't have www-browser, try launching browser with explorer.exe
7991 if not browser_opened and is_wsl ():
80- try :
81- import subprocess
82- # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
83- # Ampersand (&) should be quoted
84- exit_code = subprocess .call (
85- ['powershell.exe' , '-NoProfile' , '-Command' , 'Start-Process "{}"' .format (auth_uri )])
92+ import subprocess
93+ try : # Try wslview first, which is the recommended way on WSL
94+ # https://github.com/wslutilities/wslu
95+ exit_code = subprocess .call (['wslview' , auth_uri ])
8696 browser_opened = exit_code == 0
87- except FileNotFoundError : # WSL might be too old
97+ except FileNotFoundError : # wslview might not be installed
8898 pass
99+ if not browser_opened :
100+ try :
101+ # Fallback to explorer.exe as recommended for WSL
102+ # Note: explorer.exe returns 1 on success in some WSL environments
103+ exit_code = subprocess .call (['explorer.exe' , auth_uri ])
104+ browser_opened = exit_code in (0 , 1 )
105+ except FileNotFoundError :
106+ pass
89107 return browser_opened
90108
91109
@@ -102,12 +120,10 @@ def _is_html(text):
102120def _escape (key_value_pairs ):
103121 return {k : escape (v ) for k , v in key_value_pairs .items ()}
104122
105-
106123def _printify (text ):
107124 # If an https request is sent to an http server, the text needs to be repr-ed
108125 return repr (text ) if isinstance (text , str ) and not text .isprintable () else text
109126
110-
111127class _AuthCodeHandler (BaseHTTPRequestHandler ):
112128 def do_GET (self ):
113129 qs = parse_qs (urlparse (self .path ).query )
0 commit comments