changeset 34837:4fdc4adbc838

templatefilters: defend against evil unicode strs in json filter We only want to do I/O in terms of bytes, so lets explode early instead of recursing forever. Differential Revision: https://phab.mercurial-scm.org/D1136
author Augie Fackler <augie@google.com>
date Mon, 16 Oct 2017 22:44:43 -0400
parents 537de0b14030
children d3ea6a1c798f
files mercurial/templatefilters.py
diffstat 1 files changed, 8 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/templatefilters.py	Wed Sep 20 19:38:06 2017 +0200
+++ b/mercurial/templatefilters.py	Mon Oct 16 22:44:43 2017 -0400
@@ -13,6 +13,7 @@
 
 from . import (
     encoding,
+    error,
     hbisect,
     node,
     pycompat,
@@ -233,6 +234,13 @@
         return pycompat.bytestr(obj)
     elif isinstance(obj, bytes):
         return '"%s"' % encoding.jsonescape(obj, paranoid=paranoid)
+    elif isinstance(obj, str):
+        # This branch is unreachable on Python 2, because bytes == str
+        # and we'll return in the next-earlier block in the elif
+        # ladder. On Python 3, this helps us catch bugs before they
+        # hurt someone.
+        raise error.ProgrammingError(
+            'Mercurial only does output with bytes on Python 3: %r' % obj)
     elif util.safehasattr(obj, 'keys'):
         out = ['"%s": %s' % (encoding.jsonescape(k, paranoid=paranoid),
                              json(v, paranoid))