@@ -10,15 +10,6 @@ def loads(object):
1010 f = StringIO .StringIO (object )
1111 marshaller = JavaObjectMarshaller ()
1212 return marshaller .load_stream (f )
13- # ba = f.read(4)
14- # (magic, version) = struct.unpack(">HH", ba)
15- # print magic
16- # if magic != 0xaced:
17- # raise RuntimeError("The stream is not java serialized object. Magic number failed.")
18- #
19- # print version
20- #
21- # print type(object), Magic
2213
2314def dumps (object ):
2415 """
@@ -130,7 +121,7 @@ def load_stream(self, stream):
130121 self ._readStreamHeader ()
131122 return self .readObject ()
132123 except Exception , e :
133- self .dump_state ()
124+ self ._oops_dump_state ()
134125 raise
135126
136127 def _readStreamHeader (self ):
@@ -139,23 +130,23 @@ def _readStreamHeader(self):
139130 raise IOError ("The stream is not java serialized object. Invalid stream header: %04X%04X" % (magic , version ))
140131
141132 def readObject (self ):
142- res = self .read_and_exec_opcode (ident = 0 ) # TODO: add expects
133+ res = self ._read_and_exec_opcode (ident = 0 ) # TODO: add expects
143134
144135 the_rest = self .object_stream .read ()
145136 if len (the_rest ):
146137 print "Warning!!!!: Stream still has %s bytes left." % len (the_rest )
147- print self .hexdump (the_rest )
138+ print self ._create_hexdump (the_rest )
148139 else :
149140 print "Ok!!!!"
150141
151142 return res
152143
153- def read_and_exec_opcode (self , ident = 0 , expect = None ):
144+ def _read_and_exec_opcode (self , ident = 0 , expect = None ):
154145 (opid , ) = self ._readStruct (">B" )
155- self .print_ident ("OpCode: 0x%X" % opid , ident )
146+ self ._log_ident ("OpCode: 0x%X" % opid , ident )
156147 if expect and opid not in expect :
157148 raise IOError ("Unexpected opcode 0x%X" % opid )
158- return self .opmap .get (opid , self .do_default_stuff )(ident = ident )
149+ return self .opmap .get (opid , self .do_unknown )(ident = ident )
159150
160151 def _readStruct (self , unpack ):
161152 length = struct .calcsize (unpack )
@@ -184,38 +175,38 @@ def do_classdesc(self, parent=None, ident=0):
184175 # objectDesc:
185176 # obj_typecode fieldName className1
186177 clazz = JavaClass ()
187- self .print_ident ("[classdesc]" , ident )
178+ self ._log_ident ("[classdesc]" , ident )
188179 ba = self ._readString ()
189180 clazz .name = ba
190- self .print_ident ("Class name: %s" % ba , ident )
181+ self ._log_ident ("Class name: %s" % ba , ident )
191182 (serialVersionUID , newHandle , classDescFlags ) = self ._readStruct (">LLB" )
192183 clazz .serialVersionUID = serialVersionUID
193184 clazz .flags = classDescFlags
194185
195- self .add_reference (clazz )
186+ self ._add_reference (clazz )
196187
197- self .print_ident ("Serial: 0x%X newHandle: 0x%X. classDescFlags: 0x%X" % (serialVersionUID , newHandle , classDescFlags ), ident )
188+ self ._log_ident ("Serial: 0x%X newHandle: 0x%X. classDescFlags: 0x%X" % (serialVersionUID , newHandle , classDescFlags ), ident )
198189 (length , ) = self ._readStruct (">H" )
199- self .print_ident ("Fields num: 0x%X" % length , ident )
190+ self ._log_ident ("Fields num: 0x%X" % length , ident )
200191
201192 clazz .fields_names = []
202193 clazz .fields_types = []
203194 for fieldId in range (length ):
204195 (type , ) = self ._readStruct (">B" )
205196 field_name = self ._readString ()
206197 field_type = None
207- field_type = self .convert_char_to_type (type )
198+ field_type = self ._convert_char_to_type (type )
208199
209200 if field_type == self .TYPE_ARRAY :
210- field_type = self .read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_STRING , self .TC_REFERENCE ])
201+ field_type = self ._read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_STRING , self .TC_REFERENCE ])
211202# if field_type is not None:
212203# field_type = "array of " + field_type
213204# else:
214205# field_type = "array of None"
215206 elif field_type == self .TYPE_OBJECT :
216- field_type = self .read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_STRING , self .TC_REFERENCE ])
207+ field_type = self ._read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_STRING , self .TC_REFERENCE ])
217208
218- self .print_ident ("FieldName: 0x%X" % type + " " + str (field_name ) + " " + str (field_type ), ident )
209+ self ._log_ident ("FieldName: 0x%X" % type + " " + str (field_name ) + " " + str (field_type ), ident )
219210 assert field_name is not None
220211 assert field_type is not None
221212
@@ -228,41 +219,41 @@ def do_classdesc(self, parent=None, ident=0):
228219 (opid , ) = self ._readStruct (">B" )
229220 if opid != self .TC_ENDBLOCKDATA :
230221 raise NotImplementedError ("classAnnotation isn't implemented yet" )
231- self .print_ident ("OpCode: 0x%X" % opid , ident )
222+ self ._log_ident ("OpCode: 0x%X" % opid , ident )
232223 # superClassDesc
233- superclassdesc = self .read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_NULL ])
234- self .print_ident (str (superclassdesc ), ident )
224+ superclassdesc = self ._read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_NULL , self . TC_REFERENCE ])
225+ self ._log_ident (str (superclassdesc ), ident )
235226 clazz .superclass = superclassdesc
236227
237228 return clazz
238229
239230 def do_blockdata (self , parent = None , ident = 0 ):
240231 # TC_BLOCKDATA (unsigned byte)<size> (byte)[size]
241- self .print_ident ("[blockdata]" , ident )
232+ self ._log_ident ("[blockdata]" , ident )
242233 (length , ) = self ._readStruct (">B" )
243234 ba = self .object_stream .read (length )
244235 return ba
245236
246237 def do_class (self , parent = None , ident = 0 ):
247238 # TC_CLASS classDesc newHandle
248- self .print_ident ("[class]" , ident )
239+ self ._log_ident ("[class]" , ident )
249240
250241 # TODO: what to do with "(ClassDesc)prevObject". (see 3rd line for classDesc:)
251- classdesc = self .read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_PROXYCLASSDESC , self .TC_NULL ])
252- self .print_ident ("Classdesc: %s" % classdesc , ident )
253- self .add_reference (classdesc )
242+ classdesc = self ._read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_PROXYCLASSDESC , self .TC_NULL , self . TC_REFERENCE ])
243+ self ._log_ident ("Classdesc: %s" % classdesc , ident )
244+ self ._add_reference (classdesc )
254245 return classdesc
255246
256247 def do_object (self , parent = None , ident = 0 ):
257248 # TC_OBJECT classDesc newHandle classdata[] // data for each class
258249 java_object = JavaObject ()
259- self .print_ident ("[object]" , ident )
250+ self ._log_ident ("[object]" , ident )
260251
261252 # TODO: what to do with "(ClassDesc)prevObject". (see 3rd line for classDesc:)
262- classdesc = self .read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_PROXYCLASSDESC , self .TC_NULL , self .TC_REFERENCE ])
253+ classdesc = self ._read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_PROXYCLASSDESC , self .TC_NULL , self .TC_REFERENCE ])
263254 # self.TC_REFERENCE hasn't shown in spec, but actually is here
264255
265- self .add_reference (java_object )
256+ self ._add_reference (java_object )
266257
267258 # classdata[]
268259
@@ -278,7 +269,7 @@ def do_object(self, parent=None, ident=0):
278269 megalist = []
279270 megatypes = []
280271 while tempclass :
281- print ">>>" , tempclass .fields_names , tempclass
272+ self . _log_ident ( ">>> " + str ( tempclass .fields_names ) + " " + str ( tempclass ), ident )
282273 fieldscopy = tempclass .fields_names [:]
283274 fieldscopy .extend (megalist )
284275 megalist = fieldscopy
@@ -289,74 +280,75 @@ def do_object(self, parent=None, ident=0):
289280
290281 tempclass = tempclass .superclass
291282
292- print "Prepared list of values:" , megalist
293- print "Prepared list of types:" , megatypes
283+ self ._log_ident ("Values count: %s" % str (len (megalist )), ident )
284+ self ._log_ident ("Prepared list of values: %s" % str (megalist ), ident )
285+ self ._log_ident ("Prepared list of types: %s" % str (megatypes ), ident )
294286
295287 for field_name , field_type in zip (megalist , megatypes ):
296- res = self .read_native (field_type , ident )
288+ res = self ._read_value (field_type , ident , name = field_name )
297289 java_object .__setattr__ (field_name , res )
298290
299291 if classdesc .flags & self .SC_SERIALIZABLE and classdesc .flags & self .SC_WRITE_METHOD or classdesc .flags & self .SC_EXTERNALIZABLE and classdesc .flags & self .SC_BLOCK_DATA :
300292 # objectAnnotation
301293 (opid , ) = self ._readStruct (">B" )
302294 if opid != self .TC_ENDBLOCKDATA : # 0x78:
303295 self .object_stream .seek (- 1 , mode = 1 )
304- print self .hexdump (self .object_stream .read ())
296+ print self ._create_hexdump (self .object_stream .read ())
305297 raise NotImplementedError ("objectAnnotation isn't fully implemented yet" ) # TODO:
306298
307299
308300 return java_object
309301
310302 def do_string (self , parent = None , ident = 0 ):
311- self .print_ident ("[string]" , ident )
303+ self ._log_ident ("[string]" , ident )
312304 ba = self ._readString ()
313- self .add_reference (str (ba ))
305+ self ._add_reference (str (ba ))
314306 return str (ba )
315307
316308 def do_array (self , parent = None , ident = 0 ):
317309 # TC_ARRAY classDesc newHandle (int)<size> values[size]
318- self .print_ident ("[array]" , ident )
319- classdesc = self .read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_PROXYCLASSDESC , self .TC_NULL ])
310+ self ._log_ident ("[array]" , ident )
311+ classdesc = self ._read_and_exec_opcode (ident = ident + 1 , expect = [self .TC_CLASSDESC , self .TC_PROXYCLASSDESC , self .TC_NULL , self . TC_REFERENCE ])
320312
321313 array = []
322314
323- self .add_reference (array )
315+ self ._add_reference (array )
324316
325317 (size , ) = self ._readStruct (">i" )
326- self .print_ident ("size: " + str (size ), ident )
318+ self ._log_ident ("size: " + str (size ), ident )
327319
328320 type_char = classdesc .name [0 ]
329321 assert type_char == self .TYPE_ARRAY
330322 type_char = classdesc .name [1 ]
331323
332324 if type_char == self .TYPE_OBJECT or type_char == self .TYPE_ARRAY :
333325 for i in range (size ):
334- res = self .read_and_exec_opcode (ident = ident + 1 )
335- print res
326+ res = self ._read_and_exec_opcode (ident = ident + 1 )
327+ self . _log_ident ( "Object value: %s" % str ( res ), ident )
336328 array .append (res )
337329 else :
338330 for i in range (size ):
339- res = self .read_native (type_char , ident )
340- print "Native value:" , res
331+ res = self ._read_value (type_char , ident )
332+ self . _log_ident ( "Native value: %s" % str ( res ), ident )
341333 array .append (res )
342334
343335 return array
344336
345337 def do_reference (self , parent = None , ident = 0 ):
346338 (handle , ) = self ._readStruct (">L" )
347- print "## Reference handle: 0x%x" % (handle )
339+ self . _log_ident ( "## Reference handle: 0x%x" % (handle ), ident )
348340 return self .references [handle - self .BASE_REFERENCE_IDX ]
349341
350342 def do_null (self , parent = None , ident = 0 ):
351343 return None
352344
353- def do_default_stuff (self , parent = None , ident = 0 ):
345+ def do_unknown (self , parent = None , ident = 0 ):
354346 raise RuntimeError ("Unknown OpCode" )
355347
356- def print_ident (self , message , ident ):
357- print " " * ident + str (message )
348+ def _log_ident (self , message , ident ):
349+ print " " * ( ident * 2 ) + str (message )
358350
359- def hexdump (self , src , length = 16 ):
351+ def _create_hexdump (self , src , length = 16 ):
360352 FILTER = '' .join ([(len (repr (chr (x )))== 3 ) and chr (x ) or '.' for x in range (256 )])
361353 result = []
362354 for i in xrange (0 , len (src ), length ):
@@ -366,7 +358,7 @@ def hexdump(self, src, length=16):
366358 result .append ("%04X %-*s %s\n " % (i , length * 3 , hexa , printable ))
367359 return '' .join (result )
368360
369- def read_native (self , field_type , ident ):
361+ def _read_value (self , field_type , ident , name = "" ):
370362 if len (field_type ) > 1 :
371363 field_type = field_type [0 ] # We don't need details for arrays and objects
372364
@@ -386,12 +378,13 @@ def read_native(self, field_type, ident):
386378 elif field_type == self .TYPE_DOUBLE :
387379 (res , ) = self ._readStruct (">d" )
388380 elif field_type == self .TYPE_OBJECT or field_type == self .TYPE_ARRAY :
389- res = self .read_and_exec_opcode (ident = ident + 1 )
381+ res = self ._read_and_exec_opcode (ident = ident + 1 )
390382 else :
391383 raise RuntimeError ("Unknown typecode: %s" % field_type )
384+ self ._log_ident ("* %s %s: " % (field_type , name ) + str (res ), ident )
392385 return res
393386
394- def convert_char_to_type (self , type_char ):
387+ def _convert_char_to_type (self , type_char ):
395388 typecode = type_char
396389 if type (type_char ) is int :
397390 typecode = chr (type_char )
@@ -401,12 +394,18 @@ def convert_char_to_type(self, type_char):
401394 else :
402395 raise RuntimeError ("Typecode %s (%s) isn't supported." % (type_char , typecode ))
403396
404- def add_reference (self , obj ):
397+ def _add_reference (self , obj ):
405398 self .references .append (obj )
406399
407- def dump_state (self ):
400+ def _oops_dump_state (self ):
408401 print "==Oops state dump" + "=" * (30 - 17 )
409- print "Referenes:" , self .references
402+ print "References:" , self .references
403+ print "Stream seeking back at -16 byte (2nd line is an actual position!):"
404+ self .object_stream .seek (- 16 , mode = 1 )
405+ the_rest = self .object_stream .read ()
406+ if len (the_rest ):
407+ print "Warning!!!!: Stream still has %s bytes left." % len (the_rest )
408+ print self ._create_hexdump (the_rest )
410409 print "=" * 30
411410 # =====================================================================================
412411
0 commit comments