Commit 08d230a5 authored by Serhiy Storchaka's avatar Serhiy Storchaka

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.
parent df9ba362
...@@ -162,6 +162,14 @@ class RowFactoryTests(unittest.TestCase): ...@@ -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()
......
...@@ -1169,6 +1169,22 @@ class SimpleNamespaceTests(unittest.TestCase): ...@@ -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,
......
...@@ -10,6 +10,9 @@ Release date: tba ...@@ -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 ...@@ -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
......
...@@ -46,7 +46,7 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) ...@@ -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;
} }
......
...@@ -398,8 +398,7 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) { ...@@ -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) { ...@@ -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;
} }
......
...@@ -164,12 +164,11 @@ namespace_clear(_PyNamespaceObject *ns) ...@@ -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;
} }
......
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