Skip to content

Escape controls without color - #420

Closed
kskalski wants to merge 2 commits into
rust-cli:mainfrom
kskalski:escape-controls-without-color
Closed

kskalski wants to merge 2 commits into
rust-cli:mainfrom
kskalski:escape-controls-without-color

Conversation

@kskalski

@kskalski kskalski commented Sep 9, 2026

Copy link
Copy Markdown

What does this PR try to solve?

Closes #419

Escapes C0 and DEL as \xNN in BufferWriter::print when color is off, sparing \n and \t. Returns Cow, so records without control characters are borrowed and never copied.

Notes to reviewers

Only #[cfg(not(feature = "color"))] changes, and that path does nothing today — no behavior change for anyone using color.

The fast-path scan folds bitwise rather than using any: short-circuiting stops LLVM vectorizing it, costing ~120 ns/record instead of ~17. Commented so it doesn't get simplified back.

Second commit updates the docs warning quoted in #419, which the first makes false.

Verified manually against a payload of CSI, OSC 0/8/52, BEL, CR, DEL and multi-byte UTF-8, under both --no-default-features and --all-features; existing tests pass in both.

LLM involvement: written with Claude Code (Opus 5) — investigation, implementation, benchmark harness, commit messages — with me directing and reviewing throughout. Figures in #419 were measured from separately built binaries, each sanity-checked for its sanitization behavior before timing.

Problem:

Dropping the `color` feature removes the `anstream` layer, and with it all
ANSI stripping — logging untrusted input then writes escape sequences
verbatim into the output. Stored logs are the worse case: `cat`, `tail -f`
and `grep` replay them raw at every future read, so OSC 52 clipboard writes,
title-setting and cursor motion keep firing long after the fact.

The build cannot just keep `color` to get sanitized: with styling disabled
`anstream` still runs its VT state machine over every byte, which triples
per-record cost.

Summary of Changes:

- escape C0 and DEL as `\xNN` in `print` when `color` is off
- spare `\n` and `\t`, which the record format itself relies on
- borrow via `Cow` so records without controls copy nothing
Problem:

The colors warning still tells readers that dropping the `color` feature
leaves them unprotected, which no longer holds now that such builds escape
control characters themselves.

Summary of Changes:

- list dropping `color` among the mitigations, noting it escapes rather than strips
- call out that `\n` stays unescaped in every configuration
@epage

epage commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This is in violation of our AI policy

@epage epage closed this Sep 9, 2026
@kskalski

kskalski commented Sep 9, 2026

Copy link
Copy Markdown
Author

Is your policy documented somewhere? Would rewriting it manually or in other way allow the contribution to be accepted?
I would still like the tradeoff between perf and vulnerability of log files / terminal fixed...

@epage

epage commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

https://github.com/rust-cli/env_logger/blob/main/AI_POLICY.md

Our contrib guide (and the PR template) say that a decision should be made on Issue before posting PRs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sanitization requires color, which parses every record

2 participants