1111import weakref
1212from http .cookies import SimpleCookie
1313
14+ from test import support
1415from test .support import (
15- TestFailed , TESTFN , run_with_locale , no_tracing , captured_stdout ,
16+ TestFailed , TESTFN , run_with_locale , no_tracing ,
1617 _2G , _4G , bigmemtest ,
1718 )
1819
@@ -679,6 +680,17 @@ def assert_is_copy(self, obj, objcopy, msg=None):
679680 self .assertEqual (getattr (obj , slot , None ),
680681 getattr (objcopy , slot , None ), msg = msg )
681682
683+ def check_unpickling_error (self , errors , data ):
684+ with self .subTest (data = data ), \
685+ self .assertRaises (errors ):
686+ try :
687+ self .loads (data )
688+ except BaseException as exc :
689+ if support .verbose > 1 :
690+ print ('%-32r - %s: %s' %
691+ (data , exc .__class__ .__name__ , exc ))
692+ raise
693+
682694 def test_load_from_data0 (self ):
683695 self .assert_is_copy (self ._testdata , self .loads (DATA0 ))
684696
@@ -759,12 +771,7 @@ def test_maxint64(self):
759771
760772 # Try too with a bogus literal.
761773 data = b'I' + str (maxint64 ).encode ("ascii" ) + b'JUNK\n .'
762- self .assertRaises (ValueError , self .loads , data )
763-
764- def test_pop_empty_stack (self ):
765- # Test issue7455
766- s = b'0'
767- self .assertRaises ((pickle .UnpicklingError , IndexError ), self .loads , s )
774+ self .check_unpickling_error (ValueError , data )
768775
769776 def test_unpickle_from_2x (self ):
770777 # Unpickle non-trivial data from Python 2.x.
@@ -849,22 +856,22 @@ def test_binbytes(self):
849856 def test_negative_32b_binbytes (self ):
850857 # On 32-bit builds, a BINBYTES of 2**31 or more is refused
851858 dumped = b'\x80 \x03 B\xff \xff \xff \xff xyzq\x00 .'
852- with self .assertRaises ((pickle .UnpicklingError , OverflowError )):
853- self . loads ( dumped )
859+ self .check_unpickling_error ((pickle .UnpicklingError , OverflowError ),
860+ dumped )
854861
855862 @requires_32b
856863 def test_negative_32b_binunicode (self ):
857864 # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
858865 dumped = b'\x80 \x03 X\xff \xff \xff \xff xyzq\x00 .'
859- with self .assertRaises ((pickle .UnpicklingError , OverflowError )):
860- self . loads ( dumped )
866+ self .check_unpickling_error ((pickle .UnpicklingError , OverflowError ),
867+ dumped )
861868
862869 def test_short_binunicode (self ):
863870 dumped = b'\x80 \x04 \x8c \x04 \xe2 \x82 \xac \x00 .'
864871 self .assertEqual (self .loads (dumped ), '\u20ac \x00 ' )
865872
866873 def test_misc_get (self ):
867- self .assertRaises (KeyError , self . loads , b'g0\n p0' )
874+ self .check_unpickling_error (KeyError , b'g0\n p0' )
868875 self .assert_is_copy ([(100 ,), (100 ,)],
869876 self .loads (b'((Kdtp0\n h\x00 l.))' ))
870877
@@ -879,14 +886,14 @@ def test_binunicode8(self):
879886 @requires_32b
880887 def test_large_32b_binbytes8 (self ):
881888 dumped = b'\x80 \x04 \x8e \4 \0 \0 \0 \1 \0 \0 \0 \xe2 \x82 \xac \x00 .'
882- with self .assertRaises ((pickle .UnpicklingError , OverflowError )):
883- self . loads ( dumped )
889+ self .check_unpickling_error ((pickle .UnpicklingError , OverflowError ),
890+ dumped )
884891
885892 @requires_32b
886893 def test_large_32b_binunicode8 (self ):
887894 dumped = b'\x80 \x04 \x8d \4 \0 \0 \0 \1 \0 \0 \0 \xe2 \x82 \xac \x00 .'
888- with self .assertRaises ((pickle .UnpicklingError , OverflowError )):
889- self . loads ( dumped )
895+ self .check_unpickling_error ((pickle .UnpicklingError , OverflowError ),
896+ dumped )
890897
891898 def test_get (self ):
892899 pickled = b'((lp100000\n g100000\n t.'
@@ -915,16 +922,16 @@ def test_dup(self):
915922 def test_negative_put (self ):
916923 # Issue #12847
917924 dumped = b'Va\n p-1\n .'
918- self .assertRaises (ValueError , self . loads , dumped )
925+ self .check_unpickling_error (ValueError , dumped )
919926
920927 @requires_32b
921928 def test_negative_32b_binput (self ):
922929 # Issue #12847
923930 dumped = b'\x80 \x03 X\x01 \x00 \x00 \x00 ar\xff \xff \xff \xff .'
924- self .assertRaises (ValueError , self . loads , dumped )
931+ self .check_unpickling_error (ValueError , dumped )
925932
926933 def test_badly_escaped_string (self ):
927- self .assertRaises (ValueError , self . loads , b"S'\\ '\n ." )
934+ self .check_unpickling_error (ValueError , b"S'\\ '\n ." )
928935
929936 def test_badly_quoted_string (self ):
930937 # Issue #17710
@@ -942,7 +949,7 @@ def test_badly_quoted_string(self):
942949 b'S\n .' ,
943950 b'S.' ]
944951 for p in badpickles :
945- self .assertRaises (pickle .UnpicklingError , self . loads , p )
952+ self .check_unpickling_error (pickle .UnpicklingError , p )
946953
947954 def test_correctly_quoted_string (self ):
948955 goodpickles = [(b"S''\n ." , '' ),
@@ -989,86 +996,183 @@ def test_compat_unpickle(self):
989996
990997 def test_bad_stack (self ):
991998 badpickles = [
992- b'0.' , # POP
993- b'1.' , # POP_MARK
994- b'2.' , # DUP
995- # b'(2.', # PyUnpickler doesn't raise
996- b'R.' , # REDUCE
997- b')R.' ,
998- b'a.' , # APPEND
999- b'Na.' ,
1000- b'b.' , # BUILD
1001- b'Nb.' ,
1002- b'd.' , # DICT
1003- b'e.' , # APPENDS
1004- # b'(e.', # PyUnpickler raises AttributeError
1005- b'ibuiltins\n list\n .' , # INST
1006- b'l.' , # LIST
1007- b'o.' , # OBJ
1008- b'(o.' ,
1009- b'p1\n .' , # PUT
1010- b'q\x00 .' , # BINPUT
1011- b'r\x00 \x00 \x00 \x00 .' , # LONG_BINPUT
1012- b's.' , # SETITEM
1013- b'Ns.' ,
1014- b'NNs.' ,
1015- b't.' , # TUPLE
1016- b'u.' , # SETITEMS
1017- b'(u.' ,
1018- b'}(Nu.' ,
1019- b'\x81 .' , # NEWOBJ
1020- b')\x81 .' ,
1021- b'\x85 .' , # TUPLE1
1022- b'\x86 .' , # TUPLE2
1023- b'N\x86 .' ,
1024- b'\x87 .' , # TUPLE3
1025- b'N\x87 .' ,
1026- b'NN\x87 .' ,
1027- b'\x90 .' , # ADDITEMS
1028- # b'(\x90.', # PyUnpickler raises AttributeError
1029- b'\x91 .' , # FROZENSET
1030- b'\x92 .' , # NEWOBJ_EX
1031- b')}\x92 .' ,
1032- b'\x93 .' , # STACK_GLOBAL
1033- b'Vlist\n \x93 .' ,
1034- b'\x94 .' , # MEMOIZE
999+ b'.' , # STOP
1000+ b'0' , # POP
1001+ b'1' , # POP_MARK
1002+ b'2' , # DUP
1003+ # b'(2', # PyUnpickler doesn't raise
1004+ b'R' , # REDUCE
1005+ b')R' ,
1006+ b'a' , # APPEND
1007+ b'Na' ,
1008+ b'b' , # BUILD
1009+ b'Nb' ,
1010+ b'd' , # DICT
1011+ b'e' , # APPENDS
1012+ # b'(e', # PyUnpickler raises AttributeError
1013+ b'ibuiltins\n list\n ' , # INST
1014+ b'l' , # LIST
1015+ b'o' , # OBJ
1016+ b'(o' ,
1017+ b'p1\n ' , # PUT
1018+ b'q\x00 ' , # BINPUT
1019+ b'r\x00 \x00 \x00 \x00 ' , # LONG_BINPUT
1020+ b's' , # SETITEM
1021+ b'Ns' ,
1022+ b'NNs' ,
1023+ b't' , # TUPLE
1024+ b'u' , # SETITEMS
1025+ # b'(u', # PyUnpickler doesn't raise
1026+ b'}(Nu' ,
1027+ b'\x81 ' , # NEWOBJ
1028+ b')\x81 ' ,
1029+ b'\x85 ' , # TUPLE1
1030+ b'\x86 ' , # TUPLE2
1031+ b'N\x86 ' ,
1032+ b'\x87 ' , # TUPLE3
1033+ b'N\x87 ' ,
1034+ b'NN\x87 ' ,
1035+ b'\x90 ' , # ADDITEMS
1036+ # b'(\x90', # PyUnpickler raises AttributeError
1037+ b'\x91 ' , # FROZENSET
1038+ b'\x92 ' , # NEWOBJ_EX
1039+ b')}\x92 ' ,
1040+ b'\x93 ' , # STACK_GLOBAL
1041+ b'Vlist\n \x93 ' ,
1042+ b'\x94 ' , # MEMOIZE
10351043 ]
10361044 for p in badpickles :
1037- with self .subTest (p ):
1038- self .assertRaises (self .bad_stack_errors , self .loads , p )
1045+ self .check_unpickling_error (self .bad_stack_errors , p )
10391046
10401047 def test_bad_mark (self ):
10411048 badpickles = [
1042- b'cbuiltins\n list\n )(R.' , # REDUCE
1043- b'cbuiltins\n list\n ()R.' ,
1044- b']N(a.' , # APPEND
1045- b'cbuiltins\n ValueError\n )R}(b.' , # BUILD
1046- b'cbuiltins\n ValueError\n )R(}b.' ,
1047- b'(Nd.' , # DICT
1048- b'}NN(s.' , # SETITEM
1049- b'}N(Ns.' ,
1050- b'cbuiltins\n list\n )(\x81 .' , # NEWOBJ
1051- b'cbuiltins\n list\n ()\x81 .' ,
1052- b'N(\x85 .' , # TUPLE1
1053- b'NN(\x86 .' , # TUPLE2
1054- b'N(N\x86 .' ,
1055- b'NNN(\x87 .' , # TUPLE3
1056- b'NN(N\x87 .' ,
1057- b'N(NN\x87 .' ,
1058- b'cbuiltins\n list\n )}(\x92 .' , # NEWOBJ_EX
1059- b'cbuiltins\n list\n )(}\x92 .' ,
1060- b'cbuiltins\n list\n ()}\x92 .' ,
1061- b'Vbuiltins\n (Vlist\n \x93 .' , # STACK_GLOBAL
1062- b'Vbuiltins\n Vlist\n (\x93 .' ,
1049+ # b'N(.', # STOP
1050+ b'N(2' , # DUP
1051+ b'cbuiltins\n list\n )(R' , # REDUCE
1052+ b'cbuiltins\n list\n ()R' ,
1053+ b']N(a' , # APPEND
1054+ # BUILD
1055+ b'cbuiltins\n ValueError\n )R}(b' ,
1056+ b'cbuiltins\n ValueError\n )R(}b' ,
1057+ b'(Nd' , # DICT
1058+ b'N(p1\n ' , # PUT
1059+ b'N(q\x00 ' , # BINPUT
1060+ b'N(r\x00 \x00 \x00 \x00 ' , # LONG_BINPUT
1061+ b'}NN(s' , # SETITEM
1062+ b'}N(Ns' ,
1063+ b'}(NNs' ,
1064+ b'}((u' , # SETITEMS
1065+ b'cbuiltins\n list\n )(\x81 ' , # NEWOBJ
1066+ b'cbuiltins\n list\n ()\x81 ' ,
1067+ b'N(\x85 ' , # TUPLE1
1068+ b'NN(\x86 ' , # TUPLE2
1069+ b'N(N\x86 ' ,
1070+ b'NNN(\x87 ' , # TUPLE3
1071+ b'NN(N\x87 ' ,
1072+ b'N(NN\x87 ' ,
1073+ b']((\x90 ' , # ADDITEMS
1074+ # NEWOBJ_EX
1075+ b'cbuiltins\n list\n )}(\x92 ' ,
1076+ b'cbuiltins\n list\n )(}\x92 ' ,
1077+ b'cbuiltins\n list\n ()}\x92 ' ,
1078+ # STACK_GLOBAL
1079+ b'Vbuiltins\n (Vlist\n \x93 ' ,
1080+ b'Vbuiltins\n Vlist\n (\x93 ' ,
1081+ b'N(\x94 ' , # MEMOIZE
1082+ ]
1083+ for p in badpickles :
1084+ self .check_unpickling_error (self .bad_mark_errors , p )
1085+
1086+ def test_truncated_data (self ):
1087+ self .check_unpickling_error (EOFError , b'' )
1088+ self .check_unpickling_error (EOFError , b'N' )
1089+ badpickles = [
1090+ b'B' , # BINBYTES
1091+ b'B\x03 \x00 \x00 ' ,
1092+ b'B\x03 \x00 \x00 \x00 ' ,
1093+ b'B\x03 \x00 \x00 \x00 ab' ,
1094+ b'C' , # SHORT_BINBYTES
1095+ b'C\x03 ' ,
1096+ b'C\x03 ab' ,
1097+ b'F' , # FLOAT
1098+ b'F0.0' ,
1099+ b'F0.00' ,
1100+ b'G' , # BINFLOAT
1101+ b'G\x00 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1102+ b'I' , # INT
1103+ b'I0' ,
1104+ b'J' , # BININT
1105+ b'J\x00 \x00 \x00 ' ,
1106+ b'K' , # BININT1
1107+ b'L' , # LONG
1108+ b'L0' ,
1109+ b'L10' ,
1110+ b'L0L' ,
1111+ b'L10L' ,
1112+ b'M' , # BININT2
1113+ b'M\x00 ' ,
1114+ # b'P', # PERSID
1115+ # b'Pabc',
1116+ b'S' , # STRING
1117+ b"S'abc'" ,
1118+ b'T' , # BINSTRING
1119+ b'T\x03 \x00 \x00 ' ,
1120+ b'T\x03 \x00 \x00 \x00 ' ,
1121+ b'T\x03 \x00 \x00 \x00 ab' ,
1122+ b'U' , # SHORT_BINSTRING
1123+ b'U\x03 ' ,
1124+ b'U\x03 ab' ,
1125+ b'V' , # UNICODE
1126+ b'Vabc' ,
1127+ b'X' , # BINUNICODE
1128+ b'X\x03 \x00 \x00 ' ,
1129+ b'X\x03 \x00 \x00 \x00 ' ,
1130+ b'X\x03 \x00 \x00 \x00 ab' ,
1131+ b'(c' , # GLOBAL
1132+ b'(cbuiltins' ,
1133+ b'(cbuiltins\n ' ,
1134+ b'(cbuiltins\n list' ,
1135+ b'Ng' , # GET
1136+ b'Ng0' ,
1137+ b'(i' , # INST
1138+ b'(ibuiltins' ,
1139+ b'(ibuiltins\n ' ,
1140+ b'(ibuiltins\n list' ,
1141+ b'Nh' , # BINGET
1142+ b'Nj' , # LONG_BINGET
1143+ b'Nj\x00 \x00 \x00 ' ,
1144+ b'Np' , # PUT
1145+ b'Np0' ,
1146+ b'Nq' , # BINPUT
1147+ b'Nr' , # LONG_BINPUT
1148+ b'Nr\x00 \x00 \x00 ' ,
1149+ b'\x80 ' , # PROTO
1150+ b'\x82 ' , # EXT1
1151+ b'\x83 ' , # EXT2
1152+ b'\x84 \x01 ' ,
1153+ b'\x84 ' , # EXT4
1154+ b'\x84 \x01 \x00 \x00 ' ,
1155+ b'\x8a ' , # LONG1
1156+ b'\x8b ' , # LONG4
1157+ b'\x8b \x00 \x00 \x00 ' ,
1158+ b'\x8c ' , # SHORT_BINUNICODE
1159+ b'\x8c \x03 ' ,
1160+ b'\x8c \x03 ab' ,
1161+ b'\x8d ' , # BINUNICODE8
1162+ b'\x8d \x03 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1163+ b'\x8d \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1164+ b'\x8d \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ab' ,
1165+ b'\x8e ' , # BINBYTES8
1166+ b'\x8e \x03 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1167+ b'\x8e \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1168+ b'\x8e \x03 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ab' ,
1169+ b'\x95 ' , # FRAME
1170+ b'\x95 \x02 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1171+ b'\x95 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \x00 ' ,
1172+ b'\x95 \x02 \x00 \x00 \x00 \x00 \x00 \x00 \x00 N' ,
10631173 ]
10641174 for p in badpickles :
1065- # PyUnpickler prints reduce errors to stdout
1066- with self .subTest (p ), captured_stdout ():
1067- try :
1068- self .loads (p )
1069- except (IndexError , AttributeError , TypeError ,
1070- pickle .UnpicklingError ):
1071- pass
1175+ self .check_unpickling_error (self .truncated_errors , p )
10721176
10731177
10741178class AbstractPickleTests (unittest .TestCase ):
0 commit comments