summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Ippolito <bob@redivi.com>2014-06-24 11:49:26 -0700
committerBob Ippolito <bob@redivi.com>2014-06-24 11:49:26 -0700
commitb7486b82233ed2ec1a614dcf8944d376d12d04bf (patch)
treee8c2f1ae3d8544d9453bc2281e631d3a6b68fba7
parenta19d53c1df389648b31619eda67cb178f8f00036 (diff)
downloadsimplejson-b7486b82233ed2ec1a614dcf8944d376d12d04bf.tar.gz
Fix lower bound checking in scan_once / raw_decode API #98v3.5.3
-rw-r--r--CHANGES.txt5
-rw-r--r--conf.py2
-rw-r--r--setup.py2
-rw-r--r--simplejson/__init__.py2
-rw-r--r--simplejson/_speedups.c4
-rw-r--r--simplejson/decoder.py4
-rw-r--r--simplejson/scanner.py5
-rw-r--r--simplejson/tests/test_decode.py11
8 files changed, 30 insertions, 5 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index deb441b..23c705b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,8 @@
+Version 3.5.3 released 2014-06-24
+
+* Fix lower bound checking in scan_once / raw_decode API
+ https://github.com/simplejson/simplejson/issues/98
+
Version 3.5.2 released 2014-05-22
* Fix Windows build with VS2008
diff --git a/conf.py b/conf.py
index afc298e..c222349 100644
--- a/conf.py
+++ b/conf.py
@@ -44,7 +44,7 @@ copyright = '2014, Bob Ippolito'
# The short X.Y version.
version = '3.5'
# The full version, including alpha/beta/rc tags.
-release = '3.5.2'
+release = '3.5.3'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
diff --git a/setup.py b/setup.py
index 96a098b..235241a 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@ from distutils.errors import CCompilerError, DistutilsExecError, \
DistutilsPlatformError
IS_PYPY = hasattr(sys, 'pypy_translation_info')
-VERSION = '3.5.2'
+VERSION = '3.5.3'
DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python"
with open('README.rst', 'r') as f:
diff --git a/simplejson/__init__.py b/simplejson/__init__.py
index af70cd4..a5c0137 100644
--- a/simplejson/__init__.py
+++ b/simplejson/__init__.py
@@ -98,7 +98,7 @@ Using simplejson.tool from the shell to validate and pretty-print::
Expecting property name: line 1 column 3 (char 2)
"""
from __future__ import absolute_import
-__version__ = '3.5.2'
+__version__ = '3.5.3'
__all__ = [
'dump', 'dumps', 'load', 'loads',
'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
index 89ecafd..01614c4 100644
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -2140,7 +2140,7 @@ scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *n
Py_ssize_t length = PyString_GET_SIZE(pystr);
PyObject *rval = NULL;
int fallthrough = 0;
- if (idx >= length) {
+ if (idx < 0 || idx >= length) {
raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
return NULL;
}
@@ -2248,7 +2248,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
Py_ssize_t length = PyUnicode_GetLength(pystr);
PyObject *rval = NULL;
int fallthrough = 0;
- if (idx >= length) {
+ if (idx < 0 || idx >= length) {
raise_errmsg(ERR_EXPECTING_VALUE, pystr, idx);
return NULL;
}
diff --git a/simplejson/decoder.py b/simplejson/decoder.py
index 38cb027..1a6c5d9 100644
--- a/simplejson/decoder.py
+++ b/simplejson/decoder.py
@@ -384,6 +384,10 @@ class JSONDecoder(object):
have extraneous data at the end.
"""
+ if idx < 0:
+ # Ensure that raw_decode bails on negative indexes, the regex
+ # would otherwise mask this behavior. #98
+ raise JSONDecodeError('Expecting value', s, idx)
if _PY3 and not isinstance(s, text_type):
raise TypeError("Input string must be text, not bytes")
return self.scan_once(s, idx=_w(s, idx).end())
diff --git a/simplejson/scanner.py b/simplejson/scanner.py
index b7918b3..5abed35 100644
--- a/simplejson/scanner.py
+++ b/simplejson/scanner.py
@@ -118,6 +118,11 @@ def py_make_scanner(context):
raise JSONDecodeError(errmsg, string, idx)
def scan_once(string, idx):
+ if idx < 0:
+ # Ensure the same behavior as the C speedup, otherwise
+ # this would work for *some* negative string indices due
+ # to the behavior of __getitem__ for strings. #98
+ raise JSONDecodeError('Expecting value', string, idx)
try:
return _scan_once(string, idx)
finally:
diff --git a/simplejson/tests/test_decode.py b/simplejson/tests/test_decode.py
index ea5c90a..30b692a 100644
--- a/simplejson/tests/test_decode.py
+++ b/simplejson/tests/test_decode.py
@@ -86,3 +86,14 @@ class TestDecode(TestCase):
self.assertEqual(
({'a': {}}, 11),
cls().raw_decode(" \n{\"a\": {}}"))
+
+ def test_bounds_checking(self):
+ # https://github.com/simplejson/simplejson/issues/98
+ j = json.decoder.JSONDecoder()
+ for i in [4, 5, 6, -1, -2, -3, -4, -5, -6]:
+ self.assertRaises(ValueError, j.scan_once, '1234', i)
+ self.assertRaises(ValueError, j.raw_decode, '1234', i)
+ x, y = sorted(['128931233', '472389423'], key=id)
+ diff = id(x) - id(y)
+ self.assertRaises(ValueError, j.scan_once, y, diff)
+ self.assertRaises(ValueError, j.raw_decode, y, i)