|
2 | 2 | /// <reference types="@actions/github-script" /> |
3 | 3 |
|
4 | 4 | const fs = require("fs"); |
| 5 | +const { spawnSync } = require("child_process"); |
5 | 6 |
|
6 | 7 | const AGENT_OUTPUT_PATH = "/tmp/gh-aw/agent_output.json"; |
7 | | -const SAFE_BRANCH_NAME_REGEX = /^[a-zA-Z0-9/_.-]+$/; |
| 8 | +const MAX_BRANCH_NAME_LENGTH = 255; |
8 | 9 |
|
9 | 10 | /** |
10 | 11 | * @param {string} itemRepo |
@@ -49,9 +50,26 @@ function extractBaseBranchFromAgentOutput(opts = {}) { |
49 | 50 | async function main() { |
50 | 51 | const baseBranch = extractBaseBranchFromAgentOutput(); |
51 | 52 | if (!baseBranch) return; |
52 | | - if (!SAFE_BRANCH_NAME_REGEX.test(baseBranch) || baseBranch.length > 255) return; |
| 53 | + if (!isValidBaseBranchName(baseBranch)) return; |
53 | 54 | core.setOutput("base-branch", baseBranch); |
54 | 55 | core.info(`Extracted base branch from safe output: ${baseBranch}`); |
55 | 56 | } |
56 | 57 |
|
57 | | -module.exports = { extractBaseBranchFromAgentOutput, isSameWorkflowRepo, main }; |
| 58 | +/** |
| 59 | + * @param {string} branchName |
| 60 | + * @returns {boolean} |
| 61 | + */ |
| 62 | +function isValidBaseBranchName(branchName) { |
| 63 | + if (!branchName || branchName.length > MAX_BRANCH_NAME_LENGTH) { |
| 64 | + return false; |
| 65 | + } |
| 66 | + |
| 67 | + // Use refs/heads/<name> to validate as a literal ref, not a branch expression. |
| 68 | + // --branch also accepts @{-N} git expressions; refs/heads/ form correctly rejects them. |
| 69 | + // Fail-closed: if git is unavailable (ENOENT) or times out (ETIMEDOUT), result.error is set |
| 70 | + // and we return false, safely dropping the base branch rather than passing an invalid value. |
| 71 | + const result = spawnSync("git", ["check-ref-format", `refs/heads/${branchName}`], { stdio: "ignore", timeout: 5000 }); |
| 72 | + return !result.error && result.status === 0; |
| 73 | +} |
| 74 | + |
| 75 | +module.exports = { extractBaseBranchFromAgentOutput, isSameWorkflowRepo, isValidBaseBranchName, main }; |
0 commit comments