mirror of
https://github.com/python/cpython.git
synced 2025-08-09 19:38:42 +00:00
[3.12] gh-123431: Harmonize extension code checks in pickle (GH-123434) (#123460)
This checks are redundant in normal circumstances and can only work if
the extension registry was intentionally broken.
(cherry picked from commit 0c3ea30238
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
10adcb4a2b
commit
58e01a1c7f
3 changed files with 72 additions and 23 deletions
|
@ -1297,6 +1297,35 @@ class AbstractUnpickleTests:
|
|||
self.assertEqual(loads(b'cmath\nlog\n.'), ('math', 'log'))
|
||||
self.assertEqual(loads(b'\x8c\x04math\x8c\x03log\x93.'), ('math', 'log'))
|
||||
|
||||
def test_bad_ext_code(self):
|
||||
# unregistered extension code
|
||||
self.check_unpickling_error(ValueError, b'\x82\x01.')
|
||||
self.check_unpickling_error(ValueError, b'\x82\xff.')
|
||||
self.check_unpickling_error(ValueError, b'\x83\x01\x00.')
|
||||
self.check_unpickling_error(ValueError, b'\x83\xff\xff.')
|
||||
self.check_unpickling_error(ValueError, b'\x84\x01\x00\x00\x00.')
|
||||
self.check_unpickling_error(ValueError, b'\x84\xff\xff\xff\x7f.')
|
||||
# EXT specifies code <= 0
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'\x82\x00.')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'\x83\x00\x00.')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'\x84\x00\x00\x00\x00.')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'\x84\x00\x00\x00\x80.')
|
||||
self.check_unpickling_error(pickle.UnpicklingError, b'\x84\xff\xff\xff\xff.')
|
||||
|
||||
@support.cpython_only
|
||||
def test_bad_ext_inverted_registry(self):
|
||||
code = 1
|
||||
def check(key, exc):
|
||||
with support.swap_item(copyreg._inverted_registry, code, key):
|
||||
with self.assertRaises(exc):
|
||||
self.loads(b'\x82\x01.')
|
||||
check(None, ValueError)
|
||||
check((), ValueError)
|
||||
check((__name__,), (TypeError, ValueError))
|
||||
check((__name__, "MyList", "x"), (TypeError, ValueError))
|
||||
check((__name__, None), (TypeError, ValueError))
|
||||
check((None, "MyList"), (TypeError, ValueError))
|
||||
|
||||
def test_bad_reduce(self):
|
||||
self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0)
|
||||
self.check_unpickling_error(TypeError, b'N)R.')
|
||||
|
@ -2033,6 +2062,28 @@ class AbstractPicklingErrorTests:
|
|||
check({Clearer(): 1, Clearer(): 2})
|
||||
check({1: Clearer(), 2: Clearer()})
|
||||
|
||||
@support.cpython_only
|
||||
def test_bad_ext_code(self):
|
||||
# This should never happen in normal circumstances, because the type
|
||||
# and the value of the extesion code is checked in copyreg.add_extension().
|
||||
key = (__name__, 'MyList')
|
||||
def check(code, exc):
|
||||
assert key not in copyreg._extension_registry
|
||||
assert code not in copyreg._inverted_registry
|
||||
with (support.swap_item(copyreg._extension_registry, key, code),
|
||||
support.swap_item(copyreg._inverted_registry, code, key)):
|
||||
for proto in protocols[2:]:
|
||||
with self.assertRaises(exc):
|
||||
self.dumps(MyList, proto)
|
||||
|
||||
check(object(), TypeError)
|
||||
check(None, TypeError)
|
||||
check(-1, (RuntimeError, struct.error))
|
||||
check(0, RuntimeError)
|
||||
check(2**31, (RuntimeError, OverflowError, struct.error))
|
||||
check(2**1000, (OverflowError, struct.error))
|
||||
check(-2**1000, (OverflowError, struct.error))
|
||||
|
||||
|
||||
class AbstractPickleTests:
|
||||
# Subclass must define self.dumps, self.loads.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue