Skip to content

impr: Refuse invalid Data Inspector edits and guard against decode crashes - #2904

Open
scottanderson wants to merge 6 commits into
WerWolv:masterfrom
scottanderson:data-inspector-edit-safety
Open

scottanderson wants to merge 6 commits into
WerWolv:masterfrom
scottanderson:data-inspector-edit-safety

Conversation

@scottanderson

Copy link
Copy Markdown
Contributor

Problem

A Data Inspector row could not differentiate "no bytes" from "invalid input", so bad input committed an empty value instead of being refused.

A row's display or edit function can also throw: a custom inspector runs pattern language code, and a pattern-backed row can decode invalid bytes. The throw crossed ImGui's style and table stacks, leaving them unbalanced and crashing ImHex.

Implementation

Return std::optional from EditWidget::Widget::Function and hex::decodeByteString(). Invalid text keeps edit mode open with a red border, checked on every keystroke. Trim the edit buffer to the typed length each frame, so it cannot grow without bound.

Catch at each site that can throw, log, and show "Invalid". The pattern tree's "Copy Value" also calls toString() inside a table, so guard that too.

A plain byte vector could not tell "no bytes" from "invalid input".
Bad input committed an empty value instead of being refused.

Return std::optional instead. Invalid text keeps edit mode open with
a red border, checked on every keystroke.

Trim the edit buffer to the typed length each frame, so it cannot
grow without bound.
A Data Inspector row's display or edit function can throw: a custom
inspector runs pattern language code, and a pattern-backed row can
decode invalid bytes. The throw crossed ImGui's style/table stacks,
leaving them unbalanced.

Catch at each site, log, and show "Invalid". The pattern tree's "Copy
Value" also calls toString() inside a table, so guard that too.
Comment thread plugins/builtin/source/content/views/view_data_inspector.cpp
Comment thread lib/libimhex/source/api/content_registry.cpp Outdated
TextInput::draw() resized its buffer every frame, whatever the user
typed. Register ImGuiInputTextFlags_CallbackResize instead, the same
pattern ImGuiExt::UpdateStringSizeCallback already uses elsewhere: the
callback grows the buffer only when ImGui runs out of room for what
was typed.

This also drops the frame-by-frame `value = value.c_str()` trim; the
callback keeps `value`'s size exact, so nothing grows unbounded to
trim in the first place.
The comment called it a guard against pattern language code, but a
pattern-backed row never re-enters the runtime here: its value comes
from a cache executeInspector() already filled in, a failed formatter
surfaces through hasValidFormattedValue() rather than a throw, and a
visualizer catches and renders its own failure. The catch backstops a
ContentRegistry::DataInspector::add() display function instead, which
is arbitrary C++ and can still throw for other reasons.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants