Skip to content

Commit 5555a2e

Browse files
author
vbuell
committed
adopt api to handle multiple objects being read from the stream
1 parent d0616c4 commit 5555a2e

File tree

3 files changed

+40
-44
lines changed

3 files changed

+40
-44
lines changed

javaobj.py

Lines changed: 28 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ def loads(object):
88
See: http://download.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html
99
"""
1010
f = StringIO.StringIO(object)
11-
marshaller = JavaObjectMarshaller()
12-
return marshaller.load_stream(f)
11+
marshaller = JavaObjectUnmarshaller(f)
12+
return marshaller.readObject()
1313

1414
def dumps(object):
1515
"""
@@ -41,8 +41,7 @@ class JavaObject(object):
4141
def get_class(self):
4242
return self.classdesc
4343

44-
45-
class JavaObjectMarshaller:
44+
class JavaObjectConstants:
4645

4746
STREAM_MAGIC = 0xaced
4847
STREAM_VERSION = 0x05
@@ -100,7 +99,10 @@ class JavaObjectMarshaller:
10099

101100
BASE_REFERENCE_IDX = 0x7E0000
102101

103-
def __init__(self):
102+
103+
class JavaObjectUnmarshaller(JavaObjectConstants):
104+
105+
def __init__(self, stream=None):
104106
self.opmap = {
105107
self.TC_NULL: self.do_null,
106108
self.TC_CLASSDESC: self.do_classdesc,
@@ -114,12 +116,23 @@ def __init__(self):
114116
self.current_object = None
115117
self.reference_counter = 0
116118
self.references = []
119+
self.object_stream = stream
120+
self._readStreamHeader()
117121

118-
def load_stream(self, stream):
122+
def readObject(self):
119123
try:
120-
self.object_stream = stream
121-
self._readStreamHeader()
122-
return self.readObject()
124+
res = self._read_and_exec_opcode(ident=0) # TODO: add expects
125+
126+
position_bak = self.object_stream.tell()
127+
the_rest = self.object_stream.read()
128+
if len(the_rest):
129+
print "Warning!!!!: Stream still has %s bytes left." % len(the_rest)
130+
print self._create_hexdump(the_rest)
131+
else:
132+
print "Ok!!!!"
133+
self.object_stream.seek(position_bak)
134+
135+
return res
123136
except Exception, e:
124137
self._oops_dump_state()
125138
raise
@@ -129,18 +142,6 @@ def _readStreamHeader(self):
129142
if magic != self.STREAM_MAGIC or version != self.STREAM_VERSION:
130143
raise IOError("The stream is not java serialized object. Invalid stream header: %04X%04X" % (magic, version))
131144

132-
def readObject(self):
133-
res = self._read_and_exec_opcode(ident=0) # TODO: add expects
134-
135-
the_rest = self.object_stream.read()
136-
if len(the_rest):
137-
print "Warning!!!!: Stream still has %s bytes left." % len(the_rest)
138-
print self._create_hexdump(the_rest)
139-
else:
140-
print "Ok!!!!"
141-
142-
return res
143-
144145
def _read_and_exec_opcode(self, ident=0, expect=None):
145146
(opid, ) = self._readStruct(">B")
146147
self._log_ident("OpCode: 0x%X" % opid, ident)
@@ -409,6 +410,11 @@ def _oops_dump_state(self):
409410
print "=" * 30
410411
# =====================================================================================
411412

413+
class JavaObjectMarshaller(JavaObjectConstants):
414+
415+
def __init__(self, stream=None):
416+
self.object_stream = stream
417+
412418
def dump(self, obj):
413419
self.object_obj = obj
414420
self.object_stream = StringIO.StringIO()
@@ -428,10 +434,6 @@ def writeObject(self, obj):
428434
elif type(obj) is str:
429435
print "This is string."
430436
self.write_blockdata(obj)
431-
# (opid, ) = self._readStruct(">B")
432-
# print "OpCode: 0x%X" % opid
433-
# res = self.opmap.get(opid, self.do_default_stuff)()
434-
# return res
435437

436438
def _writeStruct(self, unpack, length, args):
437439
ba = struct.pack(unpack, *args)
@@ -443,31 +445,13 @@ def _writeString(self, string):
443445
self.object_stream.write(string)
444446

445447
def write_blockdata(self, obj, parent=None):
446-
self._writeStruct(">B", 1, (self.TC_BLOCKDATA, ))
447448
# TC_BLOCKDATA (unsigned byte)<size> (byte)[size]
449+
self._writeStruct(">B", 1, (self.TC_BLOCKDATA, ))
448450
if type(obj) is str:
449451
print "This is string."
450452
self._writeStruct(">B", 1, (len(obj), ))
451453
self.object_stream.write(obj)
452454

453455
def write_object(self, obj, parent=None):
454-
# TC_OBJECT classDesc newHandle classdata[] // data for each class
455-
# self.current_object = JavaObject()
456-
# print "[object]"
457456
self._writeStruct(">B", 1, (self.TC_OBJECT, ))
458457
self._writeStruct(">B", 1, (self.TC_CLASSDESC, ))
459-
460-
# print "OpCode: 0x%X" % opid
461-
# classdesc = self.opmap.get(opid, self.do_default_stuff)(self.current_object)
462-
# self.finalValue = classdesc
463-
# # classdata[]
464-
#
465-
# # Store classdesc of this object
466-
# self.current_object.classdesc = classdesc
467-
#
468-
# for field_name in self.current_object.__fields:
469-
# (opid, ) = self._readStruct(">B")
470-
# print "OpCode: 0x%X" % opid
471-
# res = self.opmap.get(opid, self.do_default_stuff)(self.current_object)
472-
# self.current_object.__setattr__(field_name, res)
473-
# return self.current_object

sunExample.ser

69 Bytes
Binary file not shown.

tests.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,17 @@ def test_arrays(self):
126126
print pobj.boolArr
127127
print pobj.concreteArr
128128

129+
def test_sun_example(self):
130+
marshaller = javaobj.JavaObjectUnmarshaller(open("sunExample.ser"))
131+
pobj = marshaller.readObject()
132+
133+
self.assertEqual(pobj.value, 17)
134+
self.assertTrue(pobj.next)
135+
136+
pobj = marshaller.readObject()
137+
138+
self.assertEqual(pobj.value, 19)
139+
self.assertFalse(pobj.next)
140+
129141
if __name__ == '__main__':
130142
unittest.main()

0 commit comments

Comments
 (0)