Issue #24257: Fixed incorrect uses of PyObject_IsInstance().

Fixed segmentation fault in sqlite3.Row constructor with faked cursor type.
Fixed system error in the comparison of faked types.SimpleNamespace.
This commit is contained in:
Serhiy Storchaka 2015-05-22 11:13:20 +03:00
commit e79ec70801
6 changed files with 36 additions and 8 deletions

View file

@ -180,6 +180,14 @@ class RowFactoryTests(unittest.TestCase):
self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) self.assertEqual(list(reversed(row)), list(reversed(as_tuple)))
self.assertIsInstance(row, Sequence) self.assertIsInstance(row, Sequence)
def CheckFakeCursorClass(self):
# Issue #24257: Incorrect use of PyObject_IsInstance() caused
# segmentation fault.
class FakeCursor(str):
__class__ = sqlite.Cursor
cur = self.con.cursor(factory=FakeCursor)
self.assertRaises(TypeError, sqlite.Row, cur, ())
def tearDown(self): def tearDown(self):
self.con.close() self.con.close()

View file

@ -1172,6 +1172,22 @@ class SimpleNamespaceTests(unittest.TestCase):
self.assertEqual(ns, ns_roundtrip, pname) self.assertEqual(ns, ns_roundtrip, pname)
def test_fake_namespace_compare(self):
# Issue #24257: Incorrect use of PyObject_IsInstance() caused
# SystemError.
class FakeSimpleNamespace(str):
__class__ = types.SimpleNamespace
self.assertFalse(types.SimpleNamespace() == FakeSimpleNamespace())
self.assertTrue(types.SimpleNamespace() != FakeSimpleNamespace())
with self.assertRaises(TypeError):
types.SimpleNamespace() < FakeSimpleNamespace()
with self.assertRaises(TypeError):
types.SimpleNamespace() <= FakeSimpleNamespace()
with self.assertRaises(TypeError):
types.SimpleNamespace() > FakeSimpleNamespace()
with self.assertRaises(TypeError):
types.SimpleNamespace() >= FakeSimpleNamespace()
class CoroutineTests(unittest.TestCase): class CoroutineTests(unittest.TestCase):
def test_wrong_args(self): def test_wrong_args(self):

View file

@ -10,6 +10,9 @@ Release date: 2015-05-24
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #24257: Fixed system error in the comparison of faked
types.SimpleNamespace.
- Issue #22939: Fixed integer overflow in iterator object. Patch by - Issue #22939: Fixed integer overflow in iterator object. Patch by
Clement Rouault. Clement Rouault.
@ -55,6 +58,9 @@ Core and Builtins
Library Library
------- -------
- Issue #24257: Fixed segmentation fault in sqlite3.Row constructor with faked
cursor type.
- Issue #15836: assertRaises(), assertRaisesRegex(), assertWarns() and - Issue #15836: assertRaises(), assertRaisesRegex(), assertWarns() and
assertWarnsRegex() assertments now check the type of the first argument assertWarnsRegex() assertments now check the type of the first argument
to prevent possible user error. Based on patch by Daniel Wagner-Hall. to prevent possible user error. Based on patch by Daniel Wagner-Hall.

View file

@ -46,7 +46,7 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) if (!PyArg_ParseTuple(args, "OO", &cursor, &data))
return NULL; return NULL;
if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) { if (!PyObject_TypeCheck((PyObject*)cursor, &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 NULL; return NULL;
} }

View file

@ -442,8 +442,7 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) {
PyErr_Fetch(&et, &ev, &tb); PyErr_Fetch(&et, &ev, &tb);
if (ev) { if (ev) {
/* exception will usually be normalised already */ /* exception will usually be normalised already */
if (Py_TYPE(ev) == (PyTypeObject *) et if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) {
|| PyObject_IsInstance(ev, PyExc_StopIteration)) {
value = ((PyStopIterationObject *)ev)->value; value = ((PyStopIterationObject *)ev)->value;
Py_INCREF(value); Py_INCREF(value);
Py_DECREF(ev); Py_DECREF(ev);
@ -453,7 +452,7 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) {
} else { } else {
/* normalisation required */ /* normalisation required */
PyErr_NormalizeException(&et, &ev, &tb); PyErr_NormalizeException(&et, &ev, &tb);
if (!PyObject_IsInstance(ev, PyExc_StopIteration)) { if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) {
PyErr_Restore(et, ev, tb); PyErr_Restore(et, ev, tb);
return -1; return -1;
} }

View file

@ -164,12 +164,11 @@ namespace_clear(_PyNamespaceObject *ns)
static PyObject * static PyObject *
namespace_richcompare(PyObject *self, PyObject *other, int op) namespace_richcompare(PyObject *self, PyObject *other, int op)
{ {
if (PyObject_IsInstance(self, (PyObject *)&_PyNamespace_Type) && if (PyObject_TypeCheck(self, &_PyNamespace_Type) &&
PyObject_IsInstance(other, (PyObject *)&_PyNamespace_Type)) PyObject_TypeCheck(other, &_PyNamespace_Type))
return PyObject_RichCompare(((_PyNamespaceObject *)self)->ns_dict, return PyObject_RichCompare(((_PyNamespaceObject *)self)->ns_dict,
((_PyNamespaceObject *)other)->ns_dict, op); ((_PyNamespaceObject *)other)->ns_dict, op);
Py_INCREF(Py_NotImplemented); Py_RETURN_NOTIMPLEMENTED;
return Py_NotImplemented;
} }