python-pickle 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +17 -0
  3. data/README.md +4 -1
  4. data/lib/python/pickle/deserializer.rb +142 -80
  5. data/lib/python/pickle/instructions/bin_persid.rb +31 -0
  6. data/lib/python/pickle/instructions/global.rb +11 -41
  7. data/lib/python/pickle/instructions/has_namespace_and_name.rb +61 -0
  8. data/lib/python/pickle/instructions/inst.rb +34 -0
  9. data/lib/python/pickle/instructions/next_buffer.rb +5 -1
  10. data/lib/python/pickle/instructions/obj.rb +30 -0
  11. data/lib/python/pickle/instructions/persid.rb +31 -0
  12. data/lib/python/pickle/instructions/readonly_buffer.rb +4 -0
  13. data/lib/python/pickle/instructions.rb +64 -0
  14. data/lib/python/pickle/protocol0.rb +313 -68
  15. data/lib/python/pickle/protocol1.rb +225 -93
  16. data/lib/python/pickle/protocol2.rb +205 -124
  17. data/lib/python/pickle/protocol3.rb +92 -123
  18. data/lib/python/pickle/protocol4.rb +188 -165
  19. data/lib/python/pickle/protocol5.rb +98 -166
  20. data/lib/python/pickle/version.rb +1 -1
  21. data/lib/python/pickle.rb +71 -39
  22. data/spec/deserializer_spec.rb +359 -0
  23. data/spec/fixtures/set_v0.pkl +11 -0
  24. data/spec/fixtures/set_v1.pkl +0 -0
  25. data/spec/fixtures/set_v2.pkl +0 -0
  26. data/spec/fixtures/set_v3.pkl +0 -0
  27. data/spec/fixtures/set_v4.pkl +0 -0
  28. data/spec/fixtures/set_v5.pkl +0 -0
  29. data/spec/generate_pickles2.py +1 -0
  30. data/spec/generate_pickles3.py +1 -0
  31. data/spec/integration/load/protocol0_spec.rb +10 -0
  32. data/spec/integration/load/protocol1_spec.rb +10 -0
  33. data/spec/integration/load/protocol2_spec.rb +10 -0
  34. data/spec/integration/load/protocol3_spec.rb +10 -0
  35. data/spec/integration/load/protocol4_spec.rb +10 -0
  36. data/spec/integration/load/protocol5_spec.rb +10 -0
  37. data/spec/pickle_spec.rb +61 -0
  38. data/spec/protocol0_read_instruction_examples.rb +44 -0
  39. metadata +14 -2
@@ -0,0 +1,64 @@
1
+ require 'python/pickle/instructions/proto'
2
+ require 'python/pickle/instructions/frame'
3
+ require 'python/pickle/instructions/get'
4
+ require 'python/pickle/instructions/bin_get'
5
+ require 'python/pickle/instructions/long_bin_get'
6
+ require 'python/pickle/instructions/mark'
7
+ require 'python/pickle/instructions/pop_mark'
8
+ require 'python/pickle/instructions/dup'
9
+ require 'python/pickle/instructions/put'
10
+ require 'python/pickle/instructions/bin_put'
11
+ require 'python/pickle/instructions/pop'
12
+ require 'python/pickle/instructions/memoize'
13
+ require 'python/pickle/instructions/ext1'
14
+ require 'python/pickle/instructions/ext2'
15
+ require 'python/pickle/instructions/ext4'
16
+ require 'python/pickle/instructions/persid'
17
+ require 'python/pickle/instructions/bin_persid'
18
+ require 'python/pickle/instructions/none'
19
+ require 'python/pickle/instructions/new_true'
20
+ require 'python/pickle/instructions/new_false'
21
+ require 'python/pickle/instructions/float'
22
+ require 'python/pickle/instructions/bin_float'
23
+ require 'python/pickle/instructions/int'
24
+ require 'python/pickle/instructions/bin_int1'
25
+ require 'python/pickle/instructions/long'
26
+ require 'python/pickle/instructions/long1'
27
+ require 'python/pickle/instructions/long4'
28
+ require 'python/pickle/instructions/bin_bytes'
29
+ require 'python/pickle/instructions/short_bin_bytes'
30
+ require 'python/pickle/instructions/bin_bytes8'
31
+ require 'python/pickle/instructions/string'
32
+ require 'python/pickle/instructions/bin_string'
33
+ require 'python/pickle/instructions/short_bin_string'
34
+ require 'python/pickle/instructions/bin_unicode'
35
+ require 'python/pickle/instructions/short_bin_unicode'
36
+ require 'python/pickle/instructions/bin_unicode8'
37
+ require 'python/pickle/instructions/byte_array8'
38
+ require 'python/pickle/instructions/empty_list'
39
+ require 'python/pickle/instructions/empty_tuple'
40
+ require 'python/pickle/instructions/tuple'
41
+ require 'python/pickle/instructions/empty_dict'
42
+ require 'python/pickle/instructions/empty_set'
43
+ require 'python/pickle/instructions/frozen_set'
44
+ require 'python/pickle/instructions/append'
45
+ require 'python/pickle/instructions/appends'
46
+ require 'python/pickle/instructions/add_items'
47
+ require 'python/pickle/instructions/list'
48
+ require 'python/pickle/instructions/tuple1'
49
+ require 'python/pickle/instructions/tuple2'
50
+ require 'python/pickle/instructions/tuple3'
51
+ require 'python/pickle/instructions/dict'
52
+ require 'python/pickle/instructions/global'
53
+ require 'python/pickle/instructions/stack_global'
54
+ require 'python/pickle/instructions/inst'
55
+ require 'python/pickle/instructions/obj'
56
+ require 'python/pickle/instructions/new_obj'
57
+ require 'python/pickle/instructions/new_obj_ex'
58
+ require 'python/pickle/instructions/reduce'
59
+ require 'python/pickle/instructions/build'
60
+ require 'python/pickle/instructions/set_item'
61
+ require 'python/pickle/instructions/set_items'
62
+ require 'python/pickle/instructions/next_buffer'
63
+ require 'python/pickle/instructions/readonly_buffer'
64
+ require 'python/pickle/instructions/stop'
@@ -13,11 +13,15 @@ require 'python/pickle/instructions/list'
13
13
  require 'python/pickle/instructions/none'
14
14
  require 'python/pickle/instructions/append'
15
15
  require 'python/pickle/instructions/global'
16
+ require 'python/pickle/instructions/obj'
17
+ require 'python/pickle/instructions/inst'
16
18
  require 'python/pickle/instructions/reduce'
17
19
  require 'python/pickle/instructions/build'
18
20
  require 'python/pickle/instructions/pop'
19
21
  require 'python/pickle/instructions/pop_mark'
20
22
  require 'python/pickle/instructions/dup'
23
+ require 'python/pickle/instructions/persid'
24
+ require 'python/pickle/instructions/bin_persid'
21
25
  require 'python/pickle/instructions/stop'
22
26
  require 'python/pickle/exceptions'
23
27
 
@@ -32,32 +36,180 @@ module Python
32
36
  #
33
37
  class Protocol0 < Protocol
34
38
 
35
- # Opcodes for Pickle protocol version 0.
36
- #
37
- # @see https://github.com/python/cpython/blob/main/Lib/pickletools.py
38
- OPCODES = Set[
39
- 40, # MARK
40
- 46, # STOP
41
- 48, # POP
42
- 49, # POP_MARK
43
- 50, # DUP
44
- 70, # FLOAT
45
- 73, # INT
46
- 76, # LONG
47
- 78, # NONE
48
- 82, # REDUCE
49
- 83, # STRING
50
- 86, # UNICODE
51
- 97, # APPEND
52
- 98, # BUILD
53
- 99, # GLOBAL
54
- 100, # DICT
55
- 103, # GET
56
- 108, # LIST
57
- 112, # PUT
58
- 115, # SETITEM
59
- 116 # TUPLE
60
- ]
39
+ # The `MARK` opcode.
40
+ #
41
+ # @since 0.2.0
42
+ #
43
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L102
44
+ MARK = 40
45
+
46
+ # The `STOP` opcode.
47
+ #
48
+ # @since 0.2.0
49
+ #
50
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L103
51
+ STOP = 46
52
+
53
+ # The `POP` opcode.
54
+ #
55
+ # @since 0.2.0
56
+ #
57
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L104
58
+ POP = 48
59
+
60
+ # The `POP_MARK` opcode.
61
+ #
62
+ # @since 0.2.0
63
+ #
64
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L105
65
+ POP_MARK = 49
66
+
67
+ # The `DUP` opcode.
68
+ #
69
+ # @since 0.2.0
70
+ #
71
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L106
72
+ DUP = 50
73
+
74
+ # The `FLOAT` opcode.
75
+ #
76
+ # @since 0.2.0
77
+ #
78
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L107
79
+ FLOAT = 70
80
+
81
+ # The `INT` opcode.
82
+ #
83
+ # @since 0.2.0
84
+ #
85
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L108
86
+ INT = 73
87
+
88
+ # The `LONG` opcode.
89
+ #
90
+ # @since 0.2.0
91
+ #
92
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L111
93
+ LONG = 76
94
+
95
+ # The `NONE` opcode.
96
+ #
97
+ # @since 0.2.0
98
+ #
99
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L113
100
+ NONE = 78
101
+
102
+ # The `PERSID` opcode.
103
+ #
104
+ # @since 0.2.0
105
+ #
106
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L114
107
+ PERSID = 80
108
+
109
+ # The `BINPERSID` opcode.
110
+ #
111
+ # @since 0.2.0
112
+ #
113
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L115
114
+ BINPERSID = 81
115
+
116
+ # The `REDUCE` opcode.
117
+ #
118
+ # @since 0.2.0
119
+ #
120
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L116
121
+ REDUCE = 82
122
+
123
+ # The `STRING` opcode.
124
+ #
125
+ # @since 0.2.0
126
+ #
127
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L117
128
+ STRING = 83
129
+
130
+ # The `UNICODE` opcode.
131
+ #
132
+ # @since 0.2.0
133
+ #
134
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L120
135
+ UNICODE = 86
136
+
137
+ # The `APPEND` opcode.
138
+ #
139
+ # @since 0.2.0
140
+ #
141
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L122
142
+ APPEND = 97
143
+
144
+ # The `BUILD` opcode.
145
+ #
146
+ # @since 0.2.0
147
+ #
148
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L123
149
+ BUILD = 98
150
+
151
+ # The `GLOBAL` opcode.
152
+ #
153
+ # @since 0.2.0
154
+ #
155
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L124
156
+ GLOBAL = 99
157
+
158
+ # The `DICT` opcode.
159
+ #
160
+ # @since 0.2.0
161
+ #
162
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L125
163
+ DICT = 100
164
+
165
+ # The `GET` opcode.
166
+ #
167
+ # @since 0.2.0
168
+ #
169
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L128
170
+ GET = 103
171
+
172
+ # The `INST` opcode.
173
+ #
174
+ # @since 0.2.0
175
+ #
176
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L130
177
+ INST = 105
178
+
179
+ # The `LIST` opcode.
180
+ #
181
+ # @since 0.2.0
182
+ #
183
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L132
184
+ LIST = 108
185
+
186
+ # The `OBJ` opcode.
187
+ #
188
+ # @since 0.2.0
189
+ #
190
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L137
191
+ OBJ = 111
192
+
193
+ # The `PUT` opcode.
194
+ #
195
+ # @since 0.2.0
196
+ #
197
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L135
198
+ PUT = 112
199
+
200
+ # The `SETITEM` opcode.
201
+ #
202
+ # @since 0.2.0
203
+ #
204
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L138
205
+ SETITEM = 115
206
+
207
+ # The `TUPLE` opcode.
208
+ #
209
+ # @since 0.2.0
210
+ #
211
+ # @see https://github.com/python/cpython/blob/v2.7/Lib/pickle.py#L139
212
+ TUPLE = 116
61
213
 
62
214
  #
63
215
  # Reads an instruction from the pickle stream.
@@ -70,48 +222,31 @@ module Python
70
222
  #
71
223
  def read_instruction
72
224
  case (opcode = @io.getbyte)
73
- when 40 # MARK
74
- Instructions::MARK
75
- when 46 # STOP
76
- Instructions::STOP
77
- when 48 # POP
78
- Instructions::POP
79
- when 49 # POP_MARK
80
- Instructions::POP_MARK
81
- when 50 # DUP
82
- Instructions::DUP
83
- when 70 # FLOAT
84
- Instructions::Float.new(read_float)
85
- when 73 # INT
86
- Instructions::Int.new(read_int)
87
- when 76 # LONG
88
- Instructions::Long.new(read_long)
89
- when 78 # NONE
90
- Instructions::NONE
91
- when 82 # REDUCE
92
- Instructions::REDUCE
93
- when 83 # STRING
94
- Instructions::String.new(read_string)
95
- when 86 # UNICODE
96
- Instructions::String.new(read_unicode_string)
97
- when 97 # APPEND
98
- Instructions::APPEND
99
- when 98 # BUILD
100
- Instructions::BUILD
101
- when 99 # GLOBAL
102
- Instructions::Global.new(read_nl_string,read_nl_string)
103
- when 100 # DICT
104
- Instructions::DICT
105
- when 103 # GET
106
- Instructions::Get.new(read_int)
107
- when 108 # LIST
108
- Instructions::LIST
109
- when 112 # PUT
110
- Instructions::Put.new(read_int)
111
- when 115 # SETITEM
112
- Instructions::SETITEM
113
- when 116 # TUPLE
114
- Instructions::TUPLE
225
+ when MARK then Instructions::MARK
226
+ when STOP then Instructions::STOP
227
+ when POP then Instructions::POP
228
+ when POP_MARK then Instructions::POP_MARK
229
+ when DUP then Instructions::DUP
230
+ when FLOAT then read_float_instruction
231
+ when INT then read_int_instruction
232
+ when LONG then read_long_instruction
233
+ when NONE then Instructions::NONE
234
+ when REDUCE then Instructions::REDUCE
235
+ when STRING then read_string_instruction
236
+ when UNICODE then read_unicode_instruction
237
+ when APPEND then Instructions::APPEND
238
+ when BUILD then Instructions::BUILD
239
+ when GLOBAL then read_global_instruction
240
+ when DICT then Instructions::DICT
241
+ when GET then read_get_instruction
242
+ when LIST then Instructions::LIST
243
+ when PUT then read_put_instruction
244
+ when SETITEM then Instructions::SETITEM
245
+ when TUPLE then Instructions::TUPLE
246
+ when INST then read_inst_instruction
247
+ when OBJ then Instructions::OBJ
248
+ when PERSID then read_persid_instruction
249
+ when BINPERSID then Instructions::BINPERSID
115
250
  else
116
251
  raise(InvalidFormat,"invalid opcode (#{opcode.inspect}) for protocol 0")
117
252
  end
@@ -394,6 +529,116 @@ module Python
394
529
  raise(InvalidFormat,"unexpected end of stream while parsing a long integer: #{new_string.inspect}")
395
530
  end
396
531
 
532
+ #
533
+ # Reads a `FLOAT` instruction.
534
+ #
535
+ # @return [Instructions::Float]
536
+ #
537
+ # @since 0.2.0
538
+ #
539
+ def read_float_instruction
540
+ Instructions::Float.new(read_float)
541
+ end
542
+
543
+ #
544
+ # Reads a `INT` instruction.
545
+ #
546
+ # @return [Instructions::Int]
547
+ #
548
+ # @since 0.2.0
549
+ #
550
+ def read_int_instruction
551
+ Instructions::Int.new(read_int)
552
+ end
553
+
554
+ #
555
+ # Reads a `LONG` instruction.
556
+ #
557
+ # @return [Instructions::Long]
558
+ #
559
+ # @since 0.2.0
560
+ #
561
+ def read_long_instruction
562
+ Instructions::Long.new(read_long)
563
+ end
564
+
565
+ #
566
+ # Reads a `STRING` instruction.
567
+ #
568
+ # @return [Instructions::String]
569
+ #
570
+ # @since 0.2.0
571
+ #
572
+ def read_string_instruction
573
+ Instructions::String.new(read_string)
574
+ end
575
+
576
+ #
577
+ # Reads a `UNICODE` instruction.
578
+ #
579
+ # @return [Instructions::Unicode]
580
+ #
581
+ # @since 0.2.0
582
+ #
583
+ def read_unicode_instruction
584
+ Instructions::String.new(read_unicode_string)
585
+ end
586
+
587
+ #
588
+ # Reads a `GLOBAL` instruction.
589
+ #
590
+ # @return [Instructions::Global]
591
+ #
592
+ # @since 0.2.0
593
+ #
594
+ def read_global_instruction
595
+ Instructions::Global.new(read_nl_string,read_nl_string)
596
+ end
597
+
598
+ #
599
+ # Reads a `INST` instruction.
600
+ #
601
+ # @return [Instructions::Inst]
602
+ #
603
+ # @since 0.2.0
604
+ #
605
+ def read_inst_instruction
606
+ Instructions::Inst.new(read_nl_string,read_nl_string)
607
+ end
608
+
609
+ #
610
+ # Reads a `GET` instruction.
611
+ #
612
+ # @return [Instructions::Get]
613
+ #
614
+ # @since 0.2.0
615
+ #
616
+ def read_get_instruction
617
+ Instructions::Get.new(read_int)
618
+ end
619
+
620
+ #
621
+ # Reads a `PUT` instruction.
622
+ #
623
+ # @return [Instructions::Put]
624
+ #
625
+ # @since 0.2.0
626
+ #
627
+ def read_put_instruction
628
+ Instructions::Put.new(read_int)
629
+ end
630
+
631
+ #
632
+ # Reads a `PERSID` instruction.
633
+ #
634
+ # @return [Instructions::PersID]
635
+ #
636
+ # @since 0.2.0
637
+ #
638
+ def read_persid_instruction
639
+ Instructions::PersID.new(read_nl_string)
640
+ end
641
+
397
642
  end
398
643
  end
399
644
  end