[PATCH STABLE] templater: do not preprocess template string in "if" expression (issue4714)

Yuya Nishihara yuya at tcha.org
Mon Jun 8 13:09:42 UTC 2015


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1433754862 -32400
#      Mon Jun 08 18:14:22 2015 +0900
# Branch stable
# Node ID b19842c5083d6af4056c1f3778b699c07de74e95
# Parent  bd4bcfa48c9e1a1797248725078f040e4841b45a
templater: do not preprocess template string in "if" expression (issue4714)

The problem was spotted at 5ab28a2e9962, that says "this patch invokes it
with "strtoken='rawstring'" in "_evalifliteral()", because "t" is the result
of "arg" evaluation and it should be "string-escape"-ed if "arg" is "string"
expression." This workaround is no longer valid since 890845af1ac2 introduced
strict parsing of '\{'.

Instead, we should interpret bare token as "string" or "rawstring" template.
This is what buildmap() does at parsing phase.

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -326,12 +326,13 @@ def get(context, mapping, args):
     yield dictarg.get(key)
 
 def _evalifliteral(arg, context, mapping):
-    t = stringify(arg[0](context, mapping, arg[1]))
-    if arg[0] == runstring or arg[0] == runrawstring:
+    # get back to token tag to reinterpret string as template
+    strtoken = {runstring: 'string', runrawstring: 'rawstring'}.get(arg[0])
+    if strtoken:
         yield runtemplate(context, mapping,
-                          compiletemplate(t, context, strtoken='rawstring'))
+                          compiletemplate(arg[1], context, strtoken))
     else:
-        yield t
+        yield stringify(arg[0](context, mapping, arg[1]))
 
 def if_(context, mapping, args):
     """:if(expr, then[, else]): Conditionally execute based on the result of
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -2284,6 +2284,17 @@ Test leading backslashes:
   \{rev} \{file} \\\head1
   $ cd ..
 
+Test leading backslashes in "if" expression (issue4714):
+
+  $ cd latesttag
+  $ hg log -r 2 -T '{if("1", "\{rev}")} {if("1", r"\{rev}")}\n'
+  {rev} \2
+  $ hg log -r 2 -T '{if("1", "\\{rev}")} {if("1", r"\\{rev}")}\n'
+  \2 \\2
+  $ hg log -r 2 -T '{if("1", "\\\{rev}")} {if("1", r"\\\{rev}")}\n'
+  \{rev} \\\2
+  $ cd ..
+
 "string-escape"-ed "\x5c\x786e" becomes r"\x6e" (once) or r"n" (twice)
 
   $ hg log -R a -r 0 --template '{if("1", "\x5c\x786e", "NG")}\n'


More information about the Mercurial-devel mailing list