1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 06:31:14 +02:00

libutil: amend OSC 8 escape stripping for xterm-style separator

Before the change `nix` was stripping warning flags
reported by `gcc-14` too eagerly:

    $ nix build -f. texinfo4
    error: builder for '/nix/store/i9948l91s3df44ip5jlpp6imbrcs646x-texinfo-4.13a.drv' failed with exit code 2;
           last 25 log lines:
           >  1495 | info_tag (mbi_iterator_t iter, int handle, size_t *plen)
           >       |                                            ~~~~~~~~^~~~
           > window.c:1887:39: error: passing argument 4 of 'printed_representation' from incompatible pointer type []
           >  1887 |                                       &replen);
           >       |                                       ^~~~~~~
           >       |                                       |
           >       |                                       int *

After the change the compiler flag remains:

    $ ~/patched.nix build -f. texinfo4
    error: builder for '/nix/store/i9948l91s3df44ip5jlpp6imbrcs646x-texinfo-4.13a.drv' failed with exit code 2;
       last 25 log lines:
       >  1495 | info_tag (mbi_iterator_t iter, int handle, size_t *plen)
       >       |                                            ~~~~~~~~^~~~
       > window.c:1887:39: error: passing argument 4 of 'printed_representation' from incompatible pointer type [-Wincompatible-pointer-types]
       >  1887 |                                       &replen);
       >       |                                       ^~~~~~~
       >       |                                       |
       >       |                                       int *

Note the difference in flag rendering around the warning.

https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda has a
good sumamry of why it happens. Befomre the change `nix` was handling
just one form or URL separator:

    $ printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'

Now it also handled another for (used by gcc-14`):

    printf '\e]8;;http://example.com\aThis is a link\e]8;;\a\n'

While at it fixed accumulation of trailing escape `\e\\` symbol.
This commit is contained in:
Sergei Trofimovich 2025-04-29 15:35:53 +01:00
parent 2ec1303286
commit e322b714dc
2 changed files with 21 additions and 4 deletions

View file

@ -66,4 +66,12 @@ TEST(filterANSIEscapes, osc8)
ASSERT_EQ(filterANSIEscapes("\e]8;;http://example.com\e\\This is a link\e]8;;\e\\"), "This is a link");
}
TEST(filterANSIEscapes, osc8_bell_as_sep)
{
// gcc-14 uses \a as a separator, xterm style:
// https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
ASSERT_EQ(filterANSIEscapes("\e]8;;http://example.com\aThis is a link\e]8;;\a"), "This is a link");
ASSERT_EQ(filterANSIEscapes("\e]8;;http://example.com\a\\This is a link\e]8;;\a"), "\\This is a link");
}
} // namespace nix

View file

@ -95,10 +95,19 @@ std::string filterANSIEscapes(std::string_view s, bool filterAll, unsigned int w
} else if (i != s.end() && *i == ']') {
// OSC
e += *i++;
// eat ESC
while (i != s.end() && *i != '\e') e += *i++;
// eat backslash
if (i != s.end() && *i == '\\') e += last = *i++;
// https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda defines
// two forms of a URI separator:
// 1. ESC '\' (standard)
// 2. BEL ('\a') (xterm-style, used by gcc)
// eat ESC or BEL
while (i != s.end() && *i != '\e' && *i != '\a') e += *i++;
if (i != s.end()) {
char v = *i;
e += *i++;
// eat backslash after ESC
if (i != s.end() && v == '\e' && *i == '\\') e += last = *i++;
}
} else {
if (i != s.end() && *i >= 0x40 && *i <= 0x5f) e += *i++;
}