Patchwork D1079: hgweb: rewrite most obviously-native-strings to be native strings

login
register
mail settings
Submitter phabricator
Date Oct. 14, 2017, 8:16 p.m.
Message ID <differential-rev-PHID-DREV-knkflxc2653mjmaje7x4-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/24910/
State Superseded
Headers show

Comments

phabricator - Oct. 14, 2017, 8:16 p.m.
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This clearly won't be everything, but it unblocks a fair amount of
  stuff here.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1079

AFFECTED FILES
  mercurial/hgweb/__init__.py
  mercurial/hgweb/hgweb_mod.py

CHANGE DETAILS




To: durin42, #hg-reviewers
Cc: mercurial-devel
phabricator - Oct. 14, 2017, 8:56 p.m.
indygreg added subscribers: yuja, indygreg.
indygreg accepted this revision.
indygreg added a comment.
This revision is now accepted and ready to land.


  There might be some subtle issues with encoding for e.g. form values (if we don't have a test for e.g. a Unicode value in a revset search, we should add one). But I'm sure @yuja will flag those if they exist. I'm happy to queue until then.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1079

To: durin42, #hg-reviewers, indygreg
Cc: indygreg, yuja, mercurial-devel
phabricator - Oct. 15, 2017, 3:16 a.m.
yuja added a comment.


  Please don't count on me that I can catch unicode issues around
  Python URL/HTTP libraries. I hate Python 3 because of the unicode
  mess, so I don't write it for any projects other than Mercurial.
  
  Maybe we'll need a clear boundary between Mercurial and Python
  types to determine which value should be bytes/unicode.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D1079

To: durin42, #hg-reviewers, indygreg
Cc: indygreg, yuja, mercurial-devel

Patch

diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -165,9 +165,9 @@ 
             proto = 'http'
             default_port = '80'
 
-        port = req.env['SERVER_PORT']
-        port = port != default_port and (':' + port) or ''
-        urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
+        port = req.env[r'SERVER_PORT']
+        port = port != default_port and (r':' + port) or r''
+        urlbase = r'%s://%s%s' % (proto, req.env[r'SERVER_NAME'], port)
         logourl = self.config('web', 'logourl')
         logoimg = self.config('web', 'logoimg')
         staticurl = self.config('web', 'staticurl') or req.url + 'static/'
@@ -341,27 +341,27 @@ 
         # work with CGI variables to create coherent structure
         # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
 
-        req.url = req.env['SCRIPT_NAME']
+        req.url = req.env[r'SCRIPT_NAME']
         if not req.url.endswith('/'):
             req.url += '/'
         if req.env.get('REPO_NAME'):
-            req.url += req.env['REPO_NAME'] + '/'
+            req.url += req.env[r'REPO_NAME'] + r'/'
 
-        if 'PATH_INFO' in req.env:
-            parts = req.env['PATH_INFO'].strip('/').split('/')
-            repo_parts = req.env.get('REPO_NAME', '').split('/')
+        if r'PATH_INFO' in req.env:
+            parts = req.env[r'PATH_INFO'].strip('/').split('/')
+            repo_parts = req.env.get(r'REPO_NAME', r'').split(r'/')
             if parts[:len(repo_parts)] == repo_parts:
                 parts = parts[len(repo_parts):]
             query = '/'.join(parts)
         else:
-            query = req.env['QUERY_STRING'].partition('&')[0]
-            query = query.partition(';')[0]
+            query = req.env[r'QUERY_STRING'].partition(r'&')[0]
+            query = query.partition(r';')[0]
 
         # process this if it's a protocol request
         # protocol bits don't need to create any URLs
         # and the clients always use the old URL structure
 
-        cmd = req.form.get('cmd', [''])[0]
+        cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0])
         if protocol.iscmd(cmd):
             try:
                 if query:
@@ -386,17 +386,16 @@ 
         # translate user-visible url structure to internal structure
 
         args = query.split('/', 2)
-        if 'cmd' not in req.form and args and args[0]:
-
+        if r'cmd' not in req.form and args and args[0]:
             cmd = args.pop(0)
             style = cmd.rfind('-')
             if style != -1:
                 req.form['style'] = [cmd[:style]]
                 cmd = cmd[style + 1:]
 
             # avoid accepting e.g. style parameter as command
             if util.safehasattr(webcommands, cmd):
-                req.form['cmd'] = [cmd]
+                req.form[r'cmd'] = [cmd]
 
             if cmd == 'static':
                 req.form['file'] = ['/'.join(args)]
@@ -431,17 +430,17 @@ 
                 self.check_perm(rctx, req, None)
 
             if cmd == '':
-                req.form['cmd'] = [tmpl.cache['default']]
-                cmd = req.form['cmd'][0]
+                req.form[r'cmd'] = [tmpl.cache['default']]
+                cmd = req.form[r'cmd'][0]
 
             # Don't enable caching if using a CSP nonce because then it wouldn't
             # be a nonce.
             if rctx.configbool('web', 'cache') and not rctx.nonce:
                 caching(self, req) # sets ETag header or raises NOT_MODIFIED
             if cmd not in webcommands.__all__:
                 msg = 'no such method: %s' % cmd
                 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
-            elif cmd == 'file' and 'raw' in req.form.get('style', []):
+            elif cmd == 'file' and r'raw' in req.form.get(r'style', []):
                 rctx.ctype = ctype
                 content = webcommands.rawfile(rctx, req, tmpl)
             else:
diff --git a/mercurial/hgweb/__init__.py b/mercurial/hgweb/__init__.py
--- a/mercurial/hgweb/__init__.py
+++ b/mercurial/hgweb/__init__.py
@@ -14,6 +14,7 @@ 
 
 from .. import (
     error,
+    pycompat,
     util,
 )
 
@@ -61,25 +62,26 @@ 
         else:
             prefix = ''
 
-        port = ':%d' % self.httpd.port
-        if port == ':80':
-            port = ''
+        port = r':%d' % self.httpd.port
+        if port == r':80':
+            port = r''
 
         bindaddr = self.httpd.addr
-        if bindaddr == '0.0.0.0':
-            bindaddr = '*'
-        elif ':' in bindaddr: # IPv6
-            bindaddr = '[%s]' % bindaddr
+        if bindaddr == r'0.0.0.0':
+            bindaddr = r'*'
+        elif r':' in bindaddr: # IPv6
+            bindaddr = r'[%s]' % bindaddr
 
         fqaddr = self.httpd.fqaddr
-        if ':' in fqaddr:
-            fqaddr = '[%s]' % fqaddr
+        if r':' in fqaddr:
+            fqaddr = r'[%s]' % fqaddr
         if self.opts['port']:
             write = self.ui.status
         else:
             write = self.ui.write
         write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
-              (fqaddr, port, prefix, bindaddr, self.httpd.port))
+              (pycompat.sysbytes(fqaddr), pycompat.sysbytes(port),
+               prefix, pycompat.sysbytes(bindaddr), self.httpd.port))
         self.ui.flush()  # avoid buffering of status message
 
     def run(self):