Skip to content

gh-149738: Fix segmentation fault bug in sqllite3#149754

Merged
vstinner merged 18 commits into
python:mainfrom
sepehr-rs:fix-149738
Jun 2, 2026
Merged

gh-149738: Fix segmentation fault bug in sqllite3#149754
vstinner merged 18 commits into
python:mainfrom
sepehr-rs:fix-149738

Conversation

@sepehr-rs
Copy link
Copy Markdown
Contributor

@sepehr-rs sepehr-rs commented May 13, 2026

Fixes #149738.

>>> import sqlite3
>>> db = sqlite3.connect(":memory:")
>>> del db.row_factory
>>> db.execute("test")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    db.execute("test")
    ~~~~~~~~~~^^^^^^^^
sqlite3.OperationalError: near "test": syntax error
>>> 

Copy link
Copy Markdown
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need tests and check what happens on the created connection after deletion (check that there is still a row factory on the newly created cursor)

@sepehr-rs
Copy link
Copy Markdown
Contributor Author

sepehr-rs commented May 13, 2026

Thanks for your comment and review, @picnixz!
I’ve added the tests as requested and would appreciate any feedback.

P.S. The Read the Docs build is failing, but the logs indicate it’s due to an external issue unrelated to my changes.

Copy link
Copy Markdown
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer using connection_getset instead of connection_members for row_factory and text_factory to raise an exception if the developer tries to delete the attribute (set it to NULL). Add get/set on these attributes.

@sepehr-rs
Copy link
Copy Markdown
Contributor Author

Hi @vstinner! Thank you for your kind review. Sorry for the delay, GitHub access has been unreliable here recently.
I’ve made the requested changes and would appreciate your feedback when you have a chance.

Comment thread Modules/_sqlite/connection.c
Comment thread Modules/_sqlite/connection.c Outdated
Comment thread Lib/test/test_sqlite3/test_factory.py
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2026-05-13-06-54-41.gh-issue-149738.4BLFoH.rst Outdated
@vstinner vstinner added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels May 21, 2026
Copy link
Copy Markdown
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plesse correct undefined behaviors by changing the getset signatures. There should be no cast to getter/setter.

Comment thread Modules/_sqlite/connection.c Outdated
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented May 27, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Comment thread Modules/_sqlite/connection.c Outdated
}

static PyObject *
connection_get_row_factory(pysqlite_Connection *self, void *closure)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those getsets must be using a critical section as well.

@sepehr-rs
Copy link
Copy Markdown
Contributor Author

sepehr-rs commented May 30, 2026

Hi @picnixz, thank you for the review.

I've updated the getter/setter signatures to match the expected PyGetSetDef prototypes, removed the casts, and updated the documentation with the requested notes.

Regarding the request to use a critical section: I searched Modules/_sqlite for existing uses of Py_BEGIN_CRITICAL_SECTION (and related APIs), but couldn't find any examples in the sqlite module itself. I'm not very familiar with the free-threading synchronization patterns used in this part of CPython.

Could you please point me to an example, or clarify which object/state should be protected here?

I have made the requested changes; please review again.

@picnixz
Copy link
Copy Markdown
Member

picnixz commented May 30, 2026

Thx. For now let's ignore races on attributes. If we can have many other attributes that can be mutated but none are protected, we can address it later.

Comment thread Doc/library/sqlite3.rst Outdated
Copy link
Copy Markdown
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I have minor concerns about the doc changes.

Comment thread Doc/library/sqlite3.rst Outdated

.. versionchanged:: next
Deleting the ``row_factory`` attribute is no longer allowed and raises
:exc:`AttributeError`.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that it's worth it to document this minor behavior. I'm not sure that it's useful to mention the exact exception (AttributeError).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback.
I've simplified the versionchanged note and removed the mention of the specific exception. I kept the note itself since this is a user-visible behavior change, but I'm open to removing it if you think it's not necessary.

@vstinner
Copy link
Copy Markdown
Member

vstinner commented Jun 1, 2026

@picnixz: Do you want to double check the change?

Copy link
Copy Markdown
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Should we backport it as it's a fix of a crash with an interface change though? I asked for the .. versionchanged:: stuff, but if we backport it, it will render as "3.14" for the 3.14 branch instead of 3.14.6 I think. I'm ok for the 3.15 backport at least.

@vstinner
Copy link
Copy Markdown
Member

vstinner commented Jun 2, 2026

Should we backport it as it's a fix of a crash with an interface change though?

IMO it's acceptable to backport the change. There is no reason to remove these attributes. If you remove them, sqlite does crash...

I asked for the .. versionchanged:: stuff, but if we backport it, it will render as "3.14" for the 3.14 branch instead of 3.14.6 I think. I'm ok for the 3.15 backport at least.

I expect that "next" will be rendered as "3.14.6" in the 3.14 branch.

@vstinner vstinner merged commit 60fdb31 into python:main Jun 2, 2026
55 checks passed
@miss-islington-app
Copy link
Copy Markdown

Thanks @sepehr-rs for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15.
🐍🍒⛏🤖

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jun 2, 2026

GH-150768 is a backport of this pull request to the 3.15 branch.

@miss-islington-app
Copy link
Copy Markdown

Sorry, @sepehr-rs and @vstinner, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 60fdb3192b897168ec0418fb0ea6c8d2d49ea513 3.13

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Jun 2, 2026
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jun 2, 2026

GH-150769 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Jun 2, 2026
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jun 2, 2026

GH-150770 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 bugs and security fixes label Jun 2, 2026
@vstinner
Copy link
Copy Markdown
Member

vstinner commented Jun 2, 2026

Merged, thanks for the fix @sepehr-rs. I prefer disallowing to remove attributes rather than checking if attributes are set to NULL.

vstinner pushed a commit that referenced this pull request Jun 2, 2026
…150768)

gh-149738: Fix segmentation fault bug in sqllite3 (GH-149754)

Deleting the `row_factory` or `text_factory` attribute is no longer allowed.
(cherry picked from commit 60fdb31)

Co-authored-by: Sepehr Rasouli <sepehrrasouli06@gmail.com>
@sepehr-rs
Copy link
Copy Markdown
Contributor Author

Thanks everyone for the reviews and feedback!

vstinner pushed a commit that referenced this pull request Jun 2, 2026
…150769)

gh-149738: Fix segmentation fault bug in sqllite3 (GH-149754)

Deleting the `row_factory` or `text_factory` attribute is no longer allowed.
(cherry picked from commit 60fdb31)

Co-authored-by: Sepehr Rasouli <sepehrrasouli06@gmail.com>
vstinner added a commit that referenced this pull request Jun 2, 2026
…150770)

gh-149738: Fix segmentation fault bug in sqllite3 (#149754)

Deleting the `row_factory` or `text_factory` attribute is no longer allowed.

(cherry picked from commit 60fdb31)

Co-authored-by: Sepehr Rasouli <sepehrrasouli06@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deleting sqlite3 row_factory causes segfault

3 participants