Skip to content

Commit 48c5cda

Browse files
committed
Add test that lone surrogates are not detected or fixed
Upgrade simplejson to 3.3.0 since prior to that, decoding json with lone surrogates would raise “JSONDecodeError: Unpaired high surrogate”
1 parent e709976 commit 48c5cda

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

remoteobjects/json.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,11 @@
3333
# simplejson >=3.12
3434
from simplejson.errors import errmsg
3535
except ImportError:
36-
try:
37-
# simplejson >=3.1.0, <3.12, before this commit:
38-
# https://github.com/simplejson/simplejson/commit/0d36c5cd16055d55e6eceaf252f072a9339e0746
39-
from simplejson.scanner import errmsg
40-
except ImportError:
41-
# simplejson >=1.1,<3.1.0, before this commit:
42-
# https://github.com/simplejson/simplejson/commit/104b40fcf6aa39d9ba7b240c3c528d1f85e86ef2
43-
from simplejson.decoder import errmsg
36+
# simplejson >=3.1.0, <3.12, since this commit:
37+
# https://github.com/simplejson/simplejson/commit/104b40fcf6aa39d9ba7b240c3c528d1f85e86ef2
38+
# and before this commit
39+
# https://github.com/simplejson/simplejson/commit/0d36c5cd16055d55e6eceaf252f072a9339e0746
40+
from simplejson.scanner import errmsg
4441
from simplejson.scanner import py_make_scanner
4542
from six import unichr, text_type
4643
import sys

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
provides=['remoteobjects'],
6464
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*',
6565
install_requires=[
66-
'simplejson>=2.0.0',
66+
'simplejson>=3.3.0',
6767
'httplib2>=0.5.0',
6868
'python-dateutil>=2.1',
6969
'six~=1.16.0',

tests/test_http.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import unittest
3131

3232
from remoteobjects import fields, http
33+
from six import PY2
3334
from tests import test_dataobject
3435
from tests import utils
3536

@@ -81,6 +82,40 @@ class BasicMost(self.cls):
8182
# Bad characters are replaced with the unicode Replacement Character 0xFFFD.
8283
self.assertEqual(b.value, u"image by \ufffdrew Example")
8384
h.request.assert_called_once_with(**request)
85+
h.reset_mock()
86+
87+
# since simplejson 3.3.0, lone surrogates are passed through
88+
# https://github.com/simplejson/simplejson/commit/35816bfe2d0ddeb5ddcc68239683cbb35b7e3ff2
89+
content = """{"name": "lone surrogate \\ud800", "value": "\\udc00 lone surrogate"}"""
90+
h = utils.mock_http(request, content)
91+
b = BasicMost.get('http://example.com/ohhai', http=h)
92+
# Lone surrogates are passed through as lone surrogates in the python unicode value
93+
self.assertEqual(b.name, u"lone surrogate \ud800")
94+
self.assertEqual(b.value, u"\udc00 lone surrogate")
95+
h.request.assert_called_once_with(**request)
96+
97+
content = u"""{"name": "100 \u20AC", "value": "13000 \u00A5"}""".encode('utf-8')
98+
h = utils.mock_http(request, content)
99+
b = BasicMost.get('http://example.com/ohhai', http=h)
100+
# JSON containing non-ascii UTF-8 should be decoded to unicode strings
101+
self.assertEqual(b.name, u"100 \u20AC")
102+
self.assertEqual(b.value, u"13000 \u00A5")
103+
h.request.assert_called_once_with(**request)
104+
105+
content = b"""{"name": "lone surrogate \xed\xa0\x80", "value": "\xed\xb0\x80 lone surrogate"}"""
106+
h = utils.mock_http(request, content)
107+
b = BasicMost.get('http://example.com/ohhai', http=h)
108+
# Lone surrogates are passed through as lone surrogates in the python unicode value
109+
if PY2:
110+
# in python2, our JSONDecoder does not detect naked lone surrogates
111+
self.assertEqual(b.name, u"lone surrogate \ud800")
112+
self.assertEqual(b.value, u"\udc00 lone surrogate")
113+
else:
114+
# in python3, bytes.decode replaces lone surrogates with replacement char
115+
self.assertEqual(b.name, u"lone surrogate \ufffd\ufffd\ufffd")
116+
self.assertEqual(b.value, u"\ufffd\ufffd\ufffd lone surrogate")
117+
118+
h.request.assert_called_once_with(**request)
84119

85120
def test_post(self):
86121

0 commit comments

Comments
 (0)