]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: prefer generating 0x1B 0x5C as ANSI sequence "ST"
authorLennart Poettering <lennart@poettering.net>
Thu, 31 Oct 2024 09:05:13 +0000 (10:05 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 31 Oct 2024 10:38:08 +0000 (11:38 +0100)
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
src/basic/terminal-util.c
src/basic/terminal-util.h
src/shared/pretty-print.c
src/shared/ptyfwd.c

index 8ded46f493886b1fe4311c7258bd596c53258b5b..4172db12a5b309e8cdbc006e5f13c6bf9729b181 100644 (file)
@@ -1923,12 +1923,12 @@ int get_default_background_color(double *ret_red, double *ret_green, double *ret
         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 = {};
 
index b446e547d6078e904e3a15efc6969c36aa909648..3d02e92d0bf7c86eaa00be202068fd248d2c64d8 100644 (file)
 #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);
index df1c20fa244e61af346cf06a32c543993aca00fd..1e9819ab09307ca1f7f033dc4738c9d23099ab28 100644 (file)
@@ -88,7 +88,7 @@ int terminal_urlify(const char *url, const char *text, char **ret) {
                 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)
@@ -475,7 +475,7 @@ void draw_progress_bar_unbuffered(const char *prefix, double percentage) {
                  * 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 */;
@@ -534,7 +534,7 @@ void clear_progress_bar_unbuffered(const char *prefix) {
                       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);
index c06c279d87bfc9c150ab8dc9049952ced1f9e110..11701f676874448eefad0f0d85e8153f88f3bac0 100644 (file)
@@ -397,7 +397,7 @@ static int insert_window_title_fix(PTYForward *f, size_t offset) {
         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;
 
@@ -567,7 +567,7 @@ static int do_shovel(PTYForward *f) {
                 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();
                 }