Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
main project sync
  • Loading branch information
Fede A committed Apr 13, 2020
commit 2b3593ba59981ababa65151b21f172cd7bb90166
5 changes: 3 additions & 2 deletions javaobj/v2/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ def load_array(self, reader, type_code, size):
:param size: Number of elements in the array
"""
return None

def load_custom_writeObject(self, parser, reader, name):
# type: (JavaStreamParser, DataStreamReader, str) -> Optional[JavaClassDesc]
"""
Reads content stored from a custom writeObject.

Expand All @@ -91,6 +92,6 @@ def load_custom_writeObject(self, parser, reader, name):
:param parser: The JavaStreamParser in use
:param reader: The data stream reader
:param name: The class description name
:return: An array with the parsed fields or None
:return: A JavaClassDesc instance or None
"""
return None
19 changes: 13 additions & 6 deletions javaobj/v2/beans.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,20 @@ def fields_types(self):

@property
def data_type(self):
if (ClassDescFlags.SC_SERIALIZABLE & self.desc_flags):
return ClassDataType.WRCLASS if (ClassDescFlags.SC_WRITE_METHOD & self.desc_flags) else ClassDataType.NOWRCLASS
elif (ClassDescFlags.SC_EXTERNALIZABLE & self.desc_flags):
return ClassDataType.OBJECT_ANNOTATION if (ClassDescFlags.SC_WRITE_METHOD & self.desc_flags) else ClassDataType.EXTERNAL_CONTENTS

if ClassDescFlags.SC_SERIALIZABLE & self.desc_flags:
return (
ClassDataType.WRCLASS
if (ClassDescFlags.SC_WRITE_METHOD & self.desc_flags)
else ClassDataType.NOWRCLASS
)
elif ClassDescFlags.SC_EXTERNALIZABLE & self.desc_flags:
return (
ClassDataType.OBJECT_ANNOTATION
if (ClassDescFlags.SC_WRITE_METHOD & self.desc_flags)
else ClassDataType.EXTERNAL_CONTENTS
)

raise ValueError("Unhandled Class Data Type")


def is_array_class(self):
# type: () -> bool
Expand Down
74 changes: 55 additions & 19 deletions javaobj/v2/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def _do_null(self, _):
return None

def _read_content(self, type_code, block_data, class_desc=None):
# type: (int, bool) -> ParsedJavaContent
# type: (int, bool, Optional[JavaClassDesc]) -> ParsedJavaContent
"""
Parses the next content
"""
Expand All @@ -294,9 +294,12 @@ def _read_content(self, type_code, block_data, class_desc=None):
# Look for a handler for that type code
handler = self.__type_code_handlers[type_code]
except KeyError:
'''Looking for an external reader'''
# Look for an external reader
if class_desc and class_desc.data_type == ClassDataType.WRCLASS:
# Return its result immediately
return self._custom_readObject(class_desc.name)

# No valid custom reader: abandon
raise ValueError("Unknown type code: 0x{0:x}".format(type_code))
else:
try:
Expand Down Expand Up @@ -348,7 +351,7 @@ def _read_classdesc(self):
return self._do_classdesc(type_code)

def _do_classdesc(self, type_code):
# type: (int, bool) -> JavaClassDesc
# type: (int) -> JavaClassDesc
"""
Parses a class description
"""
Expand All @@ -359,7 +362,6 @@ def _do_classdesc(self, type_code):
handle = self._new_handle()
desc_flags = self.__reader.read_byte()
nb_fields = self.__reader.read_short()

if nb_fields < 0:
raise ValueError("Invalid field count: {0}".format(nb_fields))

Expand All @@ -378,9 +380,9 @@ def _do_classdesc(self, type_code):
"Invalid field type char: 0x{0:x}".format(field_type)
)

fields.append(JavaField(
FieldType(field_type), field_name, class_name
))
fields.append(
JavaField(FieldType(field_type), field_name, class_name)
)

# Setup the class description bean
class_desc = JavaClassDesc(ClassDescType.NORMALCLASS)
Expand Down Expand Up @@ -424,18 +426,27 @@ def _do_classdesc(self, type_code):

raise ValueError("Expected a valid class description starter")


def _custom_readObject(self, class_name):
# type: (str) -> ParsedJavaContent
"""
Reads an object with a custom serialization process

:param class_name: Name of the class to load
:return: The parsed object
:raise ValueError: Unknown kind of class
"""
self.__fd.seek(-1, os.SEEK_CUR)
for transformer in self.__transformers:
class_data = transformer.load_custom_writeObject(self, self.__reader, class_name)
class_data = transformer.load_custom_writeObject(
self, self.__reader, class_name
)
if class_data:
return class_data

raise ValueError("Custom readObject can not be processed")



def _read_class_annotations(self, class_desc=None):
# type: () -> List[ParsedJavaContent]
# type: (Optional[JavaClassDesc]) -> List[ParsedJavaContent]
"""
Reads the annotations associated to a class
"""
Expand Down Expand Up @@ -500,8 +511,19 @@ def _do_object(self, type_code=0):
return instance

def _is_default_supported(self, class_name):
default_transf = [x for x in self.__transformers if isinstance(x, DefaultObjectTransformer)]
return len(default_transf) and class_name in default_transf[0]._type_mapper
# type: (str) -> bool
"""
Checks if this class is supported by the default object transformer
"""
default_transf = [
x
for x in self.__transformers
if isinstance(x, DefaultObjectTransformer)
]
return (
bool(default_transf)
and class_name in default_transf[0]._type_mapper
)

def _read_class_data(self, instance):
# type: (JavaInstance) -> None
Expand All @@ -518,11 +540,23 @@ def _read_class_data(self, instance):
for cd in classes:
values = {} # type: Dict[JavaField, Any]
cd.validate()
if cd.data_type == ClassDataType.NOWRCLASS or cd.data_type == ClassDataType.WRCLASS:
read_custom_data = cd.data_type == ClassDataType.WRCLASS and cd.is_super_class and not self._is_default_supported(cd.name)
if read_custom_data or cd.data_type == ClassDataType.WRCLASS and instance.is_external_instance:
if (
cd.data_type == ClassDataType.NOWRCLASS
or cd.data_type == ClassDataType.WRCLASS
):
read_custom_data = (
cd.data_type == ClassDataType.WRCLASS
and cd.is_super_class
and not self._is_default_supported(cd.name)
)

if (
read_custom_data
or cd.data_type == ClassDataType.WRCLASS
and instance.is_external_instance
):
annotations[cd] = self._read_class_annotations(cd)
else:
else:
for field in cd.fields:
values[field] = self._read_field_value(field.type)
all_data[cd] = values
Expand Down Expand Up @@ -574,7 +608,9 @@ def _read_field_value(self, field_type):
if sub_type_code == TerminalCode.TC_REFERENCE:
return self._do_classdesc(sub_type_code)
elif sub_type_code != TerminalCode.TC_ARRAY:
raise ValueError("Array type listed, but type code != TC_ARRAY")
raise ValueError(
"Array type listed, but type code != TC_ARRAY"
)

content = self._read_content(sub_type_code, False)
if content is not None and content.is_exception:
Expand Down
2 changes: 1 addition & 1 deletion javaobj/v2/transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

# Javaobj
from .api import ObjectTransformer
from .beans import JavaInstance
from .beans import JavaInstance, JavaClassDesc, BlockData
from ..constants import TerminalCode, TypeCode
from ..utils import to_bytes, log_error, log_debug, read_struct, read_string

Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.