From: Lennart Poettering Date: Mon, 18 Nov 2024 11:34:17 +0000 (+0100) Subject: pretty-print: don't use OSC 8 for incompatible URLs X-Git-Tag: v258-rc1~1897^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0823d96a0b60ea77e86dcf6ff4bc0cd9161bb794;p=thirdparty%2Fsystemd.git pretty-print: don't use OSC 8 for incompatible URLs --- diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 41c399c937c..547580ed067 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -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); diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index c30faf168c0..782b0fed9dd 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -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; +} diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index 97fea7ac9ad..1b735625847 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -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);