diff options
author | Bob Ippolito <bob@redivi.com> | 2008-03-25 02:43:59 +0000 |
---|---|---|
committer | Bob Ippolito <bob@redivi.com> | 2008-03-25 02:43:59 +0000 |
commit | 8b57d87e276c6031457873847d96542294a34cfe (patch) | |
tree | 95043462692ff35026b7a3679c2698db00266b4e | |
parent | 5d360053b7b6483978a82852dd7032bc30deaf97 (diff) | |
download | simplejson-8b57d87e276c6031457873847d96542294a34cfe.tar.gz |
bump version, resolve http://code.google.com/p/simplejson/issues/detail?id=3
git-svn-id: http://simplejson.googlecode.com/svn/trunk@80 a4795897-2c25-0410-b006-0d3caba88fa1
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | simplejson/__init__.py | 2 | ||||
-rw-r--r-- | simplejson/_speedups.c | 21 | ||||
-rw-r--r-- | simplejson/decoder.py | 19 | ||||
-rw-r--r-- | simplejson/tests/test_fail.py | 2 |
5 files changed, 32 insertions, 14 deletions
@@ -18,7 +18,7 @@ from distutils.command.build_ext import build_ext from distutils.errors import CCompilerError, DistutilsExecError, \ DistutilsPlatformError -VERSION = '1.8.1' +VERSION = '1.8.2' DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python" LONG_DESCRIPTION = """ simplejson is a simple, fast, complete, correct and extensible diff --git a/simplejson/__init__.py b/simplejson/__init__.py index be9e87a..94b94f8 100644 --- a/simplejson/__init__.py +++ b/simplejson/__init__.py @@ -99,7 +99,7 @@ pretty-print:: Note that the JSON produced by this module's default settings is a subset of YAML, so it may be used as a serializer for that as well. """ -__version__ = '1.8.1' +__version__ = '1.8.2' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONEncoder', diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index c7a7a7c..7021b21 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -239,7 +239,7 @@ join_list_unicode(PyObject *lst) { } static PyObject * -scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding) { +scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict) { PyObject *rval; Py_ssize_t len = PyString_GET_SIZE(pystr); Py_ssize_t begin = end - 1; @@ -257,6 +257,9 @@ scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding) { c = buf[next]; if (c == '"' || c == '\\') { break; + } else if (strict && c <= 0x1f) { + raise_errmsg("Invalid control character at", pystr, begin); + goto bail; } } if (!(c == '"' || c == '\\')) { @@ -397,7 +400,7 @@ bail: static PyObject * -scanstring_unicode(PyObject *pystr, Py_ssize_t end) { +scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict) { PyObject *rval; Py_ssize_t len = PyUnicode_GET_SIZE(pystr); Py_ssize_t begin = end - 1; @@ -415,6 +418,9 @@ scanstring_unicode(PyObject *pystr, Py_ssize_t end) { c = buf[next]; if (c == '"' || c == '\\') { break; + } else if (strict && c <= 0x1f) { + raise_errmsg("Invalid control character at", pystr, begin); + goto bail; } } if (!(c == '"' || c == '\\')) { @@ -559,11 +565,12 @@ static PyObject * py_scanstring(PyObject* self UNUSED, PyObject *args) { PyObject *pystr; Py_ssize_t end; - char *encoding; + char *encoding = NULL; + int strict = 0; #if PY_VERSION_HEX < 0x02050000 - if (!PyArg_ParseTuple(args, "Oiz:scanstring", &pystr, &end, &encoding)) { + if (!PyArg_ParseTuple(args, "Oi|zi:scanstring", &pystr, &end, &encoding, &strict)) { #else - if (!PyArg_ParseTuple(args, "Onz:scanstring", &pystr, &end, &encoding)) { + if (!PyArg_ParseTuple(args, "On|zi:scanstring", &pystr, &end, &encoding, &strict)) { #endif return NULL; } @@ -571,9 +578,9 @@ py_scanstring(PyObject* self UNUSED, PyObject *args) { encoding = DEFAULT_ENCODING; } if (PyString_Check(pystr)) { - return scanstring_str(pystr, end, encoding); + return scanstring_str(pystr, end, encoding, strict); } else if (PyUnicode_Check(pystr)) { - return scanstring_unicode(pystr, end); + return scanstring_unicode(pystr, end, strict); } PyErr_SetString(PyExc_TypeError, "first argument must be a string"); return NULL; diff --git a/simplejson/decoder.py b/simplejson/decoder.py index 6a73e9a..6d4c5d7 100644 --- a/simplejson/decoder.py +++ b/simplejson/decoder.py @@ -70,7 +70,7 @@ def JSONNumber(match, context): return res, None pattern(r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?')(JSONNumber) -STRINGCHUNK = re.compile(r'(.*?)(["\\])', FLAGS) +STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) BACKSLASH = { '"': u'"', '\\': u'\\', '/': u'/', 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t', @@ -78,7 +78,7 @@ BACKSLASH = { DEFAULT_ENCODING = "utf-8" -def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match): +def scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match): if encoding is None: encoding = DEFAULT_ENCODING chunks = [] @@ -97,6 +97,12 @@ def scanstring(s, end, encoding=None, _b=BACKSLASH, _m=STRINGCHUNK.match): _append(content) if terminator == '"': break + elif terminator != '\\': + if strict: + raise ValueError(errmsg("Invalid control character %r at", s, end)) + else: + _append(terminator) + continue try: esc = s[end] except IndexError: @@ -140,7 +146,8 @@ if _speedups is not None: def JSONString(match, context): encoding = getattr(context, 'encoding', None) - return scanstring(match.string, match.end(), encoding) + strict = getattr(context, 'strict', True) + return scanstring(match.string, match.end(), encoding, strict) pattern(r'"')(JSONString) WHITESPACE = re.compile(r'\s*', FLAGS) @@ -157,9 +164,10 @@ def JSONObject(match, context, _w=WHITESPACE.match): raise ValueError(errmsg("Expecting property name", s, end)) end += 1 encoding = getattr(context, 'encoding', None) + strict = getattr(context, 'strict', True) iterscan = JSONScanner.iterscan while True: - key, end = scanstring(s, end, encoding) + key, end = scanstring(s, end, encoding, strict) end = _w(s, end).end() if s[end:end + 1] != ':': raise ValueError(errmsg("Expecting : delimiter", s, end)) @@ -257,7 +265,7 @@ class JSONDecoder(object): __all__ = ['__init__', 'decode', 'raw_decode'] def __init__(self, encoding=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None): + parse_int=None, parse_constant=None, strict=True): """ ``encoding`` determines the encoding used to interpret any ``str`` objects decoded by this instance (utf-8 by default). It has no @@ -291,6 +299,7 @@ class JSONDecoder(object): self.parse_float = parse_float self.parse_int = parse_int self.parse_constant = parse_constant + self.strict = strict def decode(self, s, _w=WHITESPACE.match): """ diff --git a/simplejson/tests/test_fail.py b/simplejson/tests/test_fail.py index a99d9c4..9534a94 100644 --- a/simplejson/tests/test_fail.py +++ b/simplejson/tests/test_fail.py @@ -48,6 +48,8 @@ JSONDOCS = [ '["Bad value", truth]', # http://json.org/JSON_checker/test/fail24.json "['single quote']", + # http://code.google.com/p/simplejson/issues/detail?id=3 + u'["A\u001FZ control characters in string"]', ] SKIPS = { |