summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pyramid/renderers.py9
-rw-r--r--pyramid/tests/test_renderers.py8
2 files changed, 17 insertions, 0 deletions
diff --git a/pyramid/renderers.py b/pyramid/renderers.py
index 088d451bb..e3d11515d 100644
--- a/pyramid/renderers.py
+++ b/pyramid/renderers.py
@@ -1,6 +1,7 @@
import contextlib
import json
import os
+import re
from zope.interface import (
implementer,
@@ -23,6 +24,8 @@ from pyramid.decorator import reify
from pyramid.events import BeforeRender
+from pyramid.httpexceptions import HTTPBadRequest
+
from pyramid.path import caller_package
from pyramid.response import _get_response_factory
@@ -308,6 +311,8 @@ class JSON(object):
json_renderer_factory = JSON() # bw compat
+JSONP_VALID_CALLBACK = re.compile(r"^[a-zA-Z_$][0-9a-zA-Z_$]+$")
+
class JSONP(JSON):
""" `JSONP <http://en.wikipedia.org/wiki/JSONP>`_ renderer factory helper
which implements a hybrid json/jsonp renderer. JSONP is useful for
@@ -388,7 +393,11 @@ class JSONP(JSON):
body = val
if request is not None:
callback = request.GET.get(self.param_name)
+
if callback is not None:
+ if not JSONP_VALID_CALLBACK.match(callback):
+ raise HTTPBadRequest('Invalid JSONP callback function name.')
+
ct = 'application/javascript'
body = '%s(%s);' % (callback, val)
response = request.response
diff --git a/pyramid/tests/test_renderers.py b/pyramid/tests/test_renderers.py
index ed6344a40..f8b5bfca0 100644
--- a/pyramid/tests/test_renderers.py
+++ b/pyramid/tests/test_renderers.py
@@ -646,6 +646,14 @@ class TestJSONP(unittest.TestCase):
result = renderer({'a':'1'}, {})
self.assertEqual(result, '{"a": "1"}')
+ def test_render_to_jsonp_invalid_callback(self):
+ from pyramid.httpexceptions import HTTPBadRequest
+ renderer_factory = self._makeOne()
+ renderer = renderer_factory(None)
+ request = testing.DummyRequest()
+ request.GET['callback'] = '78mycallback'
+ self.assertRaises(HTTPBadRequest, renderer, {'a':'1'}, {'request':request})
+
class Dummy:
pass