OSC sequences can be closed with one of three terminators:
1. ASCII code 7, aka BEL, aka ^G, aka \x07, aka \a
2. ASCII code 156, aka \x9c
2. Pair of ASCII code 27 followed by ASCII code 92, aka \x1b\x5c
Of these, in some corner case scenarios BEL makes problem (see #34604).
Hence switch away from that wherever we use it, and prefer the \x1b\x5c
instead. That's preferable over \x9c, since the latter is also a valid
UTF-8 codepoint. See discussion here for example:
https://gist.github.com/egmontkob/
eb114294efbcd5adb1944c9f3cb5feda#the-escape-sequence
Fixes: #34604
if (tcsetattr(STDIN_FILENO, TCSADRAIN, &new_termios) < 0)
return -errno;
- r = loop_write(STDOUT_FILENO, "\x1B]11;?\x07", SIZE_MAX);
+ r = loop_write(STDOUT_FILENO, "\x1B]11;?" ANSI_ST, SIZE_MAX);
if (r < 0)
goto finish;
usec_t end = usec_add(now(CLOCK_MONOTONIC), 333 * USEC_PER_MSEC);
- char buf[STRLEN("\x1B]11;rgb:0/0/0\x07")]; /* shortest possible reply */
+ char buf[STRLEN("\x1B]11;rgb:0/0/0" ANSI_ST)]; /* shortest possible reply */
size_t buf_full = 0;
BackgroundColorContext context = {};
#define ANSI_WINDOW_TITLE_PUSH "\x1b[22;2t"
#define ANSI_WINDOW_TITLE_POP "\x1b[23;2t"
+/* ANSI "string terminator" character ("ST"). Terminal emulators typically allow three different ones: 0x07,
+ * 0x9c, and 0x1B 0x5C. We'll avoid 0x07 (BEL, aka ^G) since it might trigger unexpected TTY signal
+ * handling. And we'll avoid 0x9c since that's also valid regular codepoint in UTF-8 and elsewhere, and
+ * creates ambiguities. Because of that some terminal emulators explicitly choose not to support it. Hence we
+ * use 0x1B 0x5c */
+#define ANSI_ST "\e\\"
+
bool isatty_safe(int fd);
int terminal_reset_defensive(int fd, bool switch_to_text);
text = url;
if (urlify_enabled())
- n = strjoin("\x1B]8;;", url, "\a", text, "\x1B]8;;\a");
+ n = strjoin("\x1B]8;;", url, ANSI_ST, text, "\x1B]8;;" ANSI_ST);
else
n = strdup(text);
if (!n)
* https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
* https://github.com/microsoft/terminal/pull/8055
*/
- fprintf(stderr, "\x1B]9;4;1;%u\a", (unsigned) ceil(percentage));
+ fprintf(stderr, "\x1B]9;4;1;%u" ANSI_ST, (unsigned) ceil(percentage));
size_t cols = columns();
size_t prefix_width = utf8_console_width(prefix) + 1 /* space */;
stderr);
else
/* Undo Windows Terminal progress indication again. */
- fputs("\x1B]9;4;0;;\a"
+ fputs("\x1B]9;4;0;;" ANSI_ST
ANSI_ERASE_TO_END_OF_LINE, stderr);
fputc('\r', stderr);
if (!t)
return 0;
- _cleanup_free_ char *joined = strjoin("\x1b]0;", f->title_prefix, t, "\a");
+ _cleanup_free_ char *joined = strjoin("\x1b]0;", f->title_prefix, t, ANSI_ST);
if (!joined)
return -ENOMEM;
if (f->title) {
if (!strextend(&f->out_buffer,
ANSI_WINDOW_TITLE_PUSH
- "\x1b]2;", f->title, "\a"))
+ "\x1b]2;", f->title, ANSI_ST))
return log_oom();
}