Issue #21975: Fixed crash when using uninitialized sqlite3.Row (in particular

when unpickling pickled sqlite3.Row).  sqlite3.Row is now initialized in the
__new__() method.
This commit is contained in:
Serhiy Storchaka 2014-08-06 17:50:39 +03:00
parent 9b33872812
commit 3d4b2d4df2
2 changed files with 21 additions and 11 deletions

View File

@ -27,6 +27,10 @@ Core and Builtins
Library Library
------- -------
- Issue #21975: Fixed crash when using uninitialized sqlite3.Row (in particular
when unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in the
__new__() method.
- Issue #21580: Now Tkinter correctly handles bytes arguments passed to Tk. - Issue #21580: Now Tkinter correctly handles bytes arguments passed to Tk.
In particular this allows to initialize images from binary data. In particular this allows to initialize images from binary data.

View File

@ -32,35 +32,41 @@ void pysqlite_row_dealloc(pysqlite_Row* self)
Py_TYPE(self)->tp_free((PyObject*)self); Py_TYPE(self)->tp_free((PyObject*)self);
} }
int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs) static PyObject *
pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
pysqlite_Row *self;
PyObject* data; PyObject* data;
pysqlite_Cursor* cursor; pysqlite_Cursor* cursor;
self->data = 0; assert(type != NULL && type->tp_alloc != NULL);
self->description = 0;
if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) { if (!_PyArg_NoKeywords("Row()", kwargs))
return -1; return NULL;
} if (!PyArg_ParseTuple(args, "OO", &cursor, &data))
return NULL;
if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) { if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) {
PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
return -1; return NULL;
} }
if (!PyTuple_Check(data)) { if (!PyTuple_Check(data)) {
PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
return -1; return NULL;
} }
self = (pysqlite_Row *) type->tp_alloc(type, 0);
if (self == NULL)
return NULL;
Py_INCREF(data); Py_INCREF(data);
self->data = data; self->data = data;
Py_INCREF(cursor->description); Py_INCREF(cursor->description);
self->description = cursor->description; self->description = cursor->description;
return 0; return (PyObject *) self;
} }
PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx)
@ -260,7 +266,7 @@ PyTypeObject pysqlite_RowType = {
0, /* tp_descr_get */ 0, /* tp_descr_get */
0, /* tp_descr_set */ 0, /* tp_descr_set */
0, /* tp_dictoffset */ 0, /* tp_dictoffset */
(initproc)pysqlite_row_init, /* tp_init */ 0, /* tp_init */
0, /* tp_alloc */ 0, /* tp_alloc */
0, /* tp_new */ 0, /* tp_new */
0 /* tp_free */ 0 /* tp_free */
@ -268,7 +274,7 @@ PyTypeObject pysqlite_RowType = {
extern int pysqlite_row_setup_types(void) extern int pysqlite_row_setup_types(void)
{ {
pysqlite_RowType.tp_new = PyType_GenericNew; pysqlite_RowType.tp_new = pysqlite_row_new;
pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping;
pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence;
return PyType_Ready(&pysqlite_RowType); return PyType_Ready(&pysqlite_RowType);