]> granicus.if.org Git - python/commitdiff
bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 7 Nov 2017 00:44:23 +0000 (16:44 -0800)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 7 Nov 2017 00:44:23 +0000 (16:44 -0800)
(cherry picked from commit e56ab746a965277ffcc4396d8a0902b6e072d049)

Lib/sqlite3/test/regression.py
Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst [new file with mode: 0644]
Modules/_sqlite/cursor.c

index 7dd0050528f8fa19541e6a7ba10c30bc40c771b9..3ff9abd98993f7865191f6f23d2e03025bfee0da 100644 (file)
@@ -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 (file)
index 0000000..86c7b80
--- /dev/null
@@ -0,0 +1,2 @@
+Prevent a crash when calling the ``__init__()`` method of a
+``sqlite3.Cursor`` object more than once. Patch by Oren Milman.
index 8341fb8480172c946bfdc62c0c52dcac402d221f..b6257a0b9d5a3fc32294da8501a3094536a8bc9f 100644 (file)
@@ -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;