Fix `;` character in URI OSC 8 payload

The special character `;` can be not URL-encoded, thus it'll add
extra parameter in the payload. Handle it joining extra parameters
with the `;` as a separator.
This commit is contained in:
Kirill Chibisov 2023-03-19 18:16:28 +03:00 committed by GitHub
parent 2377c0a728
commit 4b91a1dbe9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 18 deletions

View File

@ -50,6 +50,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- EOT (`\x03`) escaping bracketed paste mode
- Drag & Drop not working for the search bar
- Simple-fullscreened window not resized when moving between monitors on macOS
- Character `;` inside the `URI` in `OSC 8` sequence breaking the URI
### Removed

View File

@ -649,8 +649,8 @@ mod tests {
let mut term = mock_term("000\r\n111");
term.goto(Line(0), Column(0));
let hyperlink_foo = Hyperlink::new(Some("1"), "foo");
let hyperlink_bar = Hyperlink::new(Some("2"), "bar");
let hyperlink_foo = Hyperlink::new(Some("1"), String::from("foo"));
let hyperlink_bar = Hyperlink::new(Some("2"), String::from("bar"));
// Create 2 hyperlinks on the first line.
term.set_hyperlink(Some(hyperlink_foo.clone()));

View File

@ -1014,7 +1014,15 @@ where
// Hyperlink.
b"8" if params.len() > 2 => {
let link_params = params[1];
let uri = str::from_utf8(params[2]).unwrap_or_default();
// NOTE: The escape sequence is of form 'OSC 8 ; params ; URI ST', where
// URI is URL-encoded. However `;` is a special character and might be
// passed as is, thus we need to rebuild the URI.
let mut uri = str::from_utf8(params[2]).unwrap_or_default().to_string();
for param in params[3..].iter() {
uri.push(';');
uri.push_str(str::from_utf8(param).unwrap_or_default());
}
// The OSC 8 escape sequence must be stopped when getting an empty `uri`.
if uri.is_empty() {

View File

@ -43,7 +43,7 @@ pub struct Hyperlink {
}
impl Hyperlink {
pub fn new<T: ToString>(id: Option<T>, uri: T) -> Self {
pub fn new<T: ToString>(id: Option<T>, uri: String) -> Self {
let inner = Arc::new(HyperlinkInner::new(id, uri));
Self { inner }
}
@ -67,7 +67,7 @@ struct HyperlinkInner {
}
impl HyperlinkInner {
pub fn new<T: ToString>(id: Option<T>, uri: T) -> Self {
pub fn new<T: ToString>(id: Option<T>, uri: String) -> Self {
let id = match id {
Some(id) => id.to_string(),
None => {
@ -77,7 +77,7 @@ impl HyperlinkInner {
},
};
Self { id, uri: uri.to_string() }
Self { id, uri }
}
}

View File

@ -1,10 +1,14 @@
[?2004hsh-5.1$ printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n' printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n'
[?2004l ]8;;https://example.com\foo]8;;\
[?2004hsh-5.1$ printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n' printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n'
[?2004l ]8;;https://example.com\foo]8;;\
[?2004hsh-5.1$ printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n' printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n'
[?2004l ]8;id=42;https://example.com\bar]8;;\
[?2004hsh-5.1$ printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n' printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n'
[?2004l ]8;id=42;https://example.com\bar]8;;\
[?2004hsh-5.1$ [?2004l
exit
sh-5.2$ cat alacritty? _tir  erminal/tests/ref/hyperlinks/alacritty.recording
[?2004hsh-5.1$ printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n' printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n'
[?2004l ]8;;https://example.com\foo]8;;\
[?2004hsh-5.1$ printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n' printf '\e]8;;https://example.com\e\\foo\e]8;;\e\\\n'
[?2004l ]8;;https://example.com\foo]8;;\
[?2004hsh-5.1$ printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n' printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n'
[?2004l ]8;id=42;https://example.com\bar]8;;\
[?2004hsh-5.1$ printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n' printf '\e]8;id=42;https://example.com\e\\bar\e]8;;\e\\\n'
[?2004l ]8;id=42;https://example.com\bar]8;;\
[?2004hsh-5.1$ [?2004l
exit
sh-5.2$ printf '\e]8;id=hello;http://example.com/naoheu;ntahoeu\e\\This is a link\e]8;id=hello;\e\\\n'
]8;id=hello;http://example.com/naoheu;ntahoeu\This is a link]8;id=hello;\
sh-5.2$ exit

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"columns":157,"screen_lines":40}
{"columns":140,"screen_lines":32}