[python-simplejson/el5] Backport a patch to fix a segfault with nested json
Toshio くらとみ
toshio at fedoraproject.org
Fri Jul 15 23:14:42 UTC 2011
commit cd536ab2cdece7494633d3889932256251b8490e
Author: Toshio Kuratomi <toshio at fedoraproject.org>
Date: Fri Jul 15 16:14:22 2011 -0700
Backport a patch to fix a segfault with nested json
python-simplejson.spec | 9 +-
simplejson-nested-json-segfault.patch | 357 +++++++++++++++++++++++++++++++++
2 files changed, 365 insertions(+), 1 deletions(-)
---
diff --git a/python-simplejson.spec b/python-simplejson.spec
index c844163..d12a130 100644
--- a/python-simplejson.spec
+++ b/python-simplejson.spec
@@ -3,7 +3,7 @@
Name: python-simplejson
Version: 2.0.9
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: Simple, fast, extensible JSON encoder/decoder for Python
Group: System Environment/Libraries
@@ -14,6 +14,9 @@ Patch0: %{name}-fix-containerless-unicode-float-decoding-r177.patch
# not upstreamed, but just modifies the test suite to verify that the issue
# above is really fixed.
Patch1: %{name}-add-test-for-containerless-unicode-float-decoding.patch
+# Backport of fix in 2.1.6 for a segfault with nexted json
+Patch2: simplejson-nested-json-segfault.patch
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: python-devel
@@ -42,6 +45,7 @@ The decoder can handle incoming JSON strings of any specified encoding
%setup -q -n simplejson-%{version}
%patch0 -p1
%patch1 -p1
+%patch2 -p1 -b .216
%build
%{__python} setup.py build
@@ -70,6 +74,9 @@ rm -rf $RPM_BUILD_ROOT
%changelog
+* Fri Jul 15 2011 Toshio Kuratomi <toshio at fedoraproject.org> - 2.0.9-3
+- Backport a patch to fix a segfault with nested json
+
* Wed Aug 11 2010 Felix Schwarz <felix.schwarz at oss.schwarz.eu> - 2.0.9-2
- add patch to fix containerless unicode float decoding (bz 622835)
diff --git a/simplejson-nested-json-segfault.patch b/simplejson-nested-json-segfault.patch
new file mode 100644
index 0000000..d5a7fa3
--- /dev/null
+++ b/simplejson-nested-json-segfault.patch
@@ -0,0 +1,357 @@
+Index: simplejson-2.0.9/simplejson/_speedups.c
+===================================================================
+--- simplejson-2.0.9.orig/simplejson/_speedups.c
++++ simplejson-2.0.9/simplejson/_speedups.c
+@@ -1470,68 +1470,92 @@ scan_once_str(PyScannerObject *s, PyObje
+ */
+ char *str = PyString_AS_STRING(pystr);
+ Py_ssize_t length = PyString_GET_SIZE(pystr);
++ PyObject *rval = NULL;
++ int fallthrough = 0;
+ if (idx >= length) {
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
++ if (Py_EnterRecursiveCall(" while decoding a JSON document"))
++ return NULL;
+ switch (str[idx]) {
+ case '"':
+ /* string */
+- return scanstring_str(pystr, idx + 1,
++ rval = scanstring_str(pystr, idx + 1,
+ PyString_AS_STRING(s->encoding),
+ PyObject_IsTrue(s->strict),
+ next_idx_ptr);
++ break;
+ case '{':
+ /* object */
+- return _parse_object_str(s, pystr, idx + 1, next_idx_ptr);
++ rval = _parse_object_str(s, pystr, idx + 1, next_idx_ptr);
++ break;
+ case '[':
+ /* array */
+- return _parse_array_str(s, pystr, idx + 1, next_idx_ptr);
++ rval = _parse_array_str(s, pystr, idx + 1, next_idx_ptr);
++ break;
+ case 'n':
+ /* null */
+ if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') {
+ Py_INCREF(Py_None);
+ *next_idx_ptr = idx + 4;
+- return Py_None;
++ rval = Py_None;
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 't':
+ /* true */
+ if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') {
+ Py_INCREF(Py_True);
+ *next_idx_ptr = idx + 4;
+- return Py_True;
++ rval = Py_True;
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 'f':
+ /* false */
+ if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') {
+ Py_INCREF(Py_False);
+ *next_idx_ptr = idx + 5;
+- return Py_False;
++ rval = Py_False;
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 'N':
+ /* NaN */
+ if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') {
+- return _parse_constant(s, "NaN", idx, next_idx_ptr);
++ rval = _parse_constant(s, "NaN", idx, next_idx_ptr);
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 'I':
+ /* Infinity */
+ if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') {
+- return _parse_constant(s, "Infinity", idx, next_idx_ptr);
++ rval = _parse_constant(s, "Infinity", idx, next_idx_ptr);
+ }
++ else
++ fallthrough = 1;
+ break;
+ case '-':
+ /* -Infinity */
+ if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') {
+- return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
++ rval = _parse_constant(s, "-Infinity", idx, next_idx_ptr);
+ }
++ else
++ fallthrough = 1;
+ break;
++ default:
++ fallthrough = 1;
+ }
+ /* Didn't find a string, object, array, or named constant. Look for a number. */
+- return _match_number_str(s, pystr, idx, next_idx_ptr);
++ if (fallthrough)
++ rval = _match_number_str(s, pystr, idx, next_idx_ptr);
++ Py_LeaveRecursiveCall();
++ return rval;
+ }
+
+ static PyObject *
+@@ -1546,67 +1570,91 @@ scan_once_unicode(PyScannerObject *s, Py
+ */
+ Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr);
+ Py_ssize_t length = PyUnicode_GET_SIZE(pystr);
++ PyObject *rval = NULL;
++ int fallthrough = 0;
+ if (idx >= length) {
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
++ if (Py_EnterRecursiveCall(" while decoding a JSON document"))
++ return NULL;
+ switch (str[idx]) {
+ case '"':
+ /* string */
+- return scanstring_unicode(pystr, idx + 1,
++ rval = scanstring_unicode(pystr, idx + 1,
+ PyObject_IsTrue(s->strict),
+ next_idx_ptr);
++ break;
+ case '{':
+ /* object */
+- return _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
++ rval = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
++ break;
+ case '[':
+ /* array */
+- return _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
++ rval = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
++ break;
+ case 'n':
+ /* null */
+ if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') {
+ Py_INCREF(Py_None);
+ *next_idx_ptr = idx + 4;
+- return Py_None;
++ rval = Py_None;
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 't':
+ /* true */
+ if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') {
+ Py_INCREF(Py_True);
+ *next_idx_ptr = idx + 4;
+- return Py_True;
++ rval = Py_True;
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 'f':
+ /* false */
+ if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') {
+ Py_INCREF(Py_False);
+ *next_idx_ptr = idx + 5;
+- return Py_False;
++ rval = Py_False;
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 'N':
+ /* NaN */
+ if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') {
+- return _parse_constant(s, "NaN", idx, next_idx_ptr);
++ rval = _parse_constant(s, "NaN", idx, next_idx_ptr);
+ }
++ else
++ fallthrough = 1;
+ break;
+ case 'I':
+ /* Infinity */
+ if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') {
+- return _parse_constant(s, "Infinity", idx, next_idx_ptr);
++ rval = _parse_constant(s, "Infinity", idx, next_idx_ptr);
+ }
++ else
++ fallthrough = 1;
+ break;
+ case '-':
+ /* -Infinity */
+ if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') {
+- return _parse_constant(s, "-Infinity", idx, next_idx_ptr);
++ rval = _parse_constant(s, "-Infinity", idx, next_idx_ptr);
+ }
++ else
++ fallthrough = 1;
+ break;
++ default:
++ fallthrough = 1;
+ }
+ /* Didn't find a string, object, array, or named constant. Look for a number. */
+- return _match_number_unicode(s, pystr, idx, next_idx_ptr);
++ if (fallthrough)
++ rval = _match_number_unicode(s, pystr, idx, next_idx_ptr);
++ Py_LeaveRecursiveCall();
++ return rval;
+ }
+
+ static PyObject *
+@@ -1910,79 +1958,79 @@ static int
+ encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssize_t indent_level)
+ {
+ /* Encode Python object obj to a JSON term, rval is a PyList */
+- PyObject *newobj;
+- int rv;
+-
+- if (obj == Py_None || obj == Py_True || obj == Py_False) {
+- PyObject *cstr = _encoded_const(obj);
+- if (cstr == NULL)
+- return -1;
+- return _steal_list_append(rval, cstr);
+- }
+- else if (PyString_Check(obj) || PyUnicode_Check(obj))
+- {
+- PyObject *encoded = encoder_encode_string(s, obj);
+- if (encoded == NULL)
+- return -1;
+- return _steal_list_append(rval, encoded);
+- }
+- else if (PyInt_Check(obj) || PyLong_Check(obj)) {
+- PyObject *encoded = PyObject_Str(obj);
+- if (encoded == NULL)
+- return -1;
+- return _steal_list_append(rval, encoded);
+- }
+- else if (PyFloat_Check(obj)) {
+- PyObject *encoded = encoder_encode_float(s, obj);
+- if (encoded == NULL)
+- return -1;
+- return _steal_list_append(rval, encoded);
+- }
+- else if (PyList_Check(obj) || PyTuple_Check(obj)) {
+- return encoder_listencode_list(s, rval, obj, indent_level);
+- }
+- else if (PyDict_Check(obj)) {
+- return encoder_listencode_dict(s, rval, obj, indent_level);
+- }
+- else {
+- PyObject *ident = NULL;
+- if (s->markers != Py_None) {
+- int has_key;
+- ident = PyLong_FromVoidPtr(obj);
+- if (ident == NULL)
+- return -1;
+- has_key = PyDict_Contains(s->markers, ident);
+- if (has_key) {
+- if (has_key != -1)
+- PyErr_SetString(PyExc_ValueError, "Circular reference detected");
+- Py_DECREF(ident);
+- return -1;
+- }
+- if (PyDict_SetItem(s->markers, ident, obj)) {
+- Py_DECREF(ident);
+- return -1;
+- }
+- }
+- newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL);
+- if (newobj == NULL) {
+- Py_XDECREF(ident);
+- return -1;
++ int rv = -1;
++ if (Py_EnterRecursiveCall(" while encoding a JSON document"))
++ return rv;
++ do {
++ if (obj == Py_None || obj == Py_True || obj == Py_False) {
++ PyObject *cstr = _encoded_const(obj);
++ if (cstr != NULL)
++ rv = _steal_list_append(rval, cstr);
++ }
++ else if (PyString_Check(obj) || PyUnicode_Check(obj))
++ {
++ PyObject *encoded = encoder_encode_string(s, obj);
++ if (encoded != NULL)
++ rv = _steal_list_append(rval, encoded);
++ }
++ else if (PyInt_Check(obj) || PyLong_Check(obj)) {
++ PyObject *encoded = PyObject_Str(obj);
++ if (encoded != NULL)
++ rv = _steal_list_append(rval, encoded);
++ }
++ else if (PyFloat_Check(obj)) {
++ PyObject *encoded = encoder_encode_float(s, obj);
++ if (encoded != NULL)
++ rv = _steal_list_append(rval, encoded);
+ }
+- rv = encoder_listencode_obj(s, rval, newobj, indent_level);
+- Py_DECREF(newobj);
+- if (rv) {
+- Py_XDECREF(ident);
+- return -1;
++ else if (PyList_Check(obj) || PyTuple_Check(obj)) {
++ rv = encoder_listencode_list(s, rval, obj, indent_level);
+ }
+- if (ident != NULL) {
+- if (PyDict_DelItem(s->markers, ident)) {
++ else if (PyDict_Check(obj)) {
++ rv = encoder_listencode_dict(s, rval, obj, indent_level);
++ }
++ else {
++ PyObject *ident = NULL;
++ PyObject *newobj;
++ if (s->markers != Py_None) {
++ int has_key;
++ ident = PyLong_FromVoidPtr(obj);
++ if (ident == NULL)
++ break;
++ has_key = PyDict_Contains(s->markers, ident);
++ if (has_key) {
++ if (has_key != -1)
++ PyErr_SetString(PyExc_ValueError, "Circular reference detected");
++ Py_DECREF(ident);
++ break;
++ }
++ if (PyDict_SetItem(s->markers, ident, obj)) {
++ Py_DECREF(ident);
++ break;
++ }
++ }
++ newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL);
++ if (newobj == NULL) {
++ Py_XDECREF(ident);
++ break;
++ }
++ rv = encoder_listencode_obj(s, rval, newobj, indent_level);
++ Py_DECREF(newobj);
++ if (rv) {
++ Py_XDECREF(ident);
++ rv = -1;
++ }
++ else if (ident != NULL) {
++ if (PyDict_DelItem(s->markers, ident)) {
++ Py_XDECREF(ident);
++ rv = -1;
++ }
+ Py_XDECREF(ident);
+- return -1;
+ }
+- Py_XDECREF(ident);
+ }
+- return rv;
+- }
++ } while (0);
++ Py_LeaveRecursiveCall();
++ return rv;
+ }
+
+ static int
More information about the scm-commits
mailing list