Patchwork [1,of,2] alias: reject non-ascii characters in user help/doc strings

login
register
mail settings
Submitter Yuya Nishihara
Date March 28, 2018, 1:18 p.m.
Message ID <34381b51be48dad3a7b5.1522243089@mimosa>
Download mbox | patch
Permalink /patch/29919/
State Accepted
Headers show

Comments

Yuya Nishihara - March 28, 2018, 1:18 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1522242285 -32400
#      Wed Mar 28 22:04:45 2018 +0900
# Node ID 34381b51be48dad3a7b53c663aa5f38e8f5913fa
# Parent  4d63f3bc1e1ad3bd145af95d6eab8104684686ca
alias: reject non-ascii characters in user help/doc strings

Since command doc/help texts are passed to i18n.gettext(), they must be
ASCII. Otherwise, UnicodeError would be raised.
Pulkit Goyal - March 28, 2018, 6:34 p.m.
On Wed, Mar 28, 2018 at 6:48 PM, Yuya Nishihara <yuya@tcha.org> wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1522242285 -32400
> #      Wed Mar 28 22:04:45 2018 +0900
> # Node ID 34381b51be48dad3a7b53c663aa5f38e8f5913fa
> # Parent  4d63f3bc1e1ad3bd145af95d6eab8104684686ca
> alias: reject non-ascii characters in user help/doc strings
>
> Since command doc/help texts are passed to i18n.gettext(), they must be
> ASCII. Otherwise, UnicodeError would be raised.

Queued the series. Many thanks!

Patch

diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -534,12 +534,24 @@  class cmdalias(object):
                              % (self.name, cmd))
 
     def _populatehelp(self, ui, name, cmd, fn, defaulthelp=None):
-        self.help = ui.config('alias', '%s:help' % name, defaulthelp or '')
+        # confine strings to be passed to i18n.gettext()
+        cfg = {}
+        for k in ('doc', 'help'):
+            v = ui.config('alias', '%s:%s' % (name, k), None)
+            if v is None:
+                continue
+            if not encoding.isasciistr(v):
+                self.badalias = (_("non-ASCII character in alias definition "
+                                   "'%s:%s'") % (name, k))
+                return
+            cfg[k] = v
+
+        self.help = cfg.get('help', defaulthelp or '')
         if self.help and self.help.startswith("hg " + cmd):
             # drop prefix in old-style help lines so hg shows the alias
             self.help = self.help[4 + len(cmd):]
 
-        self.__doc__ = ui.config('alias', '%s:doc' % name, fn.__doc__)
+        self.__doc__ = cfg.get('doc', fn.__doc__)
 
     @property
     def args(self):
diff --git a/tests/test-alias.t b/tests/test-alias.t
--- a/tests/test-alias.t
+++ b/tests/test-alias.t
@@ -616,6 +616,25 @@  help for a shell alias
   
   (some details hidden, use --verbose to show complete help)
 
+invalid character in user-specified help
+
+  >>> with open('.hg/hgrc', 'ab') as f:
+  ...     f.write(b'[alias]\n'
+  ...             b'invaliddoc = log\n'
+  ...             b'invaliddoc:doc = \xc0\n'
+  ...             b'invalidhelp = log\n'
+  ...             b'invalidhelp:help = \xc0\n') and None
+  $ hg help invaliddoc
+  non-ASCII character in alias definition 'invaliddoc:doc'
+  $ hg help invalidhelp
+  non-ASCII character in alias definition 'invalidhelp:help'
+  $ hg invaliddoc
+  abort: non-ASCII character in alias definition 'invaliddoc:doc'
+  [255]
+  $ hg invalidhelp
+  abort: non-ASCII character in alias definition 'invalidhelp:help'
+  [255]
+
 invalid arguments
 
   $ hg rt foo