Skip to content

Commit ca85362

Browse files
committed
gh-141749 fix pure python pickle.py error handling
This fix addresses error handling inconsistencies in CPython's pure Python `pickle.py` implementation to match the behavior of the C `_pickle` module. The changes make the pure Python implementation raise proper `UnpicklingError` exceptions for invalid pickle data instead of low-level `KeyError` and `IndexError` exceptions.
1 parent 14cbd0e commit ca85362

File tree

3 files changed

+12
-2
lines changed

3 files changed

+12
-2
lines changed

Lib/pickle.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1349,12 +1349,19 @@ def load(self):
13491349
if not key:
13501350
raise EOFError
13511351
assert isinstance(key, bytes_types)
1352-
dispatch[key[0]](self)
1352+
try:
1353+
func = dispatch[key[0]]
1354+
except KeyError:
1355+
raise UnpicklingError(
1356+
f"invalid load key, '\\x{key[0]:02x}'.")
1357+
func(self)
13531358
except _Stop as stopinst:
13541359
return stopinst.value
13551360

13561361
# Return a list of items pushed in the stack after last MARK instruction.
13571362
def pop_mark(self):
1363+
if not self.metastack:
1364+
raise UnpicklingError("could not find MARK")
13581365
items = self.stack
13591366
self.stack = self.metastack.pop()
13601367
self.append = self.stack.append

Lib/test/test_pickle.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class PyPickleTests(AbstractPickleModuleTests, unittest.TestCase):
5555
class PyUnpicklerTests(AbstractUnpickleTests, unittest.TestCase):
5656

5757
unpickler = pickle._Unpickler
58-
bad_stack_errors = (IndexError,)
58+
bad_stack_errors = (pickle.UnpicklingError, IndexError)
5959
truncated_errors = (pickle.UnpicklingError, EOFError,
6060
AttributeError, ValueError,
6161
struct.error, IndexError, ImportError)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:mod:`pickle`: align exceptions raised by the pure Python implementation of :func:`pickle.load`
2+
with the C implementation. Previous cases raising :exc:`KeyError` or :exc:`IndexError`
3+
now raise :exc:`~pickle.UnpicklingError`. Patch by Djoume Salvetti.

0 commit comments

Comments
 (0)