10000 bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor._… · python/cpython@4b544aa · GitHub
[go: up one dir, main page]

Skip to content

Commit 4b544aa

Browse files
miss-islingtonvstinner
authored andcommitted
bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor.__init__() more than once (GH-3968) (#4302)
(cherry picked from commit e56ab74)
1 parent 3053769 commit 4b544aa

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

Lib/sqlite3/test/regression.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import datetime
2525
import unittest
2626
import sqlite3 as sqlite
27+
import weakref
28+
from test import support
2729

2830
class RegressionTests(unittest.TestCase):
2931
def setUp(self):
@@ -358,6 +360,22 @@ def CheckCommitCursorReset(self):
358360
counter += 1
359361
self.assertEqual(counter, 3, "should have returned exactly three rows")
360362

363+
def CheckBpo31770(self):
364+
"""
365+
The interpreter shouldn't crash in case Cursor.__init__() is called
366+
more than once.
367+
"""
368+
def callback(*args):
369+
pass
370+
con = sqlite.connect(":memory:")
371+
cur = sqlite.Cursor(con)
372+
ref = weakref.ref(cur, callback)
373+
cur.__init__(con)
374+
del cur
375+
# The interpreter shouldn't crash when ref is collected.
376+
del ref
377+
support.gc_collect()
378+
361379

362380
def suite():
363381
regression_suite = unittest.makeSuite(RegressionTests, "Check")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Prevent a crash when calling the ``__init__()`` method of a
2+
``sqlite3.Cursor`` object more than once. Patch by Oren Milman.

Modules/_sqlite/cursor.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,20 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*
7878
}
7979

8080
Py_INCREF(connection);
81-
self->connection = connection;
82-
self->statement = NULL;
83-
< E096 span class=pl-s1>self->next_row = NULL;
84-
self->in_weakreflist = NULL;
81+
Py_XSETREF(self->connection, connection);
82+
Py_CLEAR(self->statement);
83+
Py_CLEAR(self->next_row);
8584

86-
self->row_cast_map = PyList_New(0);
85+
Py_XSETREF(self->row_cast_map, PyList_New(0));
8786
if (!self->row_cast_map) {
8887
return -1;
8988
}
9089

9190
Py_INCREF(Py_None);
92-
self->description = Py_None;
91+
Py_XSETREF(self->description, Py_None);
9392

9493
Py_INCREF(Py_None);
95-
self->lastrowid= Py_None;
94+
Py_XSETREF(self->lastrowid, Py_None);
9695

9796
self->arraysize = 1;
9897
self->closed = 0;
@@ -101,7 +100,7 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*
101100
self->rowcount = -1L;
102101

103102
Py_INCREF(Py_None);
104-
self->row_factory = Py_None;
103+
Py_XSETREF(self->row_factory, Py_None);
105104

106105
if (!pysqlite_check_thread(self->connection)) {
107106
return -1;

0 commit comments

Comments
 (0)
0