summaryrefslogtreecommitdiffstats
path: root/Lib/sqlite3
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@protonmail.com>2022-05-05 19:46:21 (GMT)
committerGitHub <noreply@github.com>2022-05-05 19:46:21 (GMT)
commit2a2421e538f9f7ceb419074909a313ba2c46f384 (patch)
treecc3ef5bd63bb13083f5520b592b0ba37fd495341 /Lib/sqlite3
parent9b47252d5433894c26fc07aa87b1bd6bb4238e5e (diff)
downloadcpython-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.py42
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]