# `Raxol.Core.Boundary.TermText`
[🔗](https://github.com/DROOdotFOO/raxol/blob/v2.7.0/lib/raxol/core/boundary/term_text.ex#L1)

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.

# `control_byte`

```elixir
@type control_byte() :: 0..31
```

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

# `sanitize`

```elixir
@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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
