Merge pull request #2194 from leonelcamara/patch-31
Fixes #2182 possibly Fixes #2190
This commit is contained in:
@@ -119,13 +119,43 @@ def xml(value, encoding='UTF-8', key='document', quote=True):
|
||||
return ('<?xml version="1.0" encoding="%s"?>' % encoding) + str(xml_rec(value, key, quote))
|
||||
|
||||
|
||||
def json(value, default=custom_json, indent=None, sort_keys=False):
|
||||
value = json_parser.dumps(value, default=default, sort_keys=sort_keys, indent=indent)
|
||||
# replace JavaScript incompatible spacing
|
||||
# http://timelessrepo.com/json-isnt-a-javascript-subset
|
||||
# PY3 FIXME
|
||||
# return value.replace(ur'\u2028', '\\u2028').replace(ur'\2029', '\\u2029')
|
||||
return value
|
||||
class JSONEncoderForHTML(json_parser.JSONEncoder):
|
||||
"""An encoder that produces JSON safe to embed in HTML.
|
||||
To embed JSON content in, say, a script tag on a web page, the
|
||||
characters &, < and > should be escaped. They cannot be escaped
|
||||
with the usual entities (e.g. &) because they are not expanded
|
||||
within <script> tags.
|
||||
This class also escapes the line separator and paragraph separator
|
||||
characters U+2028 and U+2029, irrespective of the ensure_ascii setting,
|
||||
as these characters are not valid in JavaScript strings (see
|
||||
http://timelessrepo.com/json-isnt-a-javascript-subset).
|
||||
"""
|
||||
|
||||
def encode(self, o):
|
||||
# Override JSONEncoder.encode because it has hacks for
|
||||
# performance that make things more complicated.
|
||||
chunks = self.iterencode(o, True)
|
||||
if self.ensure_ascii:
|
||||
return ''.join(chunks)
|
||||
else:
|
||||
return u''.join(chunks)
|
||||
|
||||
def iterencode(self, o, _one_shot=False):
|
||||
chunks = super(JSONEncoderForHTML, self).iterencode(o, _one_shot)
|
||||
for chunk in chunks:
|
||||
chunk = chunk.replace('&', '\\u0026')
|
||||
chunk = chunk.replace('<', '\\u003c')
|
||||
chunk = chunk.replace('>', '\\u003e')
|
||||
|
||||
if not self.ensure_ascii:
|
||||
chunk = chunk.replace(u'\u2028', '\\u2028')
|
||||
chunk = chunk.replace(u'\u2029', '\\u2029')
|
||||
|
||||
yield chunk
|
||||
|
||||
|
||||
def json(value, default=custom_json, indent=None, sort_keys=False, cls=JSONEncoderForHTML):
|
||||
return json_parser.dumps(value, default=default, cls=cls, sort_keys=sort_keys, indent=indent)
|
||||
|
||||
def csv(value):
|
||||
return ''
|
||||
|
||||
@@ -50,7 +50,8 @@ class TestSerializers(unittest.TestCase):
|
||||
lazy_translation = T('abc')
|
||||
self.assertEqual(json(lazy_translation), u'"abc"')
|
||||
# html helpers are xml()ed before too
|
||||
self.assertEqual(json(SPAN('abc')), u'"<span>abc</span>"')
|
||||
self.assertEqual(json(SPAN('abc'), cls=None), u'"<span>abc</span>"')
|
||||
self.assertEqual(json(SPAN('abc')), u'"\\u003cspan\\u003eabc\\u003c/span\\u003e"')
|
||||
# unicode keys make a difference with loads_json
|
||||
base = {u'è': 1, 'b': 2}
|
||||
base_enc = json(base)
|
||||
|
||||
Reference in New Issue
Block a user