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
SystemError in cPickle for incorrect input #61910
Comments
>>> import cPickle
>>> cPickle.loads(b"S' \np0\n.")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: Negative size passed to PyString_FromStringAndSize
>>> pickle.loads(b"S' \np0\n.")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/serhiy/py/cpython2.7/Lib/pickle.py", line 1382, in loads
return Unpickler(file).load()
File "/home/serhiy/py/cpython2.7/Lib/pickle.py", line 858, in load
dispatch[key](self)
File "/home/serhiy/py/cpython2.7/Lib/pickle.py", line 966, in load_string
raise ValueError, "insecure string pickle"
ValueError: insecure string pickle
>>> cPickle.loads(b"S'\np0\n.")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: Negative size passed to PyString_FromStringAndSize
>>> pickle.loads(b"S'\np0\n.")
'' Python 3 has the same behavior except C implementation raises UnpicklingError for b"S'\np0\n.". |
Here is a patch for 2.7. |
I don't think the UnpicklingError in 3.x is a bug, though: it's just a different exception than ValueError. It's just a shame that the two are used interchangeably for the same purpose. |
Hmm, forget what I just said. A SystemError can actually be triggered through a slightly longer line: $ ./python -c "import pickle; print (repr(pickle.loads(b\"S' \np0\n.\")))"
Traceback (most recent call last):
File "<string>", line 1, in <module>
SystemError: Negative size passed to PyBytes_FromStringAndSize |
And here is a 3.x patch. |
Of course, UnpicklingError is not a bug. Perhaps almost any exception except SystemError is not a bug. I mention it because it's a case where Python 3 differs from Python 2. I think _pickle.c patches can be simplified. + if (len < 2)
+ goto insecure;
if (s[0] == '"' && s[len - 1] == '"') { |
I also wrote a patch for this. I took I slightly different approach though. I fixed the C implementation to be more strict on the quoting. Currently, it strips trailing non-printable characters, something pickle.py doesn't do. I also cleaned up the tests to check this behavior. |
Alexandre, I don't like your patch very much:
|
I was targeting head, not the release branches. It is fine to change the exception there as we don't make any guarantee about the exceptions raised during the unpickling process. It is easy enough to fix patch use ValueError for the release branch. And adding guards is unnecessary after the removing the code for stripping trailing whitespace. Here's slightly updated patch that check if readline() reached an EOF instead of a newline. |
Perhaps, but I don't see the point of choosing a different fix in the default branch than in the bugfix branches. |
New changeset 527b7f88b53c by Antoine Pitrou in branch '2.7': |
New changeset 4e412cbaaf96 by Antoine Pitrou in branch '3.3': New changeset 5a16d2992112 by Antoine Pitrou in branch 'default': |
I've committed the patches. Feel free to improve the default branch if you like. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: