Skip to content

fix: handle IPv6 bracketed hosts in strip_ssh_port#310

Merged
sachiniyer merged 1 commit into
mainfrom
devin/1780685047-fix-ipv6-ssh-port-strip
Jun 5, 2026
Merged

fix: handle IPv6 bracketed hosts in strip_ssh_port#310
sachiniyer merged 1 commit into
mainfrom
devin/1780685047-fix-ipv6-ssh-port-strip

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

strip_ssh_port used split_once(':') to separate host from port, which splits inside an IPv6 literal like [::1]:22 — producing a corrupt ssh://git@[/owner/repo.git.

Fix: for bracketed hosts, split on "]:"; otherwise rsplit_once(':'):

let host = if host_port.starts_with('[') {
    host_port.split_once("]:").map(|(h, _)| format!("{h}]"))?
} else {
    host_port.rsplit_once(':').map(|(h, _)| h.to_string())?
};

Adds strip_ssh_port_handles_ipv6 test.

Closes #309

Link to Devin session: https://app.devin.ai/sessions/e9a8b1c51a604a08b3642f119c1c7384
Requested by: @sachiniyer


Open in Devin Review

Summary by cubic

Fixes URL parsing for SSH URLs with IPv6 bracketed hosts by correctly stripping the port without corrupting the host. Prevents malformed URLs like ssh://git@[/owner/repo.git when the input includes [::1]:22.

  • Bug Fixes
    • For bracketed hosts, split on "]:", otherwise use rsplit_once(':') in strip_ssh_port.
    • Added test strip_ssh_port_handles_ipv6.

Written for commit 7eebc4e. Summary will update on new commits.

Review in cubic

The split_once(':') call split inside the IPv6 literal [::1], producing
a corrupt URL. Now split on "]:" for bracketed hosts and rsplit_once(':')
otherwise.

Closes #309

Co-Authored-By: Sachin Iyer <siyer@detail.dev>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author
Original prompt from Sachin

Fix GitHub issue #309 in usedetail/cli: "Git SSH URL normalization corrupts IPv6 host when stripping port"

#``# Repository
usedetail/cli (https://github.com/usedetail/cli)

#``# Bug
In src/utils/git.rs, the strip_ssh_port function (around line 35-48) uses split_once(':') to split host from port. This breaks IPv6 bracketed hosts like ssh://git@[::1]:22/owner/repo.git because the first colon is inside the IPv6 literal [::1], producing a corrupt URL like ssh://git@[/owner/repo.git.

#``# Fix
Handle bracketed IPv6 hosts by splitting on "]:"; otherwise split on the last ::

let host = if host_port.starts_with('[') {
    host_port.split_once("]:").map(|(h, _)| format!("{h}]"))?
} else {
    host_port.rsplit_once(':').map(|(h, _)| h.to_string())?
};

#``# Requirements

  1. Fix the strip_ssh_port function to correctly handle IPv6 bracketed hosts
  2. Add a test for IPv6 SSH URL port stripping:
`#`[test]
fn strip_ssh_port_handles_ipv6() {
    let result = strip_ssh_port("ssh://git`@`[::1]:22/owner/repo.git");
    assert_eq!(result, Some("ssh://git`@`[::1]/owner/repo.git".to_string()));
}
  1. Ensure all existing tests still pass (cargo test)
  2. Ensure cargo fmt --check and cargo clippy -- -D warnings pass
  3. Create a PR that closes #309

@aviator-app

aviator-app Bot commented Jun 5, 2026

Copy link
Copy Markdown

Current Aviator status

Aviator will automatically update this comment as the status of the PR changes.
Comment /aviator refresh to force Aviator to re-examine your PR (or learn about other /aviator commands).

This PR was merged manually (without Aviator). Merging manually can negatively impact the performance of the queue. Consider using Aviator next time.


See the real-time status of this PR on the Aviator webapp.
Use the Aviator Chrome Extension to see the status of your PR within GitHub.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread src/utils/git.rs
// IPv6 bracketed host, e.g. `[::1]:22` — split on `]:`.
host_port.split_once("]:").map(|(h, _)| format!("{h}]"))?
} else {
host_port.rsplit_once(':').map(|(h, _)| h.to_string())?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Behavioral change from split_once to rsplit_once in non-IPv6 path

Line 50 changes from split_once(':') to rsplit_once(':'). For valid SSH authority strings like github.com:22, these are equivalent since there is exactly one colon. The only difference would arise for malformed authorities with multiple colons (e.g. host:foo:22), where split_once would yield host=host while rsplit_once yields host=host:foo. Since such authorities are not valid URL forms and cannot match GitHub's hostname anyway, this is a safe change — but it is a subtle semantic difference worth noting.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on the semantic difference. As noted, for any well-formed SSH authority there's exactly one colon separating host from port, so split_once and rsplit_once are equivalent. The switch to rsplit_once is intentional — it's the more defensive choice for the non-IPv6 path, mirroring RFC 3986's rule that the port is the segment after the last colon in the host info. Agreed this is safe.

@sachiniyer sachiniyer merged commit cac8b77 into main Jun 5, 2026
13 checks passed
@sachiniyer sachiniyer deleted the devin/1780685047-fix-ipv6-ssh-port-strip branch June 5, 2026 18:55
sachiniyer added a commit that referenced this pull request Jun 12, 2026
## Summary

Patch release bump `0.2.5` → `0.2.6`. Includes fixes merged since
v0.2.5:

- `#313` serialize SHELL env var mutation in completions tests
- `#312` validate `$SHELL` before extracting shell name in completions
- `#311` warn on config parse errors during auth login
- `#310` handle IPv6 bracketed hosts in `strip_ssh_port`

Once merged, the `release.yml` workflow will automatically tag `v0.2.6`,
build platform artifacts via `cargo-dist`, and publish a GitHub Release.

Link to Devin session:
https://app.devin.ai/sessions/02dfe916725247d6955ba0d4a49460df
Requested by: @sachiniyer
<!-- devin-review-badge-begin -->

---

<a href="https://app.devin.ai/review/usedetail/cli/pull/315"
target="_blank">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open in Devin Review">
  </picture>
</a>
<!-- devin-review-badge-end -->

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Release v0.2.6 to ship fixes for shell detection, SSH host parsing, and
clearer auth warnings, plus more reliable completion tests.

- **Bug Fixes**
- Serialize `SHELL` env var mutation in completions tests to prevent
flakiness.
  - Validate `$SHELL` before extracting the shell name in completions.
  - Warn on config parse errors during `auth login`.
  - Handle IPv6 bracketed hosts in `strip_ssh_port`.

<sup>Written for commit db9999c.
Summary will update on new commits.</sup>

<a href="https://cubic.dev/pr/usedetail/cli/pull/315?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Sachin Iyer <siyer@detail.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] Git SSH URL normalization corrupts IPv6 host when stripping port

1 participant