[New-bugs-announce] [issue31770] crash and refleaks when calling sqlite3.Cursor.__init__() more than once

Oren Milman report at bugs.python.org
Thu Oct 12 04:18:36 EDT 2017


New submission from Oren Milman <orenmn at gmail.com>:

The following code crashes:
import sqlite3
import weakref
def callback(*args):
    pass

connection = sqlite3.connect(":memory:")
cursor = sqlite3.Cursor(connection)
ref = weakref.ref(cursor, callback)
cursor.__init__(connection)
del cursor
del ref

IIUC, this is because pysqlite_cursor_init() (in Modules/_sqlite/cursor.c) sets
`self->in_weakreflist` to NULL, and thus corrupts the weakref list. Later,
clear_weakref() (in Objects/weakrefobject.c) tries to remove a reference from
the corrupted list, and crashes.

In every other place (that i saw) where such a weakreflist field is used, it is
set to NULL right after allocating the object (usually in __new__()), or just
not set at all, e.g. in `functools.partial`.
So since PyType_GenericNew() is the __new__() of sqlite3.Cursor, ISTM that the
simplest solution is to not touch `self->in_weakreflist` at all in
pysqlite_cursor_init().


Also, the following code results in refleaks:
import sys
import sqlite3
connection = sqlite3.connect(":memory:")
cursor = sqlite3.Cursor(connection)
refcount_before = sys.gettotalrefcount()
cursor.__init__(connection)
print(sys.gettotalrefcount() - refcount_before)  # should be close to 0

This is because pysqlite_cursor_init() doesn't decref before assigning to
fields of `self`.


I would open a PR to fix this soon.

----------
components: Extension Modules
messages: 304220
nosy: Oren Milman
priority: normal
severity: normal
status: open
title: crash and refleaks when calling sqlite3.Cursor.__init__() more than once
type: crash
versions: Python 3.7

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue31770>
_______________________________________


More information about the New-bugs-announce mailing list