@@ -263,7 +263,7 @@ def put(self, i, pack=struct.pack):
263263 if i < 256 :
264264 return BINPUT + bytes ([i ])
265265 else :
266- return LONG_BINPUT + pack ("<i " , i )
266+ return LONG_BINPUT + pack ("<I " , i )
267267
268268 return PUT + repr (i ).encode ("ascii" ) + b'\n '
269269
@@ -273,7 +273,7 @@ def get(self, i, pack=struct.pack):
273273 if i < 256 :
274274 return BINGET + bytes ([i ])
275275 else :
276- return LONG_BINGET + pack ("<i " , i )
276+ return LONG_BINGET + pack ("<I " , i )
277277
278278 return GET + repr (i ).encode ("ascii" ) + b'\n '
279279
@@ -503,15 +503,15 @@ def save_bytes(self, obj, pack=struct.pack):
503503 if n < 256 :
504504 self .write (SHORT_BINBYTES + bytes ([n ]) + bytes (obj ))
505505 else :
506- self .write (BINBYTES + pack ("<i " , n ) + bytes (obj ))
506+ self .write (BINBYTES + pack ("<I " , n ) + bytes (obj ))
507507 self .memoize (obj )
508508 dispatch [bytes ] = save_bytes
509509
510510 def save_str (self , obj , pack = struct .pack ):
511511 if self .bin :
512512 encoded = obj .encode ('utf-8' , 'surrogatepass' )
513513 n = len (encoded )
514- self .write (BINUNICODE + pack ("<i " , n ) + encoded )
514+ self .write (BINUNICODE + pack ("<I " , n ) + encoded )
515515 else :
516516 obj = obj .replace ("\\ " , "\\ u005c" )
517517 obj = obj .replace ("\n " , "\\ u000a" )
@@ -931,6 +931,9 @@ def load_long1(self):
931931
932932 def load_long4 (self ):
933933 n = mloads (b'i' + self .read (4 ))
934+ if n < 0 :
935+ # Corrupt or hostile pickle -- we never write one like this
936+ raise UnpicklingError ("LONG pickle has negative byte count" );
934937 data = self .read (n )
935938 self .append (decode_long (data ))
936939 dispatch [LONG4 [0 ]] = load_long4
@@ -959,23 +962,30 @@ def load_string(self):
959962 dispatch [STRING [0 ]] = load_string
960963
961964 def load_binstring (self ):
965+ # Deprecated BINSTRING uses signed 32-bit length
962966 len = mloads (b'i' + self .read (4 ))
967+ if len < 0 :
968+ raise UnpicklingError ("BINSTRING pickle has negative byte count" );
963969 data = self .read (len )
964970 value = str (data , self .encoding , self .errors )
965971 self .append (value )
966972 dispatch [BINSTRING [0 ]] = load_binstring
967973
968- def load_binbytes (self ):
969- len = mloads (b'i' + self .read (4 ))
974+ def load_binbytes (self , unpack = struct .unpack , maxsize = sys .maxsize ):
975+ len , = unpack ('<I' , self .read (4 ))
976+ if len > maxsize :
977+ raise UnpicklingError ("BINBYTES exceeds system's maximum size of %d bytes" % maxsize );
970978 self .append (self .read (len ))
971979 dispatch [BINBYTES [0 ]] = load_binbytes
972980
973981 def load_unicode (self ):
974982 self .append (str (self .readline ()[:- 1 ], 'raw-unicode-escape' ))
975983 dispatch [UNICODE [0 ]] = load_unicode
976984
977- def load_binunicode (self ):
978- len = mloads (b'i' + self .read (4 ))
985+ def load_binunicode (self , unpack = struct .unpack , maxsize = sys .maxsize ):
986+ len , = unpack ('<I' , self .read (4 ))
987+ if len > maxsize :
988+ raise UnpicklingError ("BINUNICODE exceeds system's maximum size of %d bytes" % maxsize );
979989 self .append (str (self .read (len ), 'utf-8' , 'surrogatepass' ))
980990 dispatch [BINUNICODE [0 ]] = load_binunicode
981991
@@ -1106,6 +1116,9 @@ def get_extension(self, code):
11061116 return
11071117 key = _inverted_registry .get (code )
11081118 if not key :
1119+ if code <= 0 : # note that 0 is forbidden
1120+ # Corrupt or hostile pickle.
1121+ raise UnpicklingError ("EXT specifies code <= 0" );
11091122 raise ValueError ("unregistered extension code %d" % code )
11101123 obj = self .find_class (* key )
11111124 _extension_cache [code ] = obj
@@ -1159,8 +1172,8 @@ def load_binget(self):
11591172 self .append (self .memo [i ])
11601173 dispatch [BINGET [0 ]] = load_binget
11611174
1162- def load_long_binget (self ):
1163- i = mloads ( b'i' + self .read (4 ))
1175+ def load_long_binget (self , unpack = struct . unpack ):
1176+ i , = unpack ( '<I' , self .read (4 ))
11641177 self .append (self .memo [i ])
11651178 dispatch [LONG_BINGET [0 ]] = load_long_binget
11661179
@@ -1178,9 +1191,9 @@ def load_binput(self):
11781191 self .memo [i ] = self .stack [- 1 ]
11791192 dispatch [BINPUT [0 ]] = load_binput
11801193
1181- def load_long_binput (self ):
1182- i = mloads ( b'i' + self .read (4 ))
1183- if i < 0 :
1194+ def load_long_binput (self , unpack = struct . unpack , maxsize = sys . maxsize ):
1195+ i , = unpack ( '<I' , self .read (4 ))
1196+ if i > maxsize :
11841197 raise ValueError ("negative LONG_BINPUT argument" )
11851198 self .memo [i ] = self .stack [- 1 ]
11861199 dispatch [LONG_BINPUT [0 ]] = load_long_binput
0 commit comments