Skip to content

Commit de4ef6e

Browse files
committed
Merge pull request #2195 from tomchristie/tomchristie-escape-u2028-u2029-json
Escape \u2028 and \u2029 in JSON output.
2 parents e2b3908 + 23fa6e5 commit de4ef6e

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

rest_framework/renderers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
102102
# and may (or may not) be unicode.
103103
# On python 3.x json.dumps() returns unicode strings.
104104
if isinstance(ret, six.text_type):
105+
# We always fully escape \u2028 and \u2029 to ensure we output JSON
106+
# that is a strict javascript subset. If bytes were returned
107+
# by json.dumps() then we don't have these characters in any case.
108+
# See: http://timelessrepo.com/json-isnt-a-javascript-subset
109+
ret = ret.replace('\u2028', '\\u2028').replace('\u2029', '\\u2029')
105110
return bytes(ret.encode('utf-8'))
106111
return ret
107112

tests/test_renderers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,15 @@ def test_proper_encoding(self):
384384
content = renderer.render(obj, 'application/json')
385385
self.assertEqual(content, '{"countries":["United Kingdom","France","España"]}'.encode('utf-8'))
386386

387+
def test_u2028_u2029(self):
388+
# The \u2028 and \u2029 characters should be escaped,
389+
# even when the non-escaping unicode representation is used.
390+
# Regression test for #2169
391+
obj = {'should_escape': '\u2028\u2029'}
392+
renderer = JSONRenderer()
393+
content = renderer.render(obj, 'application/json')
394+
self.assertEqual(content, '{"should_escape":"\\u2028\\u2029"}'.encode('utf-8'))
395+
387396

388397
class AsciiJSONRendererTests(TestCase):
389398
"""

0 commit comments

Comments
 (0)