From 9684cf69e32ae442c7be54521073ac78557f3bbf Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Mon, 6 Nov 2017 16:44:23 -0800 Subject: [PATCH] bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4301) (cherry picked from commit e56ab746a965277ffcc4396d8a0902b6e072d049) --- Lib/sqlite3/test/regression.py | 18 ++++++++++++++++++ .../2017-10-12-18-45-38.bpo-31770.GV3MPx.rst | 2 ++ Modules/_sqlite/cursor.c | 15 +++++++-------- 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index 7dd0050528f..3ff9abd9899 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -24,6 +24,8 @@ import datetime import unittest import sqlite3 as sqlite +import weakref +from test import support class RegressionTests(unittest.TestCase): def setUp(self): @@ -376,6 +378,22 @@ class RegressionTests(unittest.TestCase): counter += 1 self.assertEqual(counter, 3, "should have returned exactly three rows") + def CheckBpo31770(self): + """ + The interpreter shouldn't crash in case Cursor.__init__() is called + more than once. + """ + def callback(*args): + pass + con = sqlite.connect(":memory:") + cur = sqlite.Cursor(con) + ref = weakref.ref(cur, callback) + cur.__init__(con) + del cur + # The interpreter shouldn't crash when ref is collected. + del ref + support.gc_collect() + def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") diff --git a/Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst b/Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst new file mode 100644 index 00000000000..86c7b804bda --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst @@ -0,0 +1,2 @@ +Prevent a crash when calling the ``__init__()`` method of a +``sqlite3.Cursor`` object more than once. Patch by Oren Milman. diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 8341fb84801..b6257a0b9d5 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -39,21 +39,20 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* } Py_INCREF(connection); - self->connection = connection; - self->statement = NULL; - self->next_row = NULL; - self->in_weakreflist = NULL; + Py_XSETREF(self->connection, connection); + Py_CLEAR(self->statement); + Py_CLEAR(self->next_row); - self->row_cast_map = PyList_New(0); + Py_XSETREF(self->row_cast_map, PyList_New(0)); if (!self->row_cast_map) { return -1; } Py_INCREF(Py_None); - self->description = Py_None; + Py_XSETREF(self->description, Py_None); Py_INCREF(Py_None); - self->lastrowid= Py_None; + Py_XSETREF(self->lastrowid, Py_None); self->arraysize = 1; self->closed = 0; @@ -62,7 +61,7 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* self->rowcount = -1L; Py_INCREF(Py_None); - self->row_factory = Py_None; + Py_XSETREF(self->row_factory, Py_None); if (!pysqlite_check_thread(self->connection)) { return -1;