Expand description
Keeping untrusted text from becoming terminal commands.
datui displays text it did not write: cell values, column names, filenames,
and parser error messages all originate in whatever file the user opened.
A terminal does not distinguish text from commands, so a cell containing
\x1b]52;c;...\x07 is a clipboard write, and one containing \x1b[2J wipes
the screen. That is the standard vulnerability class for any program that
renders foreign text.
ratatui defends against this in Buffer::set_stringn, which drops
graphemes containing control characters. It does not defend against it
in Span and Line rendering, which is what almost everything actually
uses: Span::render_ref appends zero-width graphemes to the preceding cell,
and an ESC is zero-width. The crossterm backend then writes each cell symbol
out with Print, unfiltered, and the escape reaches the terminal intact.
Sanitising at the roughly two hundred places that build a Span would work
until someone adds the two hundred and first. So the sweep happens once, at
the end of App::render, over the finished buffer. Every path into the
screen has converged by then, including paths added later and paths nobody
remembered to audit.
Functionsยง
- sanitize_
buffer - Replaces control characters in every cell of a finished buffer.
- sanitized
- Returns a display-safe copy of
s, orNoneif it was already safe.