git: Detect SCP remotes with non-standard SSH usernames (#59457)
# Objective The scp-style remote rewrite only treats a leading `user@` as SSH when the username matches `^[0-9a-zA-Z\-_]+@`. Remotes like `first.last@host:owner/repo.git` (common on self-hosted instances that authenticate as the developer) therefore fail to parse, so no hosting provider matches and Copy Permalink, git blame links, and Open in browser silently break. Extends #21508, which added `org-000000@`. ## Solution Match the scp username by exclusion (`^[^/@:]+@`): anything before the `@` that isn't the `:`/`/` delimiting host and path, mirroring git's scp syntax. The pattern stays anchored, so `scheme://user@host` URLs aren't misclassified, and it's a strict superset of the old one, so existing remotes are unaffected. ## Testing `cargo test -p git` passes, including two new `test_parsing_valid_remote_urls` cases — a dotted-username scp remote (the fix) and a `https://user@host` regression guard. `cargo fmt` and `cargo clippy -p git` are clean. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed detection of SSH git remotes whose username contains characters such as `.` (e.g. `first.last@host:owner/repo.git`), which previously broke permalinks, git blame links, and "open in browser". --------- Co-authored-by: dino <dinojoaocosta@gmail.com>
This commit is contained in:
1 parent
d1eb52166e
commit
790b73e2fb
1 file changed
+17
-1
@@ -9,8 +9,12 @@ use url::Url;
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deref)]
|
||||
pub struct RemoteUrl(Url);
|
||||
|
||||
// Detect the `user@` prefix of an SCP-like remote (e.g. `git@host:path`). The
|
||||
// username may contain anything but the `@`/`:`/`/` that delimit the user,
|
||||
// host, and path, so match by exclusion rather than an allowlist that misses
|
||||
// names like `first.last`.
|
||||
static USERNAME_REGEX: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"^[0-9a-zA-Z\-_]+@").expect("Failed to create USERNAME_REGEX"));
|
||||
LazyLock::new(|| Regex::new(r"^[^/@:]+@").expect("Failed to create USERNAME_REGEX"));
|
||||
|
||||
impl FromStr for RemoteUrl {
|
||||
type Err = url::ParseError;
|
||||
@@ -41,6 +45,12 @@ mod tests {
|
||||
"github.com",
|
||||
"/octocat/zed.git",
|
||||
),
|
||||
(
|
||||
"https://jlannister@github.com/octocat/zed.git",
|
||||
"https",
|
||||
"github.com",
|
||||
"/octocat/zed.git",
|
||||
),
|
||||
(
|
||||
"git@github.com:octocat/zed.git",
|
||||
"ssh",
|
||||
@@ -53,6 +63,12 @@ mod tests {
|
||||
"github.com",
|
||||
"/octocat/zed.git",
|
||||
),
|
||||
(
|
||||
"first.last@gitlab.example.com:group/repo.git",
|
||||
"ssh",
|
||||
"gitlab.example.com",
|
||||
"/group/repo.git",
|
||||
),
|
||||
(
|
||||
"ssh://git@github.com/octocat/zed.git",
|
||||
"ssh",
|
||||
|
||||
Reference in new issue
Block a user