Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ All notable changes to this project will be documented in this file.

---

## [0.26.9] - 2026-01-27

### Fixed (0.26.9)

- **GitHub Remote Detection**: Extended URL pattern matching to support all valid GitHub URL formats
- **Added Support**: Now detects `ssh://git@github.com/owner/repo.git` and `git://github.com/owner/repo.git` formats
- **Root Cause**: Previous regex only matched `https?://` and scp-style `git@host:path` URLs, causing regression for repos using `ssh://` or `git://` schemes
- **Solution**: Extended regex pattern to include `ssh://` and `git://` schemes, with proper URL parsing for hostname validation
- **Impact**: All valid GitHub URL formats are now properly detected, ensuring GitHub adapter is selected correctly

- **Code Scanning Vulnerabilities**: Mitigated all 13 code scanning findings
- **ReDoS Fix**: Replaced regex-based section removal with line-by-line processing in `github_mapper.py`
- **URL Sanitization**: Replaced substring matching with proper URL parsing using `urllib.parse.urlparse()` in multiple files
- **Workflow Permissions**: Added explicit `permissions: contents: read` blocks to 7 GitHub Actions jobs
- **SSH Host Aliases**: Added support for `ssh.github.com` SSH host alias detection
- **Test Fixes**: Fixed async cleanup issues in test mode for progress display utilities

## [0.26.8] - 2026-01-27

### Fixed (0.26.8)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "specfact-cli"
version = "0.26.8"
version = "0.26.9"
description = "Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions."
readme = "README.md"
requires-python = ">=3.11"
Expand Down
18 changes: 12 additions & 6 deletions src/specfact_cli/adapters/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,21 +450,27 @@ def detect(self, repo_path: Path, bridge_config: BridgeConfig | None = None) ->
config_content = git_config.read_text(encoding="utf-8")
# Use proper URL parsing to avoid substring matching vulnerabilities
# Look for URL patterns in git config and validate the hostname
url_pattern = re.compile(r"url\s*=\s*(https?://[^\s]+|git@[^:]+:[^\s]+)")
# Match: https?://, ssh://, git://, and scp-style git@host:path URLs
url_pattern = re.compile(r"url\s*=\s*(https?://[^\s]+|ssh://[^\s]+|git://[^\s]+|git@[^:]+:[^\s]+)")
# Official GitHub SSH hostnames
github_ssh_hosts = {"github.com", "ssh.github.com"}
for match in url_pattern.finditer(config_content):
url_str = match.group(1)
# Handle git@ format: git@github.com:user/repo.git or git@ssh.github.com:user/repo.git
# Handle scp-style git@ format: git@github.com:user/repo.git or git@ssh.github.com:user/repo.git
if url_str.startswith("git@"):
host_part = url_str.split(":")[0].replace("git@", "")
host_part = url_str.split(":")[0].replace("git@", "").lower()
if host_part in github_ssh_hosts:
Comment thread
djm81 marked this conversation as resolved.
return True
else:
# Parse HTTP/HTTPS URLs properly
# Parse HTTP/HTTPS/SSH/GIT URLs properly
parsed = urlparse(url_str)
if parsed.hostname and parsed.hostname.lower() == "github.com":
return True
if parsed.hostname:
hostname_lower = parsed.hostname.lower()
# Check for GitHub hostnames (github.com for all schemes, ssh.github.com for SSH)
if hostname_lower == "github.com":
return True
if parsed.scheme == "ssh" and hostname_lower == "ssh.github.com":
return True
except Exception:
pass

Expand Down
Loading