Fix up JSON rendering of hex bytes and LayerData

This commit is contained in:
Mike Auty
2025-04-01 23:14:03 +01:00
parent 9791ae5878
commit e2fb96a0d3
+44 -33
View File
@@ -159,42 +159,12 @@ class LayerDataRenderer(CLITypeRenderer):
def render(
data: Union[renderers.LayerData, interfaces.renderers.BaseAbsentValue],
):
) -> str:
if isinstance(data, interfaces.renderers.BaseAbsentValue):
# FIXME: Do something cleverer here
return ""
context_byte_len = self.context_byte_len if not data.no_surrounding else 0
layer = data.context.layers[data.layer_name]
# Map of the holes
error_bytes = set()
start_offset = data.offset - context_byte_len
end_offset = data.offset + data.length + context_byte_len
if isinstance(layer, interfaces.layers.TranslationLayerInterface):
error_bytes = set()
mapping = iter(layer.mapping(start_offset, end_offset, True))
current_map = next(mapping)
for i in range(start_offset, end_offset):
# Run through the bytes, check if they're present
offset, sublength, _, _, _ = current_map
if i < offset:
error_bytes.add(i - start_offset)
if i > offset + sublength:
try:
current_map = next(mapping)
except StopIteration:
pass
offset, sublength, _, _, _ = current_map
if i > offset + sublength:
error_bytes.add(i - start_offset)
# Padded data
specific_data = data.context.layers[data.layer_name].read(
start_offset,
end_offset - start_offset,
True,
)
specific_data, error_bytes = self.render_bytes(data)
printables = ""
output = "\n"
@@ -224,6 +194,46 @@ class LayerDataRenderer(CLITypeRenderer):
render_func = render
return super().__init__(render_func)
def render_bytes(self, data: renderers.LayerData) -> tuple[bytes, set[int]]:
"""Renders a valid LayerData into bytes (with context bytes)"""
context_byte_len = self.context_byte_len if not data.no_surrounding else 0
layer = data.context.layers[data.layer_name]
# Map of the holes
error_bytes = set()
start_offset = data.offset - context_byte_len
end_offset = data.offset + data.length + context_byte_len
if isinstance(layer, interfaces.layers.TranslationLayerInterface):
error_bytes = set()
mapping = iter(layer.mapping(start_offset, end_offset, True))
current_map = next(mapping)
for i in range(start_offset, end_offset):
# Run through the bytes, check if they're present
offset, sublength, _, _, _ = current_map
if i < offset:
error_bytes.add(i - start_offset)
if i > offset + sublength:
try:
current_map = next(mapping)
except StopIteration:
pass
offset, sublength, _, _, _ = current_map
if i > offset + sublength:
error_bytes.add(i - start_offset)
# Padded data
specific_data = data.context.layers[data.layer_name].read(
start_offset,
end_offset - start_offset,
True,
)
import pdb
pdb.set_trace()
return specific_data, error_bytes
class CLIRenderer(interfaces.renderers.Renderer):
"""Class to add specific requirements for CLI renderers."""
@@ -525,9 +535,10 @@ class PrettyTextRenderer(CLIRenderer):
class JsonRenderer(CLIRenderer):
_type_renderers = {
format_hints.HexBytes: quoted_optional(hex_bytes_as_text),
format_hints.HexBytes: lambda x: x.hex(" "),
renderers.Disassembly: quoted_optional(display_disassembly),
format_hints.MultiTypeData: quoted_optional(multitypedata_as_text),
renderers.LayerData: lambda x: LayerDataRenderer().render_bytes(x)[0].hex(" "),
bytes: optional(lambda x: " ".join(f"{b:02x}" for b in x)),
datetime.datetime: lambda x: (
x.isoformat()