#36536 log: escape C1 control characters in messages

ReviewabilityReviewsAgreementSize
#36536 fametrano log: escape C1 control characters in messagesReady3Strong7 + 6 tests
  • Prevent untrusted log output from driving or corrupting terminal displays
  • Protect node operators viewing logs in VTE-based terminals from control sequence injection
  • Ready to review
  • Strong support with substantive testing on Linux x86_64 (cyb3ralbert)
  • Verified that C1 characters in paths are escaped in debug.log and unit tests pass (cyb3ralbert)
  • Minor test and comment suggestions accepted by author if a re-push is requested (cyb3ralbert)
  • Approval without stated reasons (jpk68)
  • 7 lines added or modified outside tests
  • 6 lines added or modified in tests
  • 4 lines removed in total
  • 2 files, 1 commits
Utilities (logging, arguments, libraries)#15 of 59
P2 · bug fix
  • P2 because it stops untrusted log content from injecting terminal control sequences into VTE terminals
  • Prevents terminal display corruption or escape sequence manipulation when viewing logs
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:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
cyb3ralbert (contributor)suggestion, correctnessAdd checks for \xc2\x7f and trailing single \xc2 after line 141 to independently pin down boundary conditionsanswered · author agrees and will push if requestedansweredyes2026-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, maintenanceUpdate LogEscapeMessage doc comments and test comments to mention the C1 exception and clarify the U+0100 caseanswered · author agrees and will push if requestedansweredyes2026-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

dossier JSON · extract JSON · model ledger, generated 2026-11-02T01:11, confidence high, input hash 672e26aff501ece3
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