]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pretty-print: don't use OSC 8 for incompatible URLs 35223/head
authorLennart Poettering <lennart@poettering.net>
Mon, 18 Nov 2024 11:34:17 +0000 (12:34 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 11 Dec 2024 09:35:03 +0000 (10:35 +0100)
src/basic/string-util.c
src/basic/terminal-util.h
src/shared/pretty-print.c

index 41c399c937c53ef6a0cb6072a8bdb559afbf72d8..547580ed06725f4a23974c235f55541d8930dc38 100644 (file)
@@ -801,7 +801,7 @@ char* strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
                         /* There are three kinds of OSC terminators: \x07, \x1b\x5c or \x9c. We only support
                          * the first two, because the last one is a valid UTF-8 codepoint and hence creates
                          * an ambiguity (many Terminal emulators refuse to support it as well). */
-                        if (eot || (!IN_SET(*i, '\x07', '\x1b') && (uint8_t) *i < 32U) || (uint8_t) *i > 126U) { /* EOT or invalid chars in sequence */
+                        if (eot || (!IN_SET(*i, '\x07', '\x1b') && !osc_char_is_valid(*i))) { /* EOT or invalid chars in sequence */
                                 fputc('\x1B', f);
                                 fputc(']', f);
                                 advance_offsets(i - *ibuf, highlight, shift, 2);
index c30faf168c0df4964506a51c4ecac701bc4c8330..782b0fed9dd6620a82c8324a2116178511f2049c 100644 (file)
@@ -157,3 +157,9 @@ int terminal_is_pty_fd(int fd);
 
 int pty_open_peer_racefree(int fd, int mode);
 int pty_open_peer(int fd, int mode);
+
+static inline bool osc_char_is_valid(char c) {
+        /* Checks whether the specified character is safe to be included inside an ANSI OSC sequence, as per
+         * ECMA-48 5th edition, section 8.3.89 */
+        return (unsigned char) c >= 32U && (unsigned char) c < 127;
+}
index 97fea7ac9ad0b7efc75cee0c0901f448cf2269c0..1b73562584726fe90a9bc5f0e640bae83d4372d9 100644 (file)
@@ -76,6 +76,25 @@ bool urlify_enabled(void) {
 #endif
 }
 
+static bool url_suitable_for_osc8(const char *url) {
+        assert(url);
+
+        /* Not all URLs are safe for inclusion in OSC 8 due to charset and length restrictions. Let's detect
+         * which ones those are */
+
+        /* If the URL is longer than 2K let's not try to do OSC 8. As per recommendation in
+         * https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#length-limits */
+        if (strlen(url) > 2000)
+                return false;
+
+        /* OSC sequences may only contain chars from the 32..126 range, as per ECMA-48 */
+        for (const char *c = url; *c; c++)
+                if (!osc_char_is_valid(*c))
+                        return false;
+
+        return true;
+}
+
 int terminal_urlify(const char *url, const char *text, char **ret) {
         char *n;
 
@@ -87,7 +106,7 @@ int terminal_urlify(const char *url, const char *text, char **ret) {
         if (isempty(text))
                 text = url;
 
-        if (urlify_enabled())
+        if (urlify_enabled() && url_suitable_for_osc8(url))
                 n = strjoin(ANSI_OSC "8;;", url, ANSI_ST,
                             text,
                             ANSI_OSC "8;;" ANSI_ST);