diff --git a/src/github/pr-actions.ts b/src/github/pr-actions.ts index 7917733727..4ab82725d4 100644 --- a/src/github/pr-actions.ts +++ b/src/github/pr-actions.ts @@ -21,11 +21,11 @@ const COMMIT_MESSAGES_PAGE_SIZE = 100; // recorded, not swallowed. function splitRepo(repoFullName: string): { owner: string; repo: string } { - if (repoFullName !== repoFullName.trim()) { - throw new Error(`Invalid repository full name: ${repoFullName}`); - } + // Reject any whitespace (leading, trailing, or per-segment like `owner/ repo`) so a padded slug can never + // reach a GitHub call — a valid owner/repo name never contains spaces. Mirrors parseRepoFullName in + // assignees.ts / labels.ts (#6613). const parts = repoFullName.split("/"); - if (parts.length !== 2 || !parts[0] || !parts[1]) { + if (parts.length !== 2 || !parts[0] || !parts[1] || /\s/.test(repoFullName)) { throw new Error(`Invalid repository full name: ${repoFullName}`); } return { owner: parts[0], repo: parts[1] }; diff --git a/test/unit/github-pr-actions.test.ts b/test/unit/github-pr-actions.test.ts index 3e3293c145..de2e8989d3 100644 --- a/test/unit/github-pr-actions.test.ts +++ b/test/unit/github-pr-actions.test.ts @@ -21,6 +21,12 @@ describe("GitHub PR action primitives (#778)", () => { await expect(closePullRequest(createTestEnv(), 1, " owner/repo ", 4)).rejects.toThrow( /Invalid repository full name/, ); + // Per-segment padding (#6613) — mirrors assignees.ts parseRepoFullName coverage. + for (const padded of ["owner/ repo", "owner /repo"]) { + await expect(closePullRequest(createTestEnv(), 1, padded, 4)).rejects.toThrow( + /Invalid repository full name/, + ); + } let called = false; vi.stubGlobal("fetch", async () => { called = true; @@ -32,6 +38,11 @@ describe("GitHub PR action primitives (#778)", () => { await expect(closePullRequest(envWithKey(), 1, " owner/repo ", 4)).rejects.toThrow( /Invalid repository full name/, ); + for (const padded of ["owner/ repo", "owner /repo"]) { + await expect(closePullRequest(envWithKey(), 1, padded, 4)).rejects.toThrow( + /Invalid repository full name/, + ); + } expect(called).toBe(false); });