Skip to content

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Legoclones
Copy link
Contributor

@Legoclones Legoclones commented Jun 10, 2025

I changed the data type to int from Py_ssize_t for the size variable. This variable is also used as an argument to 3 other functions but should be auto-casted (similar to load_counted_long). I also changed the error message to match the error message in the Python load_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.

…opcode `BINSTRING` to `int` from `Py_ssize_t`
@Legoclones Legoclones changed the title gh-135321: Changing data type of size variable for C implementation of pickle … gh-135321: Changing data type of size variable for BINSTRING in _pickle Jun 10, 2025
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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`.
Copy link
Member

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:

Suggested change
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`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants