templater: fix escaping in nested string literals (issue4102) stable
authorMatt Mackall <mpm@selenic.com>
Mon, 18 Nov 2013 14:02:26 -0500
branchstable
changeset 20066 64b4f0cd7336
parent 20064 99c4b8f79324
child 20067 3d8bfe2ecf6d
templater: fix escaping in nested string literals (issue4102) Before the templater got extended for nested expressions, it made sense to decode string escapes across the whole string. Now we do it on a piece by piece basis.
mercurial/cmdutil.py
mercurial/templater.py
mercurial/templates/paper/shortlog.tmpl
tests/test-command-template.t
--- a/mercurial/cmdutil.py	Thu Nov 07 20:36:26 2013 -0800
+++ b/mercurial/cmdutil.py	Mon Nov 18 14:02:26 2013 -0500
@@ -940,9 +940,7 @@
 
     tmpl = opts.get('template')
     style = None
-    if tmpl:
-        tmpl = templater.parsestring(tmpl, quoted=False)
-    else:
+    if not tmpl:
         style = opts.get('style')
 
     # ui settings
--- a/mercurial/templater.py	Thu Nov 07 20:36:26 2013 -0800
+++ b/mercurial/templater.py	Mon Nov 18 14:02:26 2013 -0500
@@ -52,7 +52,7 @@
                     if not decode:
                         yield ('string', program[s:pos].replace('\\', r'\\'), s)
                         break
-                    yield ('string', program[s:pos].decode('string-escape'), s)
+                    yield ('string', program[s:pos], s)
                     break
                 pos += 1
             else:
@@ -80,19 +80,19 @@
     parsed = []
     pos, stop = 0, len(tmpl)
     p = parser.parser(tokenizer, elements)
-
     while pos < stop:
         n = tmpl.find('{', pos)
         if n < 0:
-            parsed.append(("string", tmpl[pos:]))
+            parsed.append(("string", tmpl[pos:].decode("string-escape")))
             break
         if n > 0 and tmpl[n - 1] == '\\':
             # escaped
-            parsed.append(("string", tmpl[pos:n - 1] + "{"))
+            parsed.append(("string",
+                           (tmpl[pos:n - 1] + "{").decode("string-escape")))
             pos = n + 1
             continue
         if n > pos:
-            parsed.append(("string", tmpl[pos:n]))
+            parsed.append(("string", tmpl[pos:n].decode("string-escape")))
 
         pd = [tmpl, n + 1, stop]
         parseres, pos = p.parse(pd)
--- a/mercurial/templates/paper/shortlog.tmpl	Thu Nov 07 20:36:26 2013 -0800
+++ b/mercurial/templates/paper/shortlog.tmpl	Mon Nov 18 14:02:26 2013 -0500
@@ -80,8 +80,8 @@
                 return m ? m[1] : null;
             },
             '.bigtable > tbody:nth-of-type(2)',
-            '<tr class="%class%">\
-            <td colspan="3" style="text-align: center;">%text%</td>\
+            '<tr class="%class%">\\
+            <td colspan="3" style="text-align: center;">%text%</td>\\
             </tr>'
     );
 </script>
--- a/tests/test-command-template.t	Thu Nov 07 20:36:26 2013 -0800
+++ b/tests/test-command-template.t	Mon Nov 18 14:02:26 2013 -0500
@@ -1586,3 +1586,11 @@
   h1c
   b
   a
+
+Test string escaping:
+
+  $ hg log -R latesttag -r 0 --template '>\n<>\\n<{if(rev, "[>\n<>\\n<]")}>\n<>\\n<\n'
+  >
+  <>\n<[>
+  <>\n<]>
+  <>\n<