1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 22:42:48 +03:00

Fix spawning new tabs/windows in directory with urlunsafe paths

The CWD is internally stored as URL. The path component is therefore
stored percent_encoded. It must be decoded before use.
This commit is contained in:
Arvedui 2021-05-15 22:05:10 +02:00 committed by Wez Furlong
parent bf0320624d
commit dbc278e59a
5 changed files with 25 additions and 10 deletions

2
Cargo.lock generated
View File

@ -4885,6 +4885,7 @@ dependencies = [
"open",
"ordered-float",
"palette",
"percent-encoding",
"portable-pty",
"pretty_env_logger",
"promise",
@ -4972,6 +4973,7 @@ dependencies = [
"lazy_static",
"log",
"mux",
"percent-encoding",
"portable-pty",
"promise",
"rangeset",

View File

@ -40,6 +40,7 @@ mux = { path = "../mux" }
open = "1.4"
ordered-float = "2.1"
palette = "0.5"
percent-encoding = "2"
portable-pty = { path = "../pty", features = ["serde_support", "ssh"]}
promise = { path = "../promise" }
pulldown-cmark = "0.8"

View File

@ -5,6 +5,7 @@ use mux::activity::Activity;
use mux::domain::DomainState;
use mux::tab::SplitDirection;
use mux::Mux;
use percent_encoding::percent_decode_str;
use portable_pty::{CommandBuilder, PtySize};
use std::sync::Arc;
@ -127,15 +128,19 @@ impl super::TermWindow {
} else {
match cwd {
Some(url) if url.scheme() == "file" => {
let path = url.path().to_string();
// On Windows the file URI can produce a path like:
// `/C:\Users` which is valid in a file URI, but the leading slash
// is not liked by the windows file APIs, so we strip it off here.
let bytes = path.as_bytes();
if bytes.len() > 2 && bytes[0] == b'/' && bytes[2] == b':' {
Some(path[1..].to_owned())
if let Ok(path) = percent_decode_str(url.path()).decode_utf8() {
let path = path.into_owned();
// On Windows the file URI can produce a path like:
// `/C:\Users` which is valid in a file URI, but the leading slash
// is not liked by the windows file APIs, so we strip it off here.
let bytes = path.as_bytes();
if bytes.len() > 2 && bytes[0] == b'/' && bytes[2] == b':' {
Some(path[1..].to_owned())
} else {
Some(path)
}
} else {
Some(path)
None
}
}
Some(_) | None => None,

View File

@ -16,6 +16,7 @@ hostname = "0.3"
lazy_static = "1.4"
log = "0.4"
mux = { path = "../mux" }
percent-encoding = "2"
portable-pty = { path = "../pty", features = ["serde_support"]}
promise = { path = "../promise" }
rangeset = { path = "../rangeset" }

View File

@ -6,6 +6,7 @@ use mux::pane::{Pane, PaneId};
use mux::renderable::{RenderableDimensions, StableCursorPosition};
use mux::tab::TabId;
use mux::Mux;
use percent_encoding::percent_decode_str;
use portable_pty::PtySize;
use promise::spawn::spawn_into_main_thread;
use rangeset::RangeSet;
@ -611,8 +612,13 @@ async fn split_pane(split: SplitPane, sender: PduSender) -> anyhow::Result<Pdu>
let cwd = split.command_dir.or_else(|| {
mux.get_pane(pane_id)
.and_then(|pane| pane.get_current_working_dir())
.map(|url| {
let path = url.path().to_string();
.and_then(|url| {
percent_decode_str(url.path())
.decode_utf8()
.ok()
.map(|path| path.into_owned())
})
.map(|path| {
// On Windows the file URI can produce a path like:
// `/C:\Users` which is valid in a file URI, but the leading slash
// is not liked by the windows file APIs, so we strip it off here.