Skip to content

Commit d71bd57

Browse files
steffanncarltongibson
authored andcommitted
SchemaJSRenderer renders invalid Javascript (#5607)
* SchemaJSRenderer renders invalid Javascript Under Py3 the base64.b64encode() method returns a binary object, which gets rendered as `b'...'` in schema.js. This results in the output becoming: var coreJSON = window.atob('b'eyJf...''); which is invalid Javascript. Because base64 only uses ASCII characters it is safe to decode('ascii') it. Under Py2 this will result in a unicode object, which is fine. Under Py3 it results in a string, which is also fine. This solves the problem and results in a working schema.js output. * Add regression test for #5608 * Add regression test for #5608 * Apparently the linter on Travis wants the imports in a different order than on my box...
1 parent 1a667f4 commit d71bd57

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

rest_framework/renderers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ class SchemaJSRenderer(BaseRenderer):
852852

853853
def render(self, data, accepted_media_type=None, renderer_context=None):
854854
codec = coreapi.codecs.CoreJSONCodec()
855-
schema = base64.b64encode(codec.encode(data))
855+
schema = base64.b64encode(codec.encode(data)).decode('ascii')
856856

857857
template = loader.get_template(self.template)
858858
context = {'schema': mark_safe(schema)}

tests/test_renderers.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from rest_framework import permissions, serializers, status
1919
from rest_framework.renderers import (
2020
AdminRenderer, BaseRenderer, BrowsableAPIRenderer, DocumentationRenderer,
21-
HTMLFormRenderer, JSONRenderer, StaticHTMLRenderer
21+
HTMLFormRenderer, JSONRenderer, SchemaJSRenderer, StaticHTMLRenderer
2222
)
2323
from rest_framework.request import Request
2424
from rest_framework.response import Response
@@ -736,3 +736,20 @@ def test_document_with_link_named_data(self):
736736

737737
html = renderer.render(document, accepted_media_type="text/html", renderer_context={"request": request})
738738
assert '<h1>Data Endpoint API</h1>' in html
739+
740+
741+
class TestSchemaJSRenderer(TestCase):
742+
743+
def test_schemajs_output(self):
744+
"""
745+
Test output of the SchemaJS renderer as per #5608. Django 2.0 on Py3 prints binary data as b'xyz' in templates,
746+
and the base64 encoding used by SchemaJSRenderer outputs base64 as binary. Test fix.
747+
"""
748+
factory = APIRequestFactory()
749+
request = factory.get('/')
750+
751+
renderer = SchemaJSRenderer()
752+
753+
output = renderer.render('data', renderer_context={"request": request})
754+
assert "'ImRhdGEi'" in output
755+
assert "'b'ImRhdGEi''" not in output

0 commit comments

Comments
 (0)