Skip to content

feat: Add string-level highlighting in hex view and sync highlight to matching section string entries#8

Open
harkerhand wants to merge 2 commits intorbakbashev:masterfrom
harkerhand:master
Open

feat: Add string-level highlighting in hex view and sync highlight to matching section string entries#8
harkerhand wants to merge 2 commits intorbakbashev:masterfrom
harkerhand:master

Conversation

@harkerhand
Copy link

@harkerhand harkerhand commented Mar 22, 2026

The current implementation already has section-level highlighting, but it lacks finer-grained visualization for string-dense areas (such as string tables). I have provided secondary string highlighting and added the linkage between the left-side Hex highlighting and the section detail strings on the right.

An example is shown in the figure below (blue style) :

image

…ices; enhance string table range handling

js: add highlighting functionality for strtab sections
report_gen: modify string table generation to include section and string indices; escape HTML characters
style: add styles for strtab entries and active highlighting
Copilot AI review requested due to automatic review settings March 22, 2026 08:42
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds finer-grained highlighting for ELF string table content by introducing per-string ranges in the hex view and synchronizing hover highlighting to corresponding string entries in the section details panel.

Changes:

  • Add a new RangeType::StrtabString(section_idx, str_idx) and generate per-string ranges for SHT_STRTAB sections.
  • Emit per-string <span> entries in the STRTAB section detail table (with HTML escaping) and link them to hex-view ranges via shared strtab_ref{section}_{str} classes.
  • Add JS + CSS to sync hover state from hex-view string spans to the matching STRTAB entries.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
src/style.css Adds styles for STRTAB string hover and active entry highlighting.
src/report_gen.rs Adds HTML escaping and emits per-string STRTAB entries with reference classes; wires in new sync-highlighting JS.
src/js/highlight.js Adds document-level hover handler to activate matching STRTAB entries based on hex-view hover target.
src/elf/parser.rs Introduces StrtabString range type and populates per-string ranges for SHT_STRTAB sections.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 311 to 315
if *c == 0 {
let end = if curr_start == 0 { 0 } else { i - 1 };

let maybe = std::str::from_utf8(&section[curr_start..=end]);

Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_strtab_data can panic on valid string tables containing consecutive \0 bytes (empty strings/padding). When i == curr_start and curr_start != 0, end becomes i - 1, making the inclusive slice section[curr_start..=end] invalid (start > end). Consider skipping empty strings before slicing, and avoid the special-casing of curr_start == 0 so the first (potentially non-empty) string is handled correctly too.

Copilot uses AI. Check for mistakes.
Comment on lines +318 to +326
w!(
o,
9,
"<span class='strtab_entry strtab_ref{}_{}'>{}</span>",
section_idx,
str_idx,
escape_html_str(string)
);
str_idx += 1;
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add_strtab_ranges() (parser side) adds a final string range when the section doesn't end with \0, but this renderer only emits entries when it hits a NUL terminator. That can leave highlighted .strtab_str ranges with no matching .strtab_entry (sync highlight no-ops). Consider emitting a final entry after the loop when curr_start < section.len() to match the range-generation behavior.

Copilot uses AI. Check for mistakes.
Comment on lines 316 to 328
if let Ok(string) = maybe {
if section[curr_start] != 0 {
w!(o, 9, "{}", string);
w!(
o,
9,
"<span class='strtab_entry strtab_ref{}_{}'>{}</span>",
section_idx,
str_idx,
escape_html_str(string)
);
str_idx += 1;
}
}
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sync-highlighting is keyed off str_idx, but this code only emits .strtab_entry elements for strings where std::str::from_utf8(...) succeeds. add_strtab_ranges() will still create .strtab_str spans for non-UTF8 byte sequences, so hovering those bytes won't highlight anything on the right. Consider rendering non-UTF8 strings using a lossless/escaped representation (e.g., from_utf8_lossy or hex-escaped bytes) so every highlighted range has a corresponding entry.

Copilot uses AI. Check for mistakes.
Comment on lines +295 to +297
fn add_strtab_ranges(&mut self) {
let mut str_ranges: Vec<(usize, usize, u16, u32)> = Vec::new();

Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add_strtab_ranges builds a Vec of all string ranges (str_ranges) and then iterates again to add them to self.ranges. This can double memory usage for large string tables. You can usually avoid the temporary vector by borrowing disjoint fields (let (ranges, shdrs, contents) = (&mut self.ranges, &self.shdrs, self.contents);) and calling ranges.add_range(...) directly while iterating.

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +71
document.addEventListener("mouseover", function(event) {
let refClass = getRefClass(event.target);

clearActiveEntries();

if (refClass === null) {
return;
}

let entries = document.querySelectorAll(".strtab_entry." + refClass);

for (let entry of entries) {
entry.classList.add("strtab_entry_active");
activeEntries.push(entry);
}
}, false);
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a document-level mouseover handler that runs on every mouseover anywhere in the page, clearing/re-adding classes and doing a querySelectorAll each time. On large dumps this can become a noticeable hotspot. Consider either (1) using event delegation but tracking the last refClass and returning early when it hasn't changed, and/or (2) attaching mouseenter/mouseleave listeners only to .strtab_str elements and pre-indexing .strtab_entry nodes by refClass.

Copilot uses AI. Check for mistakes.
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