Repository navigation
fix(output,tui): neutralize control sequences and markup in server text (#206) - #207
Merged
Merged
Conversation
…xt (#206) Rich's escape() only stops [..] markup, and Rich/Textual strip just BEL, BS, VT, FF and CR, so ESC sequences and bidi overrides in NetBox data reached the terminal (retitle/clear it, spoof text). Move the sanitizer to nsc/output/sanitize.py (printable, safe_markup, safe_text) and apply it to table cells and headers (headers were not escaped at all), the --explain panel, error panels, and the TUI: list and detail cells, record picker labels, error notifications, and diff views. TUI cells are now Text, not str: DataTable/Label parsed str as markup, so a value like `[red]x[/]` was styled and lost its brackets. Claude-Session: https://claude.ai/code/session_01RD8NgCVtp3yYFd6NSZpbUb
Review of #207 found more widgets that parse a str label as markup and take server text: global-search tree leaves, FK buttons in the edit, bulk-edit and filter forms (initial label and after picking), and the column chooser (whose literal "[x]" mark was itself parsed as markup). Claude-Session: https://claude.ai/code/session_01RD8NgCVtp3yYFd6NSZpbUb
Owner
Author
|
Pushed 6d58c2f: review found more markup-parsing sinks with server text (global search leaves, FK buttons in edit/bulk-edit/filter forms, column chooser). All now |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #206.
Rich's
escape()only stops[..]markup, and Rich and Textual strip just BEL, BS, VT, FF and CR. ESC sequences, other C0/C1 controls and bidi overrides in NetBox data therefore reached the terminal: an object name could retitle or clear it, or spoof text.Shared helper:
nsc/output/sanitize.py, moved out oferrors.pyfrom #205:printable()shows control and format characters as\x../\u..... Newlines, tabs and ordinary Unicode are kept.safe_markup()=escape(printable(...)), for markup strings.safe_text()builds aText, for widgets that would parse astras markup.Applied to:
--explainpanel and the error panel.api_error_message, used by everynotify, which parses markup;TUI markup injection, found along the way: Textual's
DataTableandLabelparse a plainstras markup. A NetBox value[bold red]x[/]showed as a bold red "x" with its brackets gone. TUI cells are nowText, so they render literally. I confirmed this in a headless Textual run before the change. Four existing tests asserted the old "cells are plainstr" contract; I updated them to compare.plain.Out of scope: JSON, JSONL, YAML and CSV output (escaped or quoted, or not for a terminal). TUI titles, form labels and filter chips, which hold schema names or the user's own input.
Tests:
tests/output/test_sanitize.py: the helper; table cells and headers with color on and off; headers not parsed as markup; the explain panel.tests/tui/test_sanitize_tui.py:render_cell,api_error_message, detail-screen cells, record-picker labels.The new tests failed before the fix.
https://claude.ai/code/session_01RD8NgCVtp3yYFd6NSZpbUb