summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-05-05 07:08:49 (GMT)
committerGitHub <noreply@github.com>2017-05-05 07:08:49 (GMT)
commit76a3e51a403bc84ed536921866c86dd7d07aaa7e (patch)
tree0cfc6ca2cd2da36730d15d6b9c5d7ffaac955abd /Modules
parent898ff03e1e7925ecde3da66327d3cdc7e07625ba (diff)
downloadcpython-76a3e51a403bc84ed536921866c86dd7d07aaa7e.zip
cpython-76a3e51a403bc84ed536921866c86dd7d07aaa7e.tar.gz
cpython-76a3e51a403bc84ed536921866c86dd7d07aaa7e.tar.bz2
bpo-30243: Fixed the possibility of a crash in _json. (#1420)
It was possible to get a core dump by using uninitialized _json objects. Now __new__ methods create initialized objects. __init__ methods are removed.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_json.c86
1 files changed, 20 insertions, 66 deletions
diff --git a/Modules/_json.c b/Modules/_json.c
index 28fdc79..e78e371 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -89,16 +89,12 @@ static PyObject *
_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx);
static PyObject *
scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
-static int
-scanner_init(PyObject *self, PyObject *args, PyObject *kwds);
static void
scanner_dealloc(PyObject *self);
static int
scanner_clear(PyObject *self);
static PyObject *
encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
-static int
-encoder_init(PyObject *self, PyObject *args, PyObject *kwds);
static void
encoder_dealloc(PyObject *self);
static int
@@ -1200,38 +1196,21 @@ static PyObject *
scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyScannerObject *s;
- s = (PyScannerObject *)type->tp_alloc(type, 0);
- if (s != NULL) {
- s->strict = NULL;
- s->object_hook = NULL;
- s->object_pairs_hook = NULL;
- s->parse_float = NULL;
- s->parse_int = NULL;
- s->parse_constant = NULL;
- }
- return (PyObject *)s;
-}
-
-static int
-scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
- /* Initialize Scanner object */
PyObject *ctx;
static char *kwlist[] = {"context", NULL};
- PyScannerObject *s;
-
- assert(PyScanner_Check(self));
- s = (PyScannerObject *)self;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
- return -1;
+ return NULL;
- if (s->memo == NULL) {
- s->memo = PyDict_New();
- if (s->memo == NULL)
- goto bail;
+ s = (PyScannerObject *)type->tp_alloc(type, 0);
+ if (s == NULL) {
+ return NULL;
}
+ s->memo = PyDict_New();
+ if (s->memo == NULL)
+ goto bail;
+
/* All of these will fail "gracefully" so we don't need to verify them */
s->strict = PyObject_GetAttrString(ctx, "strict");
if (s->strict == NULL)
@@ -1252,16 +1231,11 @@ scanner_init(PyObject *self, PyObject *args, PyObject *kwds)
if (s->parse_constant == NULL)
goto bail;
- return 0;
+ return (PyObject *)s;
bail:
- Py_CLEAR(s->strict);
- Py_CLEAR(s->object_hook);
- Py_CLEAR(s->object_pairs_hook);
- Py_CLEAR(s->parse_float);
- Py_CLEAR(s->parse_int);
- Py_CLEAR(s->parse_constant);
- return -1;
+ Py_DECREF(s);
+ return NULL;
}
PyDoc_STRVAR(scanner_doc, "JSON scanner object");
@@ -1303,7 +1277,7 @@ PyTypeObject PyScannerType = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- scanner_init, /* tp_init */
+ 0, /* tp_init */
0,/* PyType_GenericAlloc, */ /* tp_alloc */
scanner_new, /* tp_new */
0,/* PyObject_GC_Del, */ /* tp_free */
@@ -1312,25 +1286,6 @@ PyTypeObject PyScannerType = {
static PyObject *
encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- PyEncoderObject *s;
- s = (PyEncoderObject *)type->tp_alloc(type, 0);
- if (s != NULL) {
- s->markers = NULL;
- s->defaultfn = NULL;
- s->encoder = NULL;
- s->indent = NULL;
- s->key_separator = NULL;
- s->item_separator = NULL;
- s->sort_keys = NULL;
- s->skipkeys = NULL;
- }
- return (PyObject *)s;
-}
-
-static int
-encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
- /* initialize Encoder object */
static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
PyEncoderObject *s;
@@ -1338,22 +1293,23 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *item_separator, *sort_keys, *skipkeys;
int allow_nan;
- assert(PyEncoder_Check(self));
- s = (PyEncoderObject *)self;
-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUOOp:make_encoder", kwlist,
&markers, &defaultfn, &encoder, &indent,
&key_separator, &item_separator,
&sort_keys, &skipkeys, &allow_nan))
- return -1;
+ return NULL;
if (markers != Py_None && !PyDict_Check(markers)) {
PyErr_Format(PyExc_TypeError,
"make_encoder() argument 1 must be dict or None, "
"not %.200s", Py_TYPE(markers)->tp_name);
- return -1;
+ return NULL;
}
+ s = (PyEncoderObject *)type->tp_alloc(type, 0);
+ if (s == NULL)
+ return NULL;
+
s->markers = markers;
s->defaultfn = defaultfn;
s->encoder = encoder;
@@ -1380,7 +1336,7 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds)
Py_INCREF(s->item_separator);
Py_INCREF(s->sort_keys);
Py_INCREF(s->skipkeys);
- return 0;
+ return (PyObject *)s;
}
static PyObject *
@@ -1911,7 +1867,7 @@ PyTypeObject PyEncoderType = {
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
- encoder_init, /* tp_init */
+ 0, /* tp_init */
0, /* tp_alloc */
encoder_new, /* tp_new */
0, /* tp_free */
@@ -1954,10 +1910,8 @@ PyInit__json(void)
PyObject *m = PyModule_Create(&jsonmodule);
if (!m)
return NULL;
- PyScannerType.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyScannerType) < 0)
goto fail;
- PyEncoderType.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyEncoderType) < 0)
goto fail;
Py_INCREF((PyObject*)&PyScannerType);