diff options
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r-- | Lib/pickle.py | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py index 6c1bcbeae5..128a62742a 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -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)) |