summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2017-11-06 16:44:23 -0800
committerVictor Stinner <victor.stinner@gmail.com>2017-11-06 16:44:23 -0800
commit9684cf69e32ae442c7be54521073ac78557f3bbf (patch)
treea14fd0f9fbc3bc0f060701c026e785e854944d6f
parenta6ffec2e88437ed4fecb10cb359cf2fb64781e9a (diff)
downloadcpython-git-9684cf69e32ae442c7be54521073ac78557f3bbf.tar.gz
bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4301)
(cherry picked from commit e56ab746a965277ffcc4396d8a0902b6e072d049)
-rw-r--r--Lib/sqlite3/test/regression.py18
-rw-r--r--Misc/NEWS.d/next/Library/2017-10-12-18-45-38.bpo-31770.GV3MPx.rst2
-rw-r--r--Modules/_sqlite/cursor.c15
3 files changed, 27 insertions, 8 deletions
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py
index 7dd0050528..3ff9abd989 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 0000000000..86c7b804bd
--- /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 8341fb8480..b6257a0b9d 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;