diff options
author | 2018-12-05 23:09:56 +0200 | |
---|---|---|
committer | 2018-12-05 23:09:56 +0200 | |
commit | 1de91a0032fed500ddd3d8c4fb7a38c0b8719f67 (patch) | |
tree | b9462a1a5e594b9eda43e7ee485dc3099b1fb2bf /Lib | |
parent | bpo-34738: Add directory entries in ZIP files created by distutils. (GH-9419) (diff) | |
download | cpython-1de91a0032fed500ddd3d8c4fb7a38c0b8719f67.tar.gz cpython-1de91a0032fed500ddd3d8c4fb7a38c0b8719f67.tar.bz2 cpython-1de91a0032fed500ddd3d8c4fb7a38c0b8719f67.zip |
bpo-34052: Prevent SQLite functions from setting callbacks on exceptions. (GH-8113). (GH-10946)
(cherry picked from commit 5b25f1d03100e2283c1b129d461ba68ac0169a14)
Co-authored-by: Sergey Fedoseev <fedoseev.sergey@gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/sqlite3/test/regression.py | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index 34cd233535d..1c59a3cd31c 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -256,24 +256,6 @@ class RegressionTests(unittest.TestCase): cur.execute("pragma page_size") row = cur.fetchone() - def CheckSetDict(self): - """ - See http://bugs.python.org/issue7478 - - It was possible to successfully register callbacks that could not be - hashed. Return codes of PyDict_SetItem were not checked properly. - """ - class NotHashable: - def __call__(self, *args, **kw): - pass - def __hash__(self): - raise TypeError() - var = NotHashable() - self.assertRaises(TypeError, self.con.create_function, var) - self.assertRaises(TypeError, self.con.create_aggregate, var) - self.assertRaises(TypeError, self.con.set_authorizer, var) - self.assertRaises(TypeError, self.con.set_progress_handler, var) - def CheckConnectionCall(self): """ Call a connection with a non-string SQL request: check error handling @@ -398,9 +380,72 @@ class RegressionTests(unittest.TestCase): support.gc_collect() +class UnhashableFunc: + __hash__ = None + + def __init__(self, return_value=None): + self.calls = 0 + self.return_value = return_value + + def __call__(self, *args, **kwargs): + self.calls += 1 + return self.return_value + + +class UnhashableCallbacksTestCase(unittest.TestCase): + """ + https://bugs.python.org/issue34052 + + Registering unhashable callbacks raises TypeError, callbacks are not + registered in SQLite after such registration attempt. + """ + def setUp(self): + self.con = sqlite.connect(':memory:') + + def tearDown(self): + self.con.close() + + def test_progress_handler(self): + f = UnhashableFunc(return_value=0) + with self.assertRaisesRegex(TypeError, 'unhashable type'): + self.con.set_progress_handler(f, 1) + self.con.execute('SELECT 1') + self.assertFalse(f.calls) + + def test_func(self): + func_name = 'func_name' + f = UnhashableFunc() + with self.assertRaisesRegex(TypeError, 'unhashable type'): + self.con.create_function(func_name, 0, f) + msg = 'no such function: %s' % func_name + with self.assertRaisesRegex(sqlite.OperationalError, msg): + self.con.execute('SELECT %s()' % func_name) + self.assertFalse(f.calls) + + def test_authorizer(self): + f = UnhashableFunc(return_value=sqlite.SQLITE_DENY) + with self.assertRaisesRegex(TypeError, 'unhashable type'): + self.con.set_authorizer(f) + self.con.execute('SELECT 1') + self.assertFalse(f.calls) + + def test_aggr(self): + class UnhashableType(type): + __hash__ = None + aggr_name = 'aggr_name' + with self.assertRaisesRegex(TypeError, 'unhashable type'): + self.con.create_aggregate(aggr_name, 0, UnhashableType('Aggr', (), {})) + msg = 'no such function: %s' % aggr_name + with self.assertRaisesRegex(sqlite.OperationalError, msg): + self.con.execute('SELECT %s()' % aggr_name) + + def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") - return unittest.TestSuite((regression_suite,)) + return unittest.TestSuite(( + regression_suite, + unittest.makeSuite(UnhashableCallbacksTestCase), + )) def test(): runner = unittest.TextTestRunner() |