Raxol.Core.Boundary.TermText (Raxol Core v2.7.0)

Copy Markdown View Source

Terminal-injection confinement: neutralize ESC/ANSI/control bytes in untrusted text before it reaches the terminal renderer.

One of the two centralized boundary confinements (PR #569 thread 2); the other is Raxol.Core.Boundary.Path (path-traversal). This one has byte-stream semantics — a total function over binaries, no filesystem, never errors, never passes a dangerous byte through. It enforces the repo rule "never embed raw ANSI codes in strings passed to text()" at the untrusted boundary instead of trusting upstream.

What sanitize/2 strips

In a single left-to-right pass:

  • ESC (0x1B) and every sequence it introduces — CSI (ESC [ … final 0x40..0x7E), OSC (ESC ] … BEL/ST; kills title-set and OSC-8 hyperlink smuggling), DCS/APC/PM/SOS (ESC P/ESC _/ESC ^/ESC X … ST), two-byte ESC <c> forms, and a truncated trailing ESC.
  • C0 controls (0x00..0x1F) except the :allow list (default [?\n]).
  • DEL (0x7F) and raw C1 controls (0x80..0x9F).
  • Invalid UTF-8 bytes → replaced with U+FFFD (never emit a broken sequence downstream). Raw C1 bytes are stripped (not replaced); other invalid bytes become U+FFFD.

Valid printable text (including CJK, emoji, and other multi-byte UTF-8) passes through unchanged. The function never raises and its output contains no ESC and no disallowed control byte for ANY input binary.

Summary

Types

A C0/allowed control byte value, e.g. ?\t or ?\n.

Functions

Sanitize binary for safe delivery to a terminal renderer.

Types

control_byte()

@type control_byte() :: 0..31

A C0/allowed control byte value, e.g. ?\t or ?\n.

Functions

sanitize(binary, opts \\ [])

@spec sanitize(binary(), keyword()) :: String.t()

Sanitize binary for safe delivery to a terminal renderer.

Total: always returns a String.t(), never raises.

Options

  • :allow — a list of C0 control byte values (0..31) to pass through. Defaults to [?\n]. ESC (0x1B) is never allowed regardless of this list.