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
+++ b/mercurial/cmdutil.py
@@ -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
+++ b/mercurial/templater.py
@@ -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
+++ b/mercurial/templates/paper/shortlog.tmpl
@@ -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
+++ b/tests/test-command-template.t
@@ -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<