commit b5aef05b8f653eca3901a9da32b75417f56904b9
parent 228ff6e5476e0b73320d32493a5d85da63836e3c
Author: Gregory Anders <greg@gpanders.com>
Date: Tue, 10 Jun 2025 15:52:45 -0500
fix(terminal): fix OSC 8 parsing (#34424)
vterm does not send us the terminator in the string fragment. Our OSC 8
parser assumed that it was and therefore treated short strings as
invalid (as it assumed it was missing a terminator).
Diffstat:
2 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
@@ -283,31 +283,22 @@ static int parse_osc8(VTermStringFragment frag, int *attr)
}
}
- // Move past the semicolon
- i++;
-
- if (i >= frag.len) {
+ if (frag.str[i] != ';') {
// Invalid OSC sequence
return 0;
}
- // Find the terminator
- const size_t start = i;
- for (; i < frag.len; i++) {
- if (frag.str[i] == '\a' || frag.str[i] == '\x1b') {
- break;
- }
- }
+ // Move past the semicolon
+ i++;
- const size_t len = i - start;
- if (len == 0) {
+ if (i >= frag.len) {
// Empty OSC 8, no URL
*attr = 0;
return 1;
}
- char *url = xmemdupz(&frag.str[start], len + 1);
- url[len] = 0;
+ char *url = xmemdupz(&frag.str[i], frag.len - i + 1);
+ url[frag.len - i] = 0;
*attr = hl_add_url(0, url);
xfree(url);
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
@@ -398,12 +398,13 @@ describe(':terminal', function()
[100] = { url = 'https://example.com' },
}
local chan = api.nvim_open_term(0, {})
- api.nvim_chan_send(chan, '\027]8;;https://example.com\027\\Example\027]8;;\027\\')
- screen:expect({
- grid = [[
- {100:^Example} |
- |*6
- ]],
- })
+ api.nvim_chan_send(
+ chan,
+ 'This is an \027]8;;https://example.com\027\\example\027]8;;\027\\ of a link'
+ )
+ screen:expect([[
+ ^This is an {100:example} of a link |
+ |*6
+ ]])
end)
end)