-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
gh-135321: Changing data type of size
variable for BINSTRING
in _pickle
#135322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
gh-135321: Changing data type of size
variable for BINSTRING
in _pickle
#135322
Conversation
…opcode `BINSTRING` to `int` from `Py_ssize_t`
size
variable for C implementation of pickle …size
variable for BINSTRING
in _pickle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bug was introduced in bpo-17810/gh-62010. The code should use calc_binsize()
instead of calc_binsize()
.
And it is worth to add a test:
diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
index 9d6ae3e4d00..2a85e31078c 100644
--- a/Lib/test/pickletester.py
+++ b/Lib/test/pickletester.py
@@ -1100,6 +1100,11 @@ def test_large_32b_binunicode8(self):
self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
dumped)
+ def test_large_binstring(self):
+ errmsg = 'UnpicklingError: BINSTRING pickle has negative byte count'
+ with self.assertRaisesRegex(pickle.UnpicklingError, errmsg):
+ self.loads(b'T\0\0\0\x80')
+
def test_get(self):
pickled = b'((lp100000\ng100000\nt.'
unpickled = self.loads(pickled)
@@ -5543,17 +5543,16 @@ static int | |||
load_counted_binstring(PickleState *st, UnpicklerObject *self, int nbytes) | |||
{ | |||
PyObject *obj; | |||
Py_ssize_t size; | |||
int size; | |||
char *s; | |||
|
|||
if (_Unpickler_Read(self, st, &s, nbytes) < 0) | |||
return -1; | |||
|
|||
size = calc_binsize(s, nbytes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
size = calc_binsize(s, nbytes); | |
size = calc_binint(s, nbytes); |
@@ -5543,17 +5543,16 @@ static int | |||
load_counted_binstring(PickleState *st, UnpicklerObject *self, int nbytes) | |||
{ | |||
PyObject *obj; | |||
Py_ssize_t size; | |||
int size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int size; | |
long size; |
@@ -0,0 +1 @@ | |||
The ``BINSTRING`` opcode of the C accelerator implementation of :mod:`pickle` was modified to have a signed 32-bit data type instead of 64-bit, keeping in line with the Python implementation of :mod:`pickle` and :mod:`pickletools`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It describes the code, not what the user will see. It is also not correctly describes the issue.
Something like the following would be better:
The ``BINSTRING`` opcode of the C accelerator implementation of :mod:`pickle` was modified to have a signed 32-bit data type instead of 64-bit, keeping in line with the Python implementation of :mod:`pickle` and :mod:`pickletools`. | |
Raise a correct exception for values greater than 0x7ffffff for the ``BINSTRING`` opcode in the C implementation of :mod:`pickle`. |
I changed the data type to
int
fromPy_ssize_t
for thesize
variable. This variable is also used as an argument to 3 other functions but should be auto-casted (similar toload_counted_long
). I also changed the error message to match the error message in the Pythonload_binstring()
function.I would like to add tests for this specific case, but the payload that would show whether or not it works as intended requires a 2GB large pickle, and I'm not sure if you'd like that to be in the tests. Let me know what you think.
BINSTRING
incorrect data type for size #135321