fix rootzip

This commit is contained in:
silverweed 2024-09-27 16:23:50 +02:00
parent fe924743ef
commit 9ecc970aff

View file

@ -129,7 +129,7 @@ enum Hover_Section_Flags {
// Functor used by get_section_hover_info to describe the structure of a section and print data about it. // Functor used by get_section_hover_info to describe the structure of a section and print data about it.
struct Sec_Hover_Fn { struct Sec_Hover_Fn {
u64 off; // the offset relative to the start of `data` u64 off; // the hovered offset relative to the start of `data`
const u8 *data; // the entire file data const u8 *data; // the entire file data
const Section &section; const Section &section;
Arena *arena; Arena *arena;
@ -139,6 +139,17 @@ struct Sec_Hover_Fn {
u8 cur_section_nesting = 0; u8 cur_section_nesting = 0;
u8 innermost_section_highlighted = 0; u8 innermost_section_highlighted = 0;
template <typename T>
b8 read(T *val, u64 offset, u64 *size = nullptr) const
{
u64 nb = size ? *size : sizeof(T);
if (offset + nb > section.range.end())
return false;
memcpy(val, data + offset, nb);
return true;
}
template <typename F> template <typename F>
void titled_section(const char *title, F &&sec_body_fn, u64 flags = 0) void titled_section(const char *title, F &&sec_body_fn, u64 flags = 0)
{ {
@ -186,7 +197,9 @@ struct Sec_Hover_Fn {
b8 hovered = cur_field_off <= off && off < cur_field_off + field_len; b8 hovered = cur_field_off <= off && off < cur_field_off + field_len;
T val; T val;
memcpy(&val, (u8 *)data + cur_field_off, field_len); if (!read(&val, cur_field_off))
return false;
String8_Node *desc = display_val(arena, info.desc, desc_fmt, val); String8_Node *desc = display_val(arena, info.desc, desc_fmt, val);
if (hovered && !display_grouped) if (hovered && !display_grouped)
info.highlighted_desc = desc; info.highlighted_desc = desc;
@ -205,7 +218,9 @@ struct Sec_Hover_Fn {
{ {
// String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple). // String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple).
TStrSize str_size; TStrSize str_size;
memcpy(&str_size, data + cur_field_off, sizeof(TStrSize)); if (!read(&str_size, cur_field_off))
return;
// DEBUG // DEBUG
if (str_size > 1000) { if (str_size > 1000) {
printf("read str_size = %u at offset 0x%lX!\n", str_size, cur_field_off); printf("read str_size = %u at offset 0x%lX!\n", str_size, cur_field_off);
@ -215,7 +230,10 @@ struct Sec_Hover_Fn {
b8 hovered = cur_field_off <= off && off < cur_field_off + field_len; b8 hovered = cur_field_off <= off && off < cur_field_off + field_len;
u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1); u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1);
memcpy(buf, data + cur_field_off + sizeof(TStrSize), str_size); u64 size_to_read = str_size;
if (!read(buf, cur_field_off + sizeof(TStrSize), &size_to_read))
return;
buf[str_size] = 0; buf[str_size] = 0;
String8 s = { buf, str_size }; String8 s = { buf, str_size };
String8_Node *desc = display_val(arena, info.desc, desc_fmt, s); String8_Node *desc = display_val(arena, info.desc, desc_fmt, s);
@ -244,6 +262,8 @@ struct Sec_Hover_Fn {
void range(const char *desc, u64 range_len, Display_Range_Fn display_val = hover_display_generic_range) void range(const char *desc, u64 range_len, Display_Range_Fn display_val = hover_display_generic_range)
{ {
b8 hovered = cur_field_off <= off && off < cur_field_off + range_len; b8 hovered = cur_field_off <= off && off < cur_field_off + range_len;
if (cur_field_off + range_len > section.range.end())
return;
String8_Node *dsc = display_val(arena, info.desc, desc, data + cur_field_off, range_len); String8_Node *dsc = display_val(arena, info.desc, desc, data + cur_field_off, range_len);
if (hovered && !display_grouped) if (hovered && !display_grouped)
info.highlighted_desc = dsc; info.highlighted_desc = dsc;
@ -257,13 +277,15 @@ struct Sec_Hover_Fn {
// Returns true if `was_zipped` was read. // Returns true if `was_zipped` was read.
b8 maybe_rootzip(b8 *was_zipped = nullptr) b8 maybe_rootzip(b8 *was_zipped = nullptr)
{ {
// TODO boundary checks
const u64 range_len = 9; const u64 range_len = 9;
if (cur_field_off + range_len > section.range.end())
return false;
b8 hovered = cur_field_off <= off && off < cur_field_off + range_len; b8 hovered = cur_field_off <= off && off < cur_field_off + range_len;
if (display_val_rootzip(arena, info.desc, "Zipped Block", data + cur_field_off)) { if (display_val_rootzip(arena, info.desc, "Zipped Block", data + cur_field_off)) {
if (display_grouped || hovered) {
if (was_zipped) if (was_zipped)
*was_zipped = true; *was_zipped = true;
if (display_grouped || hovered) {
info.rng = { cur_field_off, range_len }; info.rng = { cur_field_off, range_len };
if (hovered) if (hovered)
info.highlighted_desc = info.desc; info.highlighted_desc = info.desc;
@ -280,7 +302,9 @@ struct Sec_Hover_Fn {
{ {
titled_section(title, [this] { titled_section(title, [this] {
u16 version_be; u16 version_be;
memcpy(&version_be, data + cur_field_off + 4, sizeof(u16)); if (!read(&version_be, cur_field_off + 4))
return;
u32 version = bswap(version_be); u32 version = bswap(version_be);
b8 is_big = version > 1000; b8 is_big = version > 1000;
@ -318,7 +342,7 @@ struct Sec_Hover_Fn {
range("Envelope size: %s", 6, [] (Arena *arena, String8_Node *prev, const char *fmt, const u8 *payload, u64) { range("Envelope size: %s", 6, [] (Arena *arena, String8_Node *prev, const char *fmt, const u8 *payload, u64) {
u64 size; u64 size;
memcpy(&size, payload, 6); memcpy(&size, payload, 6);
return push_str8_node_child(arena, prev, fmt, to_pretty_size(arena, size)); return push_str8_node_child(arena, prev, fmt, to_pretty_size(arena, size).c());
}); });
}); });
} }
@ -335,7 +359,11 @@ struct Sec_Hover_Fn {
Frame_Type frame_type = Frame_INVALID; Frame_Type frame_type = Frame_INVALID;
titled_section(titlestr.c(), [this, &frame_type, &frame_size = size, n_items] { titled_section(titlestr.c(), [this, &frame_type, &frame_size = size, n_items] {
i64 size; i64 size;
memcpy(&size, data + cur_field_off, sizeof(size)); if (!read(&size, cur_field_off)) {
frame_size = 0;
frame_type = Frame_INVALID;
return;
}
// Sanity check // Sanity check
if (size > 1000000) { if (size > 1000000) {
fprintf(stderr, "Frame size read at 0x%" PRIX64 " looks bogus" fprintf(stderr, "Frame size read at 0x%" PRIX64 " looks bogus"
@ -357,7 +385,11 @@ struct Sec_Hover_Fn {
frame_type = Frame_INVALID; frame_type = Frame_INVALID;
} else { } else {
frame_type = Frame_List; frame_type = Frame_List;
memcpy(n_items, data + cur_field_off + sizeof(i64), sizeof(u32)); if (!read(n_items, cur_field_off + sizeof(i64))) {
frame_size = 0;
frame_type = Frame_INVALID;
return;
}
field<i64>("List frame size: %" PRIi64 " B", hover_display_val_le_abs<i64>); field<i64>("List frame size: %" PRIi64 " B", hover_display_val_le_abs<i64>);
field_le<u32>("List frame n.items: %u"); field_le<u32>("List frame n.items: %u");
} }
@ -625,7 +657,8 @@ struct Sec_Hover_Fn {
{ {
titled_section("TFile Header", [this] { titled_section("TFile Header", [this] {
u32 root_version_be; u32 root_version_be;
memcpy(&root_version_be, data + cur_field_off + 4, sizeof(u32)); if (!read(&root_version_be, cur_field_off + 4))
return;
u32 root_version = bswap(root_version_be); u32 root_version = bswap(root_version_be);
b8 is_big = root_version > 1000'000; b8 is_big = root_version > 1000'000;
@ -665,7 +698,8 @@ struct Sec_Hover_Fn {
field_str8<u8>("File Title: %s"); field_str8<u8>("File Title: %s");
u16 version_be; u16 version_be;
memcpy(&version_be, data + cur_field_off, sizeof(u16)); if (!read(&version_be, cur_field_off))
return;
u16 version = bswap(version_be); u16 version = bswap(version_be);
b8 is_big = version > 1000; b8 is_big = version > 1000;
@ -721,7 +755,8 @@ struct Sec_Hover_Fn {
titled_section("TFile FreeList", [this] { titled_section("TFile FreeList", [this] {
tkey(); tkey();
u16 version_be; u16 version_be;
memcpy(&version_be, data + cur_field_off, sizeof(u16)); if (!read(&version_be, cur_field_off))
return;
u32 version = bswap(version_be); u32 version = bswap(version_be);
b8 is_big = version > 1000; b8 is_big = version > 1000;