#36536 log: escape C1 control characters in messages
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #36536 log: escape C1 control characters in messages | Ready | 3 | Strong | 7 + 6 tests | |||
|
|
|
|
| |||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
Escapes UTF-8 encoded C1 control characters (U+0080 through U+009F) in `BCLog::LogEscapeMessage`. The function detects the two-byte sequences `0xC2 0x80` to `0xC2 0x9F` and formats them as hex escape sequences (`\x..\x..`) while leaving other valid UTF-8 sequences untouched.
Problem: `LogEscapeMessage` escapes ASCII controls below 0x20 and 0x7F, but allows two-byte UTF-8 C1 control codes. VTE-based terminal emulators like GNOME Terminal interpret these characters as terminal control sequences (such as CSI, OSC, and DCS), allowing untrusted data printed to logs to drive or corrupt the terminal display.
Evidence of importance:
- PR description: 'The log escapes control characters so that a message cannot drive the terminal it is printed on, but it lets through the UTF-8 form of the C1 controls U+0080 to U+009F. VTE, the library behind GNOME Terminal and others, decodes these as CSI, OSC, DCS and the rest'
- Commit 40bb43f158: 'LogEscapeMessage escapes bytes below 0x20 and 0x7f, but passes the UTF-8 encodings of U+0080 to U+009F (0xC2 0x80 to 0xC2 0x9F), which include CSI, OSC and DCS. VTE-based terminals, such as GNOME Terminal, act on them.'
Risk of a mistake: low. A bug in this string sanitization logic could result in malformed or over-escaped log strings, but cannot affect consensus, node state, or wallet security.
Changed since the previous assessment: No functional changes to the escaping logic or tests; the commit was rebased or re-authored.
Reviewability
Ready
Nothing known that would invalidate a review now.
Waiting on (from the thread read):
- reviewer: cyb3ralbert or maintainer to indicate whether to push test and doc nits 2026-11-01
Agreement
Strong
substantive support, no open objection (cyb3ralbert)
Thread notes: fametrano agreed with both test and doc nits raised by cyb3ralbert, marking both suggestions answered, but offered to keep the current head unless a maintainer asks for a re-push.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| cyb3ralbert (contributor) | suggestion, correctness | Add checks for \xc2\x7f and trailing single \xc2 after line 141 to independently pin down boundary conditions | answered · author agrees and will push if requested | answered | yes | 2026-10-22: 'the two new checks don't independently pin down both boundaries' Status from: 2026-11-01: fametrano: 'both nits are right: the two extra checks pin each boundary' |
| cyb3ralbert (contributor) | suggestion, maintenance | Update LogEscapeMessage doc comments and test comments to mention the C1 exception and clarify the U+0100 case | answered · author agrees and will push if requested | answered | yes | 2026-10-22: 'the LogEscapeMessage doc comment and the test comment "ASCII and UTF-8 must pass through unaltered" don't mention the C1 exception' Status from: 2026-11-01: fametrano: 'the comments should mention the C1 exception' |
Support:
- jpk68 (contributor) (ACK, 2026-10-21): (no reason given) [not substantive]
- Naomi-Gift (none) (Tested ACK, 2026-10-22) [tested: test_LogEscapeMessage]: test_LogEscapeMessage passes [not substantive]
- cyb3ralbert (contributor) (Tested ACK, 2026-10-22) [tested: logging_tests, debug.log]: logging_tests pass on Linux x86_64 and confirmed U+009B and U+009F in regtest datadir path are escaped in debug.log
Participants:
- jpk68 (contributor, support, 1 statements 2026-10-21 to 2026-10-21): ACK with commit hash
- Naomi-Gift (none, support, 1 statements 2026-10-22 to 2026-10-22): tACK with unit test pass
- cyb3ralbert (contributor, support, 1 statements 2026-10-22 to 2026-10-22): tACK with detailed testing and test/doc nits
Files
6 lines under test/bench/ci.
- src/logging.cpp +7/-4
- src/test/logging_tests.cpp +6/-0
Card
The short text the ranking pass compares across PRs.
Escapes UTF-8 encoded C1 control characters (U+0080 through U+009F) in BCLog::LogEscapeMessage. Log sanitization currently blocks ASCII control bytes but allows UTF-8 C1 sequences, which VTE-backed terminal emulators parse as terminal controls like CSI and OSC, letting untrusted input manipulate terminal displays. The change matches the two-byte sequences 0xC2 0x80 to 0xC2 0x9F and escapes them as hex literals without requiring a full UTF-8 decoder.
Data
thread read through 2026-11-01 (4 statements), head 40bb43f158
labels: Utils/log/libs
Categories
Utilities (logging, arguments, libraries)
P2 · bug fix
Prevents terminal control sequence injection via logs by escaping UTF-8 encoded C1 control codes. As the PR notes, LogEscapeMessage previously passed U+0080 through U+009F, allowing untrusted data to emit CSI, OSC, and DCS sequences that VTE-based terminals execute.
Membership: Matches Utils/log/libs label and modifies src/logging.cpp
Factors: security/stability 2, bug 1, performance 0, user value 1, leverage 0