sqlite3 Connection and Cursor segfault if __init__ is bypassed (by subclass or __new__ call)
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 35.9k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Crash report
What happened?
import sqlite3
con = sqlite3.Connection.__new__(sqlite3.Connection)
print(con.row_factory)
or, more likely:
import sqlite3
class MyCon(sqlite3.Connection):
def __init__(self, *a, **kw):
if self.row_factory:
pass
super().__init__()
c = MyCon(':memory:')
Both give:
fish: Job 1, './python.exe repro.py' terminated by signal SIGSEGV (Address boundary error)
LLDB:
Process 76976 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`Py_INCREF(op=0x0000000000000000) at refcount.h:286:31 [opt] [inlined]
283 _Py_atomic_add_ssize(&op->ob_ref_shared, (1 << _Py_REF_SHARED_SHIFT));
284 }
285 #elif SIZEOF_VOID_P > 4
-> 286 uint32_t cur_refcnt = op->ob_refcnt;
287 if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT) {
288 // the object is immortal
289 _Py_INCREF_IMMORTAL_STAT_INC();
Target 0: (python.exe) stopped.
warning: _sqlite3.cpython-316d-darwin.so was compiled with optimization - stepping may behave oddly; variables may not be available.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`Py_INCREF(op=0x0000000000000000) at refcount.h:286:31 [opt] [inlined]
frame #1: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`_Py_NewRef(obj=0x0000000000000000) at refcount.h:536:5 [opt] [inlined]
frame #2: 0x0000000100a93df0 _sqlite3.cpython-316d-darwin.so`connection_get_row_factory(op=0x0000007a371d4040, closure=0x0000000000000000) at connection.c:564:12 [opt]
So, basically, until the tp_init is called, both row_factory and text_factory are NULL, but are treated as always being python objects, causing a number of segfaults.
This was discovered when fixing: gh-152817 / gh-152818 which was a follow-on from: gh-149738 / gh-149754
I think the fix here is to add a tp_new that initializes the fields before python has a chance to mess with the object, and then rely on the associated guards that prevent delattr on those fields (in the above PRs)
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
Python 3.16.0a0 (heads/main-dirty:c4739533f33, Jul 3 2026, 12:34:46) [Clang 21.0.0 (clang-2100.3.20.102)]
Linked PRs
- gh-152956
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par l’implémentation de la connexion sqlite3 dans connection.c, en particulier connection_get_row_factory, et examinez le reproducer montrant un accès avant tp_init. Consultez la PR liée gh-152956 et exécutez les exemples new et de subclass signalés. C’est terminé lorsque ces cas ne provoquent plus de segfault et que les tests sqlite3 concernés les couvrent.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- c, python
- Domaine
- databases
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 25/100