Commit 2902ef94 authored by Serhiy Storchaka's avatar Serhiy Storchaka

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.
parent 2693b5e0
...@@ -19,6 +19,10 @@ Core and Builtins ...@@ -19,6 +19,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 #16037: HTTPMessage.readheaders() raises an HTTPException when more - Issue #16037: HTTPMessage.readheaders() raises an HTTPException when more
than 100 headers are read. Patch by Jyrki Pulliainen and Daniel Eriksson. than 100 headers are read. Patch by Jyrki Pulliainen and Daniel Eriksson.
......
...@@ -33,35 +33,41 @@ void pysqlite_row_dealloc(pysqlite_Row* self) ...@@ -33,35 +33,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)
...@@ -263,7 +269,7 @@ PyTypeObject pysqlite_RowType = { ...@@ -263,7 +269,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 */
...@@ -271,7 +277,7 @@ PyTypeObject pysqlite_RowType = { ...@@ -271,7 +277,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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment