EscapeFilter class final
Filters host output so that nothing reaches the renderer that leaves the device, sends data back or changes the local view on its own (24 11.2, SEC-TERM-6).
The filter works on bytes, before UTF-8 decoding: ESC and every byte of a control sequence are ASCII and never part of a UTF-8 multibyte character, so the byte view and the decoded view of the renderer see the same sequences.
Allow list (ruling of M4-35, Design note 2):
- Bytes outside escape sequences pass unchanged: printable text, UTF-8 multibyte, the C0 controls (BEL, BS, HT, LF, VT, FF, CR, SO, SI; the others too, xterm ignores them), DEL, and CAN and SUB when no sequence is open. 8-bit C1 bytes are not interpreted: the renderer works on decoded text and xterm does not parse C1.
- ESC, intermediates 0x20-0x2F and one final byte 0x30-0x7E pass (ESC 7, ESC 8, ESC D, ESC M, ESC ( B, ESC =, ESC > ...), EXCEPT the string introducers ESC P (DCS, among them DECRQSS and XTGETTCAP), ESC X (SOS), ESC ^ (PM) and ESC _ (APC): these are dropped completely with their content up to ST (ESC ); BEL does not end them.
- CSI (ESC [, parameters 0x30-0x3F, intermediates 0x20-0x2F, final 0x40-0x7E) passes,
EXCEPT these queries and reports, dropped completely:
- final
t(window operations and reports: CSI 21 t title, CSI 20 t icon title, CSI 18 t size, CSI 14 t, and CSI 8;r;c t which would resize the local view); - final
nunless the parameters are exactly6without intermediates (CPR allowed; CSI 5 n, CSI ?6 n and the others dropped); - final
cunless the parameters are ``,0,>or>0without intermediates (DA1 and DA2 allowed; tertiary CSI = c dropped); - any intermediate
$(DECRQM CSI ? Ps $ p and the rectangle and report family); - final
x(DECREQTPARM); - final
qwithout intermediates and with a>prefix (XTVERSION); CSI Ps SP q (cursor style) passes. The answers that shells need are therefore exactly CPR (CSI 6 n) and DA1/DA2. Intermediates count fornandcbecause xterm ignores them: CSI 5 SP n would be a status report for it. 3a. Renderer safety (found by the red team of M4-35): a CSI is also dropped when one of its numeric parameters, read as xterm 4.0.0 reads them, exceeds maxParameterValue (REP CSI 999999999 b would freeze the view), and an SGR whose 38 or 48 lacks its colour sub-parameters (CSI 38 m, CSI 48;2 m) is dropped, because xterm reads them without a bounds check and throws; so is SGR 38;5 or 48;5 with an index above 255 (its painter reads past the palette), REP CSI Ps b with Ps above maxRepeatCount and ECH CSI 0 X (xterm erases from column -1 and throws). These are the renderer faults known for xterm 4.0.0, not a complete guard: the view must still catch exceptions of the renderer and process large output in slices.
- final
- OSC (ESC ], ended by BEL or ST) is dropped completely: OSC 52 clipboard set and query,
OSC 0/1/2 titles, OSC 4/10/11/12 colours with
?queries, any other. EXCEPT OSC 8, which is rewritten: ESC ] 8 ; params ; URI ST with a non-empty URI emits LinkStart (params such asid=are ignored), with an empty URI LinkEnd (only while a link is open). The link text between them passes as FilteredText, so the link is inert text plus a record. A LinkStart while a link is open first emits LinkEnd. An OSC 8 whose URI is longer than maxLinkTargetBytes or holds anything but printable ASCII (a space, a control, a line separator, a bidi control or any non-ASCII character could hide or disguise the shown target) is dropped like any other OSC and emits nothing; an open link then stays open. OSC 8 without the second;emits nothing. - CAN (0x18) or SUB (0x1A) inside a sequence aborts it; the sequence and the CAN or SUB byte are dropped. An ESC inside a sequence that is not ST aborts the sequence and starts a new one at that ESC. Further rules of the VT500 parser that keep the byte view equal to the renderer's view: a C0 control inside an ESC or CSI sequence is passed at once (executed before the sequence) and the sequence goes on; DEL inside one is dropped; a byte from 0x80 aborts it and is then handled as text; a parameter byte after an intermediate makes the CSI invalid, it is dropped up to its final byte.
- Memory is bounded: an ESC or CSI sequence longer than maxControlSequenceBytes is dropped up to its final byte; dropped string sequences (DCS, SOS, PM, APC, OSC other than 8 and the params of OSC 8) are consumed without buffering; only the URI of OSC 8 is buffered, up to maxLinkTargetBytes.
- Every sequence may be split at any byte across process calls; the result is the same as in one call.
- The filter never throws, logs nothing and keeps no content beyond the current sequence (15 23.4: terminal content never reaches logs).
Example:
final filter = EscapeFilter();
for (final chunk in filter.process(frame)) {
switch (chunk) {
case FilteredText(:final bytes): render(bytes);
case LinkStart(:final target): openRecord(target);
case LinkEnd(): closeRecord();
}
}
Constructors
- EscapeFilter()
- Creates a filter in the ground state with no open link.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
process(
List< int> bytes) → List<FilteredChunk> -
Filters the next
bytesof the host output. -
reset(
) → void - Drops any partial sequence and the link state, without emitting anything.
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Constants
- maxControlSequenceBytes → const int
- The longest ESC or CSI sequence that passes, in bytes including ESC and the final byte (rule 6); real sequences stay far below it, SGR with 24-bit colours is about 20.
- maxLinkTargetBytes → const int
- The longest OSC 8 target URI that is kept, in bytes (rule 4 and 6); a longer one is dropped and emits nothing.
- maxParameterValue → const int
- The largest numeric CSI parameter that passes (rule 3a); screens, colours and modes stay below it, and xterm loops once per count for some sequences.
- maxRepeatCount → const int
- The largest REP (CSI Ps b) count that passes (rule 3a): one line of a wide screen. It bounds the work per sequence; it does not stop a flood of REP sequences.