Mercurial > hg
changeset 26215:72aad184f061
templater: create string unescape helper (issue4798)
This gives us a unified place to do error-handling of string-escaping
syntax errors
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Wed, 09 Sep 2015 14:43:45 -0700 |
parents | 46605888faf3 |
children | e86d12404d69 |
files | mercurial/templater.py tests/test-command-template.t |
diffstat | 2 files changed, 23 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/templater.py Sat Sep 05 16:50:35 2015 +0900 +++ b/mercurial/templater.py Wed Sep 09 14:43:45 2015 -0700 @@ -39,6 +39,13 @@ "end": (0, None, None, None, None), } +def _unescape(s): + try: + return s.decode("string_escape") + except ValueError as e: + # mangle Python's exception into our format + raise error.ParseError(str(e).lower()) + def tokenize(program, start, end): pos = start while pos < end: @@ -105,11 +112,8 @@ pos += 4 # skip over double escaped characters continue if program.startswith(quote, pos, end): - try: - # interpret as if it were a part of an outer string - data = program[s:pos].decode('string-escape') - except ValueError: # unbalanced escapes - raise error.ParseError(_("syntax error"), s) + # interpret as if it were a part of an outer string + data = _unescape(program[s:pos]) if token == 'template': data = _parsetemplate(data, 0, len(data))[0] yield (token, data, s) @@ -158,19 +162,18 @@ n = min((tmpl.find(c, pos, stop) for c in sepchars), key=lambda n: (n < 0, n)) if n < 0: - parsed.append(('string', tmpl[pos:stop].decode('string-escape'))) + parsed.append(('string', _unescape(tmpl[pos:stop]))) pos = stop break c = tmpl[n] bs = (n - pos) - len(tmpl[pos:n].rstrip('\\')) if bs % 2 == 1: # escaped (e.g. '\{', '\\\{', but not '\\{') - parsed.append(('string', - tmpl[pos:n - 1].decode('string-escape') + c)) + parsed.append(('string', _unescape(tmpl[pos:n - 1]) + c)) pos = n + 1 continue if n > pos: - parsed.append(('string', tmpl[pos:n].decode('string-escape'))) + parsed.append(('string', _unescape(tmpl[pos:n]))) if c == quote: return parsed, n + 1
--- a/tests/test-command-template.t Sat Sep 05 16:50:35 2015 +0900 +++ b/tests/test-command-template.t Wed Sep 09 14:43:45 2015 -0700 @@ -2936,10 +2936,10 @@ hg: parse error at 21: unterminated string [255] $ hg log -r 2 -T '{if(rev, \"\\"")}\n' - hg: parse error at 11: syntax error + hg: parse error: trailing \ in string [255] $ hg log -r 2 -T '{if(rev, r\"\\"")}\n' - hg: parse error at 12: syntax error + hg: parse error: trailing \ in string [255] $ cd .. @@ -3417,3 +3417,12 @@ $ hg log -T "{indent(date, ' ')}\n" -r 2:3 -R a 1200000.00 1300000.00 + +Test broken string escapes: + + $ hg log -T "bogus\\" -R a + hg: parse error: trailing \ in string + [255] + $ hg log -T "\\xy" -R a + hg: parse error: invalid \x escape + [255]