Type check the empty string when creating repsonse

When creating a response we type check that the user has passed the
correct type to content and text, however we check this based on whether
the value is True and not whether it has been passed at all which means
that the empty string of the wrong type can incorrectly pass through
this check.

Fix this check to test the empty string.

Anyone relying on this passing will be caught with a more confusing
TypeError later and so this should be backwards compatible.

Change-Id: I826da9b7fd83bb88af50e4a96a5e6358ee35e4b2
Closes-Bug: #1647880
This commit is contained in:
Jamie Lennox 2016-12-07 11:10:14 +11:00
parent 95dffefe83
commit 86fb33d13d
3 changed files with 28 additions and 6 deletions

View File

@ -147,9 +147,9 @@ def create_response(request, **kwargs):
json = kwargs.pop('json', None)
encoding = None
if content and not isinstance(content, six.binary_type):
if content is not None and not isinstance(content, six.binary_type):
raise TypeError('Content should be binary data')
if text and not isinstance(text, six.string_types):
if text is not None and not isinstance(text, six.string_types):
raise TypeError('Text should be string data')
if json is not None:
@ -207,12 +207,12 @@ class _MatcherResponse(object):
content = self._params.get('content')
text = self._params.get('text')
if content and not (callable(content) or
isinstance(content, six.binary_type)):
if content is not None and not (callable(content) or
isinstance(content, six.binary_type)):
raise TypeError('Content should be a callback or binary data')
if text and not (callable(text) or
isinstance(text, six.string_types)):
if text is not None and not (callable(text) or
isinstance(text, six.string_types)):
raise TypeError('Text should be a callback or string data')
def get_response(self, request):

View File

@ -265,6 +265,13 @@ class SessionAdapterTests(base.TestCase):
self.url,
content=six.u('unicode'))
def test_dont_pass_empty_string_as_content(self):
self.assertRaises(TypeError,
self.adapter.register_uri,
'GET',
self.url,
content=six.u(''))
def test_dont_pass_bytes_as_text(self):
if six.PY2:
self.skipTest('Cannot enforce byte behaviour in PY2')
@ -275,6 +282,16 @@ class SessionAdapterTests(base.TestCase):
self.url,
text=six.b('bytes'))
def test_dont_pass_empty_string_as_text(self):
if six.PY2:
self.skipTest('Cannot enforce byte behaviour in PY2')
self.assertRaises(TypeError,
self.adapter.register_uri,
'GET',
self.url,
text=six.b(''))
def test_dont_pass_non_str_as_content(self):
self.assertRaises(TypeError,
self.adapter.register_uri,

View File

@ -46,9 +46,14 @@ class ResponseTests(base.TestCase):
self.assertRaises(TypeError, self.create_response, text=55)
self.assertRaises(TypeError, self.create_response, text={'a': 1})
# this only works on python 2 because bytes is a string
if six.PY3:
self.assertRaises(TypeError, self.create_response, text=six.b(''))
def test_text_type(self):
self.assertRaises(TypeError, self.create_response, content=six.u('t'))
self.assertRaises(TypeError, self.create_response, content={'a': 1})
self.assertRaises(TypeError, self.create_response, content=six.u(''))
def test_json_body(self):
data = {'a': 1}