mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Fix Bug #114293:
Strings are unpickled by calling eval on the string's repr. This change makes pickle work like cPickle; it checks if the pickled string is safe to eval and raises ValueError if it is not. test suite modifications: Verify that pickle catches a variety of insecure string pickles Make test_pickle and test_cpickle use exactly the same test suite Add test for pickling recursive object
This commit is contained in:
parent
a647f577f0
commit
be467e5c69
5 changed files with 131 additions and 112 deletions
|
@ -577,10 +577,50 @@ class Unpickler:
|
|||
dispatch[BINFLOAT] = load_binfloat
|
||||
|
||||
def load_string(self):
|
||||
self.append(eval(self.readline()[:-1],
|
||||
rep = self.readline()[:-1]
|
||||
if not self._is_string_secure(rep):
|
||||
raise ValueError, "insecure string pickle"
|
||||
self.append(eval(rep,
|
||||
{'__builtins__': {}})) # Let's be careful
|
||||
dispatch[STRING] = load_string
|
||||
|
||||
def _is_string_secure(self, s):
|
||||
"""Return true if s contains a string that is safe to eval
|
||||
|
||||
The definition of secure string is based on the implementation
|
||||
in cPickle. s is secure as long as it only contains a quoted
|
||||
string and optional trailing whitespace.
|
||||
"""
|
||||
q = s[0]
|
||||
if q not in ("'", '"'):
|
||||
return 0
|
||||
# find the closing quote
|
||||
offset = 1
|
||||
i = None
|
||||
while 1:
|
||||
try:
|
||||
i = s.index(q, offset)
|
||||
except ValueError:
|
||||
# if there is an error the first time, there is no
|
||||
# close quote
|
||||
if offset == 1:
|
||||
return 0
|
||||
if s[i-1] != '\\':
|
||||
break
|
||||
# check to see if this one is escaped
|
||||
nslash = 0
|
||||
j = i - 1
|
||||
while j >= offset and s[j] == '\\':
|
||||
j = j - 1
|
||||
nslash = nslash + 1
|
||||
if nslash % 2 == 0:
|
||||
break
|
||||
offset = i + 1
|
||||
for c in s[i+1:]:
|
||||
if ord(c) > 32:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def load_binstring(self):
|
||||
len = mloads('i' + self.read(4))
|
||||
self.append(self.read(len))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue