# HG changeset patch # User Matt Mackall # Date 2016-07-18 21:25:35 # Node ID 67b180c0e2634971d8f7e0e31b00dc4bdc7768cc # Parent b33c0c38d68fd8e14e6223a1eb46aade2745f74c extdiff: escape path for docstring (issue5301) The existing code (a) assumed path would be specified in encoding.encoding and (b) assumed unicode() objects wouldn't cause other parts of Mercurial to blow up. Both are dangerous assumptions. Since we don't know the encoding of path and can't pass non-ASCII through docstrings, just escape the path and drop the early _(). Will have to suffice until we can teach docstrings to handle UTF-8b escaping. This has the side-effect that the line containing the path is now variable by the time it reaches _() and thus can't be translated. diff --git a/hgext/extdiff.py b/hgext/extdiff.py --- a/hgext/extdiff.py +++ b/hgext/extdiff.py @@ -76,7 +76,6 @@ from mercurial import ( archival, cmdutil, commands, - encoding, error, filemerge, scmutil, @@ -365,7 +364,10 @@ def uisetup(ui): if options: options = ' ' + options return dodiff(ui, repo, cmdline + options, pats, opts) - doc = _('''\ + # We can't pass non-ASCII through docstrings (and path is + # in an unknown encoding anyway) + docpath = path.encode("string-escape") + mydiff.__doc__ = '''\ use %(path)s to diff repository (or selected files) Show differences between revisions for the specified files, using @@ -376,15 +378,7 @@ use %(path)s to diff repository (or sele that revision is compared to the working directory, and, when no revisions are specified, the working directory files are compared to its parent.\ -''') % {'path': util.uirepr(path)} - - # We must translate the docstring right away since it is - # used as a format string. The string will unfortunately - # be translated again in commands.helpcmd and this will - # fail when the docstring contains non-ASCII characters. - # Decoding the string to a Unicode string here (using the - # right encoding) prevents that. - mydiff.__doc__ = doc.decode(encoding.encoding) +''' % {'path': util.uirepr(docpath)} return mydiff command(cmd, extdiffopts[:], _('hg %s [OPTION]... [FILE]...') % cmd, inferrepo=True)(save(cmdline)) diff --git a/tests/test-extdiff.t b/tests/test-extdiff.t --- a/tests/test-extdiff.t +++ b/tests/test-extdiff.t @@ -389,3 +389,23 @@ Test symlinks handling (issue1909) $ cd .. #endif + +Test handling of non-ASCII paths in generated docstrings (issue5301) + + >>> open("u", "w").write("\xa5\xa5") + $ U=`cat u` + + $ HGPLAIN=1 hg --config hgext.extdiff= --config extdiff.cmd.td=hi help -k xyzzy + abort: no matches + (try "hg help" for a list of topics) + [255] + + $ HGPLAIN=1 hg --config hgext.extdiff= --config extdiff.cmd.td=hi help td > /dev/null + + $ LC_MESSAGES=ja_JP.UTF-8 hg --config hgext.extdiff= --config extdiff.cmd.td=$U help -k xyzzy + abort: no matches + (try "hg help" for a list of topics) + [255] + + $ LC_MESSAGES=ja_JP.UTF-8 hg --config hgext.extdiff= --config extdiff.cmd.td=$U help td | grep "^use" + use '\xa5\xa5' to diff repository (or selected files)