Description
Bug report
Bug description:
A small inconsistency in behavior between pickle
and _pickle
exists for the ADDITEMS
and APPENDS
opcodes. Both opcodes are meant to add items to a set or list by popping off all objects delimited by the MARK
object. Then, an add()
/extend()
/append()
attribute function is called to add the new items to the object.
In the C accelerator, the number of items to be added is explicitly checked in both opcodes, and if it's 0 it returns early.
Lines 6638 to 6639 in f079979
Lines 6494 to 6495 in f079979
However in the Python version, there is no check for 0 items.
Lines 1818 to 1826 in f079979
Lines 1785 to 1800 in f079979
This normally wouldn't cause any inconsistencies unless the item on the top of the stack (ie the list or set being appended to) isn't actually a list or set. For example, if we put an integer on the stack instead of a list and used the APPENDS
opcode to add 0 items, it will error in pickle
since the integer doesn't have an append()
attribute, but it will just return in _pickle
due to the check.
The following payloads demonstrate the inconsistencies:
payload: b'K\x01(e.'
pickle: FAILURE 'int' object has no attribute 'append'
_pickle.c: 1
pickletools:
0: K BININT1 1
2: ( MARK
3: e APPENDS (MARK at 2)
4: . STOP
highest protocol among opcodes = 1
payload: b'K\x01(\x90.'
pickle: FAILURE 'int' object has no attribute 'add'
_pickle.c: 1
pickletools:
0: K BININT1 1
2: ( MARK
3: \x90 ADDITEMS (MARK at 2)
4: . STOP
highest protocol among opcodes = 4
This can be easily mitigated by adding the same check for 0 items to the Python version of the pickle
module for both opcodes.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
Metadata
Metadata
Assignees
Projects
Status