[Python-checkins] bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4302)

Victor Stinner webhook-mailer at python.org
Mon Nov 6 19:44:22 EST 2017


https://github.com/python/cpython/commit/4b544aadd54fd2337d2ab5c137389cae8d1fd781
commit: 4b544aadd54fd2337d2ab5c137389cae8d1fd781
branch: 2.7
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Victor Stinner <victor.stinner at gmail.com>
date: 2017-11-06T16:44:19-08:00
summary:

bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4302)

(cherry picked from commit e56ab746a965277ffcc4396d8a0902b6e072d049)

files:
A Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst
M Lib/sqlite3/test/regression.py
M Modules/_sqlite/cursor.c

diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py
index 36fec59f113..323b25dbb21 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):
@@ -358,6 +360,22 @@ def CheckCommitCursorReset(self):
             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 ad607d93861..3197e78aaed 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -78,21 +78,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;
@@ -101,7 +100,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;



More information about the Python-checkins mailing list