From 36c6f488e436c385f55e4785436213c56a6abf6c Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Tue, 10 Jun 2025 15:52:45 -0500 Subject: [PATCH] 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). (cherry picked from commit b5aef05b8f653eca3901a9da32b75417f56904b9) --- src/nvim/terminal.c | 21 ++++++--------------- test/functional/terminal/highlight_spec.lua | 15 ++++++++------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index f4acfb486c..16b0e31f19 100644 --- 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 index 0afbd010f7..42dbee02c8 100644 --- 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)