changeset 20066:64b4f0cd7336 stable

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.
author Matt Mackall <mpm@selenic.com>
date Mon, 18 Nov 2013 14:02:26 -0500
parents 99c4b8f79324
children 3d8bfe2ecf6d
files mercurial/cmdutil.py mercurial/templater.py mercurial/templates/paper/shortlog.tmpl tests/test-command-template.t
diffstat 4 files changed, 16 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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<