Skip to content

Commit

Permalink
Type check the empty string when creating repsonse
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jamielennox committed Jan 31, 2017
1 parent 95dffef commit 86fb33d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
12 changes: 6 additions & 6 deletions requests_mock/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -207,12 +207,12 @@ def __init__(self, **kwargs):
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):
Expand Down
17 changes: 17 additions & 0 deletions requests_mock/tests/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,13 @@ def test_dont_pass_unicode_as_content(self):
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')
Expand All @@ -275,6 +282,16 @@ def test_dont_pass_bytes_as_text(self):
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,
Expand Down
5 changes: 5 additions & 0 deletions requests_mock/tests/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ def test_content_type(self):
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}
Expand Down

0 comments on commit 86fb33d

Please sign in to comment.