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:02:49 +03:00
parent df9ba3623a
commit 08d230a540
6 changed files with 36 additions and 8 deletions

View file

@ -162,6 +162,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

@ -1169,6 +1169,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()
def test_main(): def test_main():
run_unittest(TypesTests, MappingProxyTests, ClassCreationTests, run_unittest(TypesTests, MappingProxyTests, ClassCreationTests,

View file

@ -10,6 +10,9 @@ Release date: tba
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.
@ -56,6 +59,9 @@ Core and Builtins
Library Library
------- -------
- Issue #24257: Fixed segmentation fault in sqlite3.Row constructor with faked
cursor type.
- Issue #22107: tempfile.gettempdir() and tempfile.mkdtemp() now try again - Issue #22107: tempfile.gettempdir() and tempfile.mkdtemp() now try again
when a directory with the chosen name already exists on Windows as well as when a directory with the chosen name already exists on Windows as well as
on Unix. tempfile.mkstemp() now fails early if parent directory is not on Unix. tempfile.mkstemp() now fails early if parent directory is not

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

@ -398,8 +398,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);
@ -409,7 +408,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;
} }