diff options
author | Erlend Egeberg Aasland <erlend.aasland@protonmail.com> | 2022-05-05 19:46:21 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-05 19:46:21 (GMT) |
commit | 2a2421e538f9f7ceb419074909a313ba2c46f384 (patch) | |
tree | cc3ef5bd63bb13083f5520b592b0ba37fd495341 /Lib/sqlite3 | |
parent | 9b47252d5433894c26fc07aa87b1bd6bb4238e5e (diff) | |
download | cpython-2a2421e538f9f7ceb419074909a313ba2c46f384.zip cpython-2a2421e538f9f7ceb419074909a313ba2c46f384.tar.gz cpython-2a2421e538f9f7ceb419074909a313ba2c46f384.tar.bz2 |
[3.10] gh-80254: Disallow recursive usage of cursors in `sqlite3` converters (#92274)
* [3.10] gh-80254: Disallow recursive usage of cursors in `sqlite3` converters (#29054)
(cherry picked from commit f629dcfe835e349433e4c5099381d668e8fe69c8)
Co-authored-by: Sergey Fedoseev <fedoseev.sergey@gmail.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
* Fix ref leak in pysqlite_cursor_iternext
Diffstat (limited to 'Lib/sqlite3')
-rw-r--r-- | Lib/sqlite3/test/regression.py | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index 70d0ff9..8937f9f 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -27,6 +27,9 @@ import weakref import functools from test import support +from unittest.mock import patch + + class RegressionTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") @@ -415,9 +418,46 @@ class RegressionTests(unittest.TestCase): self.assertEqual(val, b'') +class RecursiveUseOfCursors(unittest.TestCase): + # GH-80254: sqlite3 should not segfault for recursive use of cursors. + msg = "Recursive use of cursors not allowed" + + def setUp(self): + self.con = sqlite.connect(":memory:", + detect_types=sqlite.PARSE_COLNAMES) + self.cur = self.con.cursor() + self.cur.execute("create table test(x foo)") + self.cur.executemany("insert into test(x) values (?)", + [("foo",), ("bar",)]) + + def tearDown(self): + self.cur.close() + self.con.close() + + def test_recursive_cursor_init(self): + conv = lambda x: self.cur.__init__(self.con) + with patch.dict(sqlite.converters, {"INIT": conv}): + with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg): + self.cur.execute(f'select x as "x [INIT]", x from test') + + def test_recursive_cursor_close(self): + conv = lambda x: self.cur.close() + with patch.dict(sqlite.converters, {"CLOSE": conv}): + with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg): + self.cur.execute(f'select x as "x [CLOSE]", x from test') + + def test_recursive_cursor_fetch(self): + conv = lambda x, l=[]: self.cur.fetchone() if l else l.append(None) + with patch.dict(sqlite.converters, {"ITER": conv}): + self.cur.execute(f'select x as "x [ITER]", x from test') + with self.assertRaisesRegex(sqlite.ProgrammingError, self.msg): + self.cur.fetchall() + + def suite(): tests = [ - RegressionTests + RegressionTests, + RecursiveUseOfCursors, ] return unittest.TestSuite( [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests] |