Goal
Make text, CSV, and TSV rendering honor the documented control-character sanitization contract and resist terminal-direction spoofing.
Background
_table_cell() deliberately preserves tab and accepts every Unicode character above ASCII space except DEL. It therefore retains C1 controls and format controls such as U+202E RIGHT-TO-LEFT OVERRIDE. _display_width() then assigns format controls zero width while the output still emits them, so alignment and visual order can differ from the measured content. Tabs also expand unpredictably in terminal tables.
docs/output-contracts.md says ANSI escapes and other control characters are replaced with spaces.
Reproduction and evidence
Framework reference: 263d893 on main.
Rendering one terminal row with name="safe\u202eexe" and path="left\tright" produces:
'NAME PATH\nsafe\u202eexe left\tright\n'
Both the bidi override and tab remain in emitted terminal content. CSV/TSV pass through the same sanitizer; quoting protects record framing but contradicts the stated replacement rule.
Scope
- Replace C0, C1, and relevant Unicode
Cc/Cf controls with safe spaces in human and delimited cells.
- Treat tab consistently with the documented contract.
- Measure/truncate the sanitized representation only.
- Apply the same sanitized rows to built-in and Rich rendering.
- Add tests for tab, C1 controls, bidi isolates/overrides, ANSI, newline, and combining/wide characters.
Acceptance criteria
- Rendered cells contain no terminal control or bidi-format characters.
- Display-width calculation matches the emitted text.
- A cell cannot visually reverse or reorder adjacent table content.
- CSV/TSV stay one-record-per-line and remain parseable with the standard
csv module.
- Documentation and tests agree on the exact sanitizer contract.
Project fields
- Status: Backlog
- Priority: P1
- Area: Security
- Initiative: v1.0 Readiness
- Size: S
Ownership
Goal
Make text, CSV, and TSV rendering honor the documented control-character sanitization contract and resist terminal-direction spoofing.
Background
_table_cell()deliberately preserves tab and accepts every Unicode character above ASCII space except DEL. It therefore retains C1 controls and format controls such as U+202E RIGHT-TO-LEFT OVERRIDE._display_width()then assigns format controls zero width while the output still emits them, so alignment and visual order can differ from the measured content. Tabs also expand unpredictably in terminal tables.docs/output-contracts.mdsays ANSI escapes and other control characters are replaced with spaces.Reproduction and evidence
Framework reference:
263d893onmain.Rendering one terminal row with
name="safe\u202eexe"andpath="left\tright"produces:'NAME PATH\nsafe\u202eexe left\tright\n'Both the bidi override and tab remain in emitted terminal content. CSV/TSV pass through the same sanitizer; quoting protects record framing but contradicts the stated replacement rule.
Scope
Cc/Cfcontrols with safe spaces in human and delimited cells.Acceptance criteria
csvmodule.Project fields
Ownership