From 573d9a641ecb780a0e018468b0ac12e2395881d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A8NW=C2=A8?= <¨neroworld@mail.ru¨> Date: Sun, 19 Apr 2026 12:17:53 +0100 Subject: [PATCH] fix(security): add rstrip('/') to get_target_repo for trailing-slash URLs The regex r'[:/]([^/]+/[^/]+?)(?:\.git)?$' fails on URLs with trailing slashes like 'https://git.softuniq.eu/UniqueSoft/APAW/' because the final '/' breaks the pattern. Added .rstrip('/') in Python and sed 's:/*' in Bash to all get_target_repo() implementations across 11 files. --- .kilo/commands/landing-page.md | 2 +- .kilo/commands/pipeline.md | 2 +- .kilo/commands/workflow.md | 2 +- .kilo/rules/gitea-centric-workflow.md | 2 +- .kilo/shared/gitea-api.md | 6 +++--- .kilo/skills/gitea-commenting/SKILL.md | 6 +++--- .kilo/skills/gitea-workflow/SKILL.md | 2 +- .kilo/skills/gitea/SKILL.md | 2 +- .kilo/skills/task-analysis/SKILL.md | 4 ++-- AGENTS.md | 2 +- README.md | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.kilo/commands/landing-page.md b/.kilo/commands/landing-page.md index 45c6947..c2e4890 100644 --- a/.kilo/commands/landing-page.md +++ b/.kilo/commands/landing-page.md @@ -114,7 +114,7 @@ def get_target_repo(): """Detect target project from git remote — see .kilo/shared/gitea-auth.md""" try: result = subprocess.run(['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True) - match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip()) + match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip().rstrip('/')) if match: return match.group(1) except Exception: diff --git a/.kilo/commands/pipeline.md b/.kilo/commands/pipeline.md index 1e8f7c0..7cd980b 100644 --- a/.kilo/commands/pipeline.md +++ b/.kilo/commands/pipeline.md @@ -64,7 +64,7 @@ After each agent completes, post comment to the TARGET project issue (NOT APAW): ```bash # Auto-detect target project -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') # Post comment using target project curl -X POST -H "Authorization: token ${GITEA_TOKEN}" \ diff --git a/.kilo/commands/workflow.md b/.kilo/commands/workflow.md index cf19998..baff914 100644 --- a/.kilo/commands/workflow.md +++ b/.kilo/commands/workflow.md @@ -79,7 +79,7 @@ def get_target_repo(): """Detect target project from git remote — see .kilo/shared/gitea-auth.md""" try: result = subprocess.run(['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True) - match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip()) + match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip().rstrip('/')) if match: return match.group(1) except Exception: diff --git a/.kilo/rules/gitea-centric-workflow.md b/.kilo/rules/gitea-centric-workflow.md index 4bc8974..be14097 100644 --- a/.kilo/rules/gitea-centric-workflow.md +++ b/.kilo/rules/gitea-centric-workflow.md @@ -71,7 +71,7 @@ def get_target_repo(): ['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True ) - remote_url = result.stdout.strip() + remote_url = result.stdout.strip().rstrip('/') # HTTPS: https://git.softuniq.eu/Owner/Repo.git # SSH: git@git.softuniq.eu:Owner/Repo.git diff --git a/.kilo/shared/gitea-api.md b/.kilo/shared/gitea-api.md index aed823b..923ae43 100644 --- a/.kilo/shared/gitea-api.md +++ b/.kilo/shared/gitea-api.md @@ -17,7 +17,7 @@ def get_target_repo(): ['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True ) - remote_url = result.stdout.strip() + remote_url = result.stdout.strip().rstrip('/') # HTTPS: https://git.softuniq.eu/Owner/Repo.git # SSH: git@git.softuniq.eu:Owner/Repo.git @@ -51,7 +51,7 @@ def get_target_repo(): ['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True ) - remote_url = result.stdout.strip() + remote_url = result.stdout.strip().rstrip('/') match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', remote_url) if match: return match.group(1) @@ -89,7 +89,7 @@ def create_issue(title, body, labels=None, repo=None): ```bash # Auto-detect target repo -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') # Post comment curl -X POST -H "Authorization: token ${GITEA_TOKEN}" \ diff --git a/.kilo/skills/gitea-commenting/SKILL.md b/.kilo/skills/gitea-commenting/SKILL.md index 46e683a..03e3911 100644 --- a/.kilo/skills/gitea-commenting/SKILL.md +++ b/.kilo/skills/gitea-commenting/SKILL.md @@ -63,7 +63,7 @@ Please respond with your choice. ```bash # Auto-detect target repo -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') # Using curl with GITEA_TOKEN curl -X POST \ @@ -90,7 +90,7 @@ def get_target_repo(): ['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True ) - remote_url = result.stdout.strip() + remote_url = result.stdout.strip().rstrip('/') match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', remote_url) if match: return match.group(1) @@ -206,7 +206,7 @@ def upload_screenshot(issue_number, screenshot_path, description="Error screensh if repo is None: try: result = subprocess.run(['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True) - match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip()) + match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip().rstrip('/')) repo = match.group(1) if match else os.environ.get('GITEA_TARGET_REPO', 'UniqueSoft/APAW') except Exception: repo = os.environ.get('GITEA_TARGET_REPO', 'UniqueSoft/APAW') diff --git a/.kilo/skills/gitea-workflow/SKILL.md b/.kilo/skills/gitea-workflow/SKILL.md index c319932..51a5678 100644 --- a/.kilo/skills/gitea-workflow/SKILL.md +++ b/.kilo/skills/gitea-workflow/SKILL.md @@ -29,7 +29,7 @@ class GiteaClient: ['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True ) - remote_url = result.stdout.strip() + remote_url = result.stdout.strip().rstrip('/') match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', remote_url) if match: return match.group(1) diff --git a/.kilo/skills/gitea/SKILL.md b/.kilo/skills/gitea/SKILL.md index 75abfda..cb86a16 100644 --- a/.kilo/skills/gitea/SKILL.md +++ b/.kilo/skills/gitea/SKILL.md @@ -118,7 +118,7 @@ If Gitea token is available: ```bash # Auto-detect target repo -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') ``` Project URL: `https://git.softuniq.eu/{TARGET_REPO}` diff --git a/.kilo/skills/task-analysis/SKILL.md b/.kilo/skills/task-analysis/SKILL.md index 0b076fd..b1a7504 100644 --- a/.kilo/skills/task-analysis/SKILL.md +++ b/.kilo/skills/task-analysis/SKILL.md @@ -20,7 +20,7 @@ git log --all --oneline --grep="" git log --all --oneline -- "" # Search issues for similar tasks (auto-detect repo) -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') curl -s "https://git.softuniq.eu/api/v1/repos/${TARGET_REPO}/issues?state=all" | \ python3 -c "import sys,json; [print(f\"#{i['number']}: {i['title']}\") for i in json.load(sys.stdin) if '' in i['title'].lower()]" ``` @@ -73,7 +73,7 @@ def get_target_repo(): import subprocess, re try: result = subprocess.run(['git', 'remote', 'get-url', 'origin'], capture_output=True, text=True) - match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip()) + match = re.search(r'[:/]([^/]+/[^/]+?)(?:\.git)?$', result.stdout.strip().rstrip('/')) if match: return match.group(1) except Exception: diff --git a/AGENTS.md b/AGENTS.md index 814131f..c5d7a82 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -412,7 +412,7 @@ bun run scripts/agent-stats.ts --project UniqueSoft/my-shop ```bash # Auto-detect from git remote -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') ``` ### Atomic Tasks (1 action = 1 task) diff --git a/README.md b/README.md index eb9bc7b..bc3c490 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ bun run agent:stats --project UniqueSoft/my-shop ```bash # Автоопределение проекта из git remote -TARGET_REPO=$(git remote get-url origin | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') +TARGET_REPO=$(git remote get-url origin | sed 's:/*$::' | sed -E 's|.*[:/]([^/]+/[^/]+?)(\.git)?$|\1|') ``` ### Атомарные задачи (1 действие = 1 задача)