File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1156,16 +1156,22 @@ def load_long_binget(self):
11561156
11571157 def load_put (self ):
11581158 i = int (self .readline ()[:- 1 ])
1159+ if i < 0 :
1160+ raise ValueError ("negative PUT argument" )
11591161 self .memo [i ] = self .stack [- 1 ]
11601162 dispatch [PUT [0 ]] = load_put
11611163
11621164 def load_binput (self ):
11631165 i = self .read (1 )[0 ]
1166+ if i < 0 :
1167+ raise ValueError ("negative BINPUT argument" )
11641168 self .memo [i ] = self .stack [- 1 ]
11651169 dispatch [BINPUT [0 ]] = load_binput
11661170
11671171 def load_long_binput (self ):
11681172 i = mloads (b'i' + self .read (4 ))
1173+ if i < 0 :
1174+ raise ValueError ("negative LONG_BINPUT argument" )
11691175 self .memo [i ] = self .stack [- 1 ]
11701176 dispatch [LONG_BINPUT [0 ]] = load_long_binput
11711177
Original file line number Diff line number Diff line change @@ -1121,6 +1121,18 @@ def test_negative_32b_binunicode(self):
11211121 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
11221122 self .check_negative_32b_binXXX (b'\x80 \x03 X\xff \xff \xff \xff xyzq\x00 .' )
11231123
1124+ def test_negative_put (self ):
1125+ # Issue #12847
1126+ dumped = b'Va\n p-1\n .'
1127+ self .assertRaises (ValueError , self .loads , dumped )
1128+
1129+ def test_negative_32b_binput (self ):
1130+ # Issue #12847
1131+ if sys .maxsize > 2 ** 32 :
1132+ self .skipTest ("test is only meaningful on 32-bit builds" )
1133+ dumped = b'\x80 \x03 X\x01 \x00 \x00 \x00 ar\xff \xff \xff \xff .'
1134+ self .assertRaises (ValueError , self .loads , dumped )
1135+
11241136
11251137class BigmemPickleTests (unittest .TestCase ):
11261138
Original file line number Diff line number Diff line change @@ -22,6 +22,9 @@ Core and Builtins
2222Library
2323-------
2424
25+ - Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in
26+ the C pickle implementation.
27+
2528- Issue #11564: Avoid crashes when trying to pickle huge objects or containers
2629 (more than 2**31 items). Instead, in most cases, an OverflowError is raised.
2730
Original file line number Diff line number Diff line change @@ -4853,8 +4853,12 @@ load_put(UnpicklerObject *self)
48534853 return -1 ;
48544854 idx = PyLong_AsSsize_t (key );
48554855 Py_DECREF (key );
4856- if (idx == -1 && PyErr_Occurred ())
4856+ if (idx < 0 ) {
4857+ if (!PyErr_Occurred ())
4858+ PyErr_SetString (PyExc_ValueError ,
4859+ "negative PUT argument" );
48574860 return -1 ;
4861+ }
48584862
48594863 return _Unpickler_MemoPut (self , idx , value );
48604864}
@@ -4893,6 +4897,11 @@ load_long_binput(UnpicklerObject *self)
48934897 value = self -> stack -> data [Py_SIZE (self -> stack ) - 1 ];
48944898
48954899 idx = calc_binsize (s , 4 );
4900+ if (idx < 0 ) {
4901+ PyErr_SetString (PyExc_ValueError ,
4902+ "negative LONG_BINPUT argument" );
4903+ return -1 ;
4904+ }
48964905
48974906 return _Unpickler_MemoPut (self , idx , value );
48984907}
You can’t perform that action at this time.
0 commit comments