Skip to content

log: escape terminal control characters - #1114

Merged
steadytao merged 4 commits into
masterfrom
escape-terminal-controls
Oct 3, 2026
Merged

steadytao merged 4 commits into
masterfrom
escape-terminal-controls

Conversation

@steadytao

@steadytao steadytao commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Fixes #1112

Summary

Escape terminal control characters in filenames and diagnostics written to standard output, standard error or rsync log files. The output filter preserves printable text in the active locale while escaping:

  • C0 controls except tab
  • DEL
  • C1 controls
  • existing \#NNN sequences which would otherwise be ambiguous

Invalid or incomplete multibyte input falls back to conservative byte filtering. Generic output no longer trusts leading or trailing carriage returns. The three intentional progress displays emit their intended carriage return through a dedicated helper.

Compatibility

Character boundaries are decoded using the active locale. This preserves valid multibyte text including UTF-8 and EUC-JP while still escaping C1 bytes in single-byte locales such as ISO-8859-1. Systems without wchar.h or mbrtowc() use a conservative byte-oriented fallback. Default filtering without --8-bit-output remains byte-oriented.

@steadytao

Copy link
Copy Markdown
Member Author

@rubo77 please review

@seks99x

seks99x commented Oct 1, 2026

Copy link
Copy Markdown
Member

I have this on my radar, just need some proper time reviewing this complex bounds checking and pointer math. Will come back to it

Comment thread log.c
Comment thread log.c
@rubo77

This comment was marked as low quality.

@rubo77

This comment was marked as low quality.

@steadytao

steadytao commented Oct 2, 2026 •

Copy link
Copy Markdown
Member Author

Both locale concerns from @FusionPow were valid. The filter was treating permitted high bytes as UTF-8 regardless of the active locale. Reworked this to instead use the active locale's decoder to identify boundaries. ISO-8859-1 d8 9b preserves d8 and escapes the C1 byte while EUC-JP 8e b1 remains intact. Invalid or incomplete input falls back to byte filtering.

I also tightened the output bounds before expansion and added regressions for UTF-8, ISO-8859-1, EUC-JP and LC_ALL=C. Thanks for checking these cases.

@steadytao

Copy link
Copy Markdown
Member Author

And @rubo77, I would report a case only where raw control characters demonstrably reach a terminal. Raw bytes in redirected or machine-readable output can be intentional so this should not be reported broadly without reproducing a terminal path.

@steadytao

steadytao commented Oct 2, 2026 •

Copy link
Copy Markdown
Member Author

Updated description; will address any CI failures.

@steadytao

Copy link
Copy Markdown
Member Author

@seks99x: I have this on my radar, just need some proper time reviewing this complex bounds checking and pointer math. Will come back to it

Also. Appreciated.

@seks99x

seks99x commented Oct 3, 2026

Copy link
Copy Markdown
Member

Great job @steadytao. LGTM

@steadytao
steadytao merged commit 7b9cedc into master Oct 3, 2026
20 checks passed
@steadytao
steadytao deleted the escape-terminal-controls branch October 3, 2026 08:54
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.

progress output prints filenames with C1 control characters unescaped, corrupting the terminal display

4 participants