Skip to content

Show text-based resources inline with syntax highlighting#3861

Merged
siegfriedpammer merged 1 commit into
masterfrom
worktree-text-resource-detection
Jul 5, 2026
Merged

Show text-based resources inline with syntax highlighting#3861
siegfriedpammer merged 1 commit into
masterfrom
worktree-text-resource-detection

Conversation

@siegfriedpammer

@siegfriedpammer siegfriedpammer commented Jul 4, 2026

Copy link
Copy Markdown
Member

What

Textual assembly resources (JSON, XML, Markdown, plain text, ...) previously rendered as an opaque byte count with only a Save button. They now display inline in the decompiler text view with the correct syntax highlighting.

Detection

New TextResourceDetector.TryDetectText:

  • Text vs binary: size cap (10 MB, checked before any I/O), BOM-aware decoding (UTF-8/16/32), strict UTF-8 for BOM-less payloads; any decode failure, NUL, DEL, U+FFFD, or control character outside tab/CR/LF/FF marks the payload binary.
  • Format: a whitelist maps resource-name extensions to highlighting extensions (the XML family -> ILSpy's XML mode; .json/.md/.js/.css/.html/.py/.sql/.ps1/... -> AvaloniaEdit built-ins). Unknown or missing extensions are content-sniffed: leading < is XML (or HTML on <!DOCTYPE html/<html), and {/[ payloads are parsed with JsonDocument before claiming JSON. Everything else displays as plain text.

Display

The generic resource nodes (ResourceEntryNode, ResourceTreeNode) render detected text as the view's whole content and set SyntaxExtensionOverride accordingly, mirroring how the XML/XAML nodes present theirs. Binary resources keep the byte-count-plus-Save presentation unchanged.

Container routing

.resources and !AvaloniaResources containers unpack their entries as raw byte arrays. ResourceEntryNode.Create(string, byte[]) now dispatches those through the same IResourceNodeFactory pipeline as top-level resources, so a nested .baml gets the BAML view, an image its viewer, and so on, instead of the generic byte node. Both container views also list their entries by name.

Theming

HighlightingService.GetByExtension registers whatever definition it resolves with the theme manager, so AvaloniaEdit's built-in definitions (JSON, Markdown, ...) follow the dark theme like the bundled ones.

Tests

TDD throughout. 31 new tests in TextResourceDetectionTests (encodings, binary rejection, no-read guarantee for oversized payloads, extension mapping, content sniffing, node-level rendering) plus factory-routing and entry-listing tests in ResourceFactoryTests. Full ILSpy.Tests suite green (1013/1013). Verified in the running app on Linux against a mixed-resource fixture and a real !AvaloniaResources bundle.

A security review of the branch (untrusted resource bytes/names) found no exploitable issues: no XML parsing of resource content (prefix sniff only, no XXE), JsonDocument is a pure syntactic parser behind a size cap, attacker-controlled names reach only a literal whitelist, and no new file I/O. Nested-container reachability was checked and does not auto-recurse (resource nodes return FilterResult.Match) and cannot nest infinitely (each level is a strict sub-slice of its parent).

This PR was authored by an AI agent (Claude Code) operated by @siegfriedpammer and reviewed and manually verified by him.

🤖 Generated with Claude Code

Textual assembly resources (JSON, XML, Markdown, plain text, ...) rendered
as an opaque byte count with only a Save button. Detect text vs binary from
the payload (size cap, BOM-aware decoding, strict UTF-8, rejecting control
characters) and pick a highlighting extension by resource-name extension,
falling back to content sniffing (angle-bracket for XML/HTML, an actual
JsonDocument parse for JSON) when the extension is unknown. Text renders as
the view's whole content with the matching highlighting; binary keeps the
byte-count-plus-Save presentation.

Container resources unpack their entries as raw byte arrays. Route those
through the same IResourceNodeFactory pipeline as top-level resources so a
nested .baml gets the BAML view, an image its viewer, and so on, instead of
the generic byte node; the .resources and !AvaloniaResources views also list
their entries by name. Register built-in AvaloniaEdit definitions (JSON,
Markdown, ...) with the theme manager on lookup so they follow the dark
theme like the bundled ones.

Assisted-by: Claude:claude-fable-5:Claude Code
@siegfriedpammer
siegfriedpammer merged commit 93a1653 into master Jul 5, 2026
13 checks passed
@siegfriedpammer
siegfriedpammer deleted the worktree-text-resource-detection branch July 7, 2026 13:50
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.

1 participant