Parse bracketed IPv6 file endpoints
ci / test (push) Waiting to run
ci / fuzz-smoke (push) Waiting to run
ci / windows-client (push) Waiting to run
ci / package-release (linux-x86_64, ubuntu-latest) (push) Waiting to run
ci / package-release (macos-aarch64, macos-14) (push) Waiting to run
ci / package-release (macos-x86_64, macos-13) (push) Waiting to run
ci / package-release (windows-x86_64, windows-latest) (push) Waiting to run
ci / publish-gitea-release (push) Blocked by required conditions
ci / remote-bench (push) Waiting to run
ci / test (push) Waiting to run
ci / fuzz-smoke (push) Waiting to run
ci / windows-client (push) Waiting to run
ci / package-release (linux-x86_64, ubuntu-latest) (push) Waiting to run
ci / package-release (macos-aarch64, macos-14) (push) Waiting to run
ci / package-release (macos-x86_64, macos-13) (push) Waiting to run
ci / package-release (windows-x86_64, windows-latest) (push) Waiting to run
ci / publish-gitea-release (push) Blocked by required conditions
ci / remote-bench (push) Waiting to run
This commit is contained in:
+31
-17
@@ -9600,23 +9600,24 @@ mod tests {
|
|||||||
input_matches_escape, is_local_status_target, is_resume_response_for_client,
|
input_matches_escape, is_local_status_target, is_resume_response_for_client,
|
||||||
latest_release_download_url, load_first_native_identity_with_prompt,
|
latest_release_download_url, load_first_native_identity_with_prompt,
|
||||||
native_proxy_udp_warning, newest_client_trace_path_from, parse_dynamic_forward,
|
native_proxy_udp_warning, newest_client_trace_path_from, parse_dynamic_forward,
|
||||||
parse_escape_key, parse_local_forward, parse_remote_forward, parse_ssh_config,
|
parse_escape_key, parse_local_forward, parse_remote_forward, parse_single_remote_path,
|
||||||
parse_trace_line, parse_trace_options, parse_trace_report_options, parse_trace_summary,
|
parse_ssh_config, parse_trace_line, parse_trace_options, parse_trace_report_options,
|
||||||
parse_update_options, post_submit_hold_duration, queue_pending_user_input,
|
parse_trace_summary, parse_update_options, post_submit_hold_duration,
|
||||||
queue_stale_pending_user_input, raw_contains_host_table, recv_response_until,
|
queue_pending_user_input, queue_stale_pending_user_input, raw_contains_host_table,
|
||||||
refresh_live_addr, release_tag_download_url, release_tag_from_effective_url,
|
recv_response_until, refresh_live_addr, release_tag_download_url,
|
||||||
release_version_from_tag, render_status_clear, render_status_overlay, requested_env,
|
release_tag_from_effective_url, release_version_from_tag, render_status_clear,
|
||||||
resolved_startup_command, retire_stream_state, retransmit_stream_opens,
|
render_status_overlay, requested_env, resolved_startup_command, retire_stream_state,
|
||||||
rewrite_forward_command, sanitize_trace_name, selected_predict_mode, selected_udp_host,
|
retransmit_stream_opens, rewrite_forward_command, sanitize_trace_name,
|
||||||
server_version_mismatch, should_flush_terminal_input_after_contact,
|
selected_predict_mode, selected_udp_host, server_version_mismatch,
|
||||||
should_health_log_client_start, should_hold_during_startup_gate,
|
should_flush_terminal_input_after_contact, should_health_log_client_start,
|
||||||
should_hold_post_submit_input, should_reconnect_before_input_for_local_sleep,
|
should_hold_during_startup_gate, should_hold_post_submit_input,
|
||||||
should_repaint_idle_terminal, should_strip_unowned_terminal_reports,
|
should_reconnect_before_input_for_local_sleep, should_repaint_idle_terminal,
|
||||||
split_after_command_submit, split_trace_tokens, ssh_command_target, ssh_config_uses_proxy,
|
should_strip_unowned_terminal_reports, split_after_command_submit, split_trace_tokens,
|
||||||
ssh_destination_host, ssh_username, ssh_with_user, startup_command, status_ssh_target,
|
ssh_command_target, ssh_config_uses_proxy, ssh_destination_host, ssh_username,
|
||||||
strip_stale_mouse_reports, strip_terminal_focus_reports, strip_unowned_terminal_reports,
|
ssh_with_user, startup_command, status_ssh_target, strip_stale_mouse_reports,
|
||||||
summarize_trace_file, summarize_trace_file_with_mode, terminal_private_mode_transition,
|
strip_terminal_focus_reports, strip_unowned_terminal_reports, summarize_trace_file,
|
||||||
toml_bare_key_or_quoted, top_trace_events, trace_report_warnings, unix_update_script,
|
summarize_trace_file_with_mode, terminal_private_mode_transition, toml_bare_key_or_quoted,
|
||||||
|
top_trace_events, trace_report_warnings, unix_update_script,
|
||||||
update_binary_version_for_installer, update_installer_url, update_version_status,
|
update_binary_version_for_installer, update_installer_url, update_version_status,
|
||||||
upsert_managed_block, valid_forward_host, vscode_safe_alias, wake_repaint_retry_deadline,
|
upsert_managed_block, valid_forward_host, vscode_safe_alias, wake_repaint_retry_deadline,
|
||||||
windows_update_script,
|
windows_update_script,
|
||||||
@@ -11709,6 +11710,19 @@ mod tests {
|
|||||||
assert!(valid_forward_host("server.example.com"));
|
assert!(valid_forward_host("server.example.com"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn single_remote_path_accepts_bracketed_ipv6_hosts() {
|
||||||
|
assert_eq!(
|
||||||
|
parse_single_remote_path("[2001:db8::1]:/tmp/file", "cat").unwrap(),
|
||||||
|
("2001:db8::1".to_string(), "/tmp/file".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_single_remote_path("[::1]:", "ls").unwrap(),
|
||||||
|
("::1".to_string(), ".".to_string())
|
||||||
|
);
|
||||||
|
assert!(parse_single_remote_path("[::1]", "ls").is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recover_removes_only_matching_cached_credentials() {
|
fn recover_removes_only_matching_cached_credentials() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
@@ -165,6 +165,12 @@ pub fn parse_copy_endpoint(raw: &str) -> CopyEndpoint {
|
|||||||
if looks_like_windows_path(raw) {
|
if looks_like_windows_path(raw) {
|
||||||
return CopyEndpoint::Local(PathBuf::from(raw));
|
return CopyEndpoint::Local(PathBuf::from(raw));
|
||||||
}
|
}
|
||||||
|
if let Some((host, path)) = parse_bracketed_remote_endpoint(raw) {
|
||||||
|
return CopyEndpoint::Remote { host, path };
|
||||||
|
}
|
||||||
|
if raw.starts_with('[') {
|
||||||
|
return CopyEndpoint::Local(PathBuf::from(raw));
|
||||||
|
}
|
||||||
let Some(index) = raw.find(':') else {
|
let Some(index) = raw.find(':') else {
|
||||||
return CopyEndpoint::Local(PathBuf::from(raw));
|
return CopyEndpoint::Local(PathBuf::from(raw));
|
||||||
};
|
};
|
||||||
@@ -183,6 +189,25 @@ pub fn parse_copy_endpoint(raw: &str) -> CopyEndpoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_bracketed_remote_endpoint(raw: &str) -> Option<(String, String)> {
|
||||||
|
let rest = raw.strip_prefix('[')?;
|
||||||
|
let close = rest.find(']')?;
|
||||||
|
let host = &rest[..close];
|
||||||
|
let suffix = &rest[close + 1..];
|
||||||
|
if host.is_empty() || host.contains('/') || host.contains('\\') || !suffix.starts_with(':') {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let path = &suffix[1..];
|
||||||
|
Some((
|
||||||
|
host.to_string(),
|
||||||
|
if path.is_empty() {
|
||||||
|
".".to_string()
|
||||||
|
} else {
|
||||||
|
path.to_string()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum CopyEndpoint {
|
pub enum CopyEndpoint {
|
||||||
Local(PathBuf),
|
Local(PathBuf),
|
||||||
@@ -277,4 +302,30 @@ mod tests {
|
|||||||
CopyEndpoint::Local(PathBuf::from("C:\\Users\\palav\\x"))
|
CopyEndpoint::Local(PathBuf::from("C:\\Users\\palav\\x"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn copy_endpoint_parses_bracketed_ipv6_remote_paths() {
|
||||||
|
assert_eq!(
|
||||||
|
parse_copy_endpoint("[2001:db8::1]:/var/log/syslog"),
|
||||||
|
CopyEndpoint::Remote {
|
||||||
|
host: "2001:db8::1".to_string(),
|
||||||
|
path: "/var/log/syslog".to_string()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_copy_endpoint("[::1]:"),
|
||||||
|
CopyEndpoint::Remote {
|
||||||
|
host: "::1".to_string(),
|
||||||
|
path: ".".to_string()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_copy_endpoint("[bad/host]:path"),
|
||||||
|
CopyEndpoint::Local(PathBuf::from("[bad/host]:path"))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_copy_endpoint("[::1]"),
|
||||||
|
CopyEndpoint::Local(PathBuf::from("[::1]"))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user