bpo-31770: Prevent a crash and refleaks when calling sqlite3.Cursor._… · python/cpython@9684cf6

3 files changed

lines changed

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):

@@ -376,6 +378,22 @@ def CheckCommitCursorReset(self):

376378

counter += 1

377379

self.assertEqual(counter, 3, "should have returned exactly three rows")

378380
381+

def CheckBpo31770(self):

382+

"""

383+

The interpreter shouldn't crash in case Cursor.__init__() is called

384+

more than once.

385+

"""

386+

def callback(*args):

387+

pass

388+

con = sqlite.connect(":memory:")

389+

cur = sqlite.Cursor(con)

390+

ref = weakref.ref(cur, callback)

391+

cur.__init__(con)

392+

del cur

393+

# The interpreter shouldn't crash when ref is collected.

394+

del ref

395+

support.gc_collect()

396+
379397
380398

def suite():

381399

regression_suite = unittest.makeSuite(RegressionTests, "Check")

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.

Original file line numberDiff line numberDiff line change

@@ -39,21 +39,20 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*

3939

}

4040
4141

Py_INCREF(connection);

42-

self->connection = connection;

43-

self->statement = NULL;

44-

self->next_row = NULL;

45-

self->in_weakreflist = NULL;

42+

Py_XSETREF(self->connection, connection);

43+

Py_CLEAR(self->statement);

44+

Py_CLEAR(self->next_row);

4645
47-

self->row_cast_map = PyList_New(0);

46+

Py_XSETREF(self->row_cast_map, PyList_New(0));

4847

if (!self->row_cast_map) {

4948

return -1;

5049

}

5150
5251

Py_INCREF(Py_None);

53-

self->description = Py_None;

52+

Py_XSETREF(self->description, Py_None);

5453
5554

Py_INCREF(Py_None);

56-

self->lastrowid= Py_None;

55+

Py_XSETREF(self->lastrowid, Py_None);

5756
5857

self->arraysize = 1;

5958

self->closed = 0;

@@ -62,7 +61,7 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*

6261

self->rowcount = -1L;

6362
6463

Py_INCREF(Py_None);

65-

self->row_factory = Py_None;

64+

Py_XSETREF(self->row_factory, Py_None);

6665
6766

if (!pysqlite_check_thread(self->connection)) {

6867

return -1;