mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Reject placeholder tokens when parsing branches
A message quoting a template command — `git checkout -b <branch>` — parsed the literal "<branch>" as the chat's branch and the work panel chip displayed it. Every command-parsed candidate now has to look like a real git ref (alphanumeric start, ref charset, not a sha); the prose patterns were already restricted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f682796d43
commit
d2d26bc07c
@@ -141,3 +141,22 @@ test("non-agent messages and branchless text derive nothing", () => {
|
||||
);
|
||||
assert.equal(deriveBranchFromAgentMessages([], null), null);
|
||||
});
|
||||
|
||||
test("placeholder tokens in template commands never parse as branches", () => {
|
||||
assert.equal(parseBranchFromCommand("git checkout -b <branch>"), null);
|
||||
assert.equal(parseBranchFromCommand("git switch <name>"), null);
|
||||
assert.equal(parseBranchFromCommand("git worktree add ../wt <branch>"), null);
|
||||
assert.equal(parseBranchFromCommand("git worktree add ../<dir>"), null);
|
||||
assert.equal(
|
||||
deriveBranchFromAgentMessages(
|
||||
[
|
||||
{
|
||||
pubkey: "cd".repeat(32),
|
||||
content: "Run `git checkout -b <branch>` to start.",
|
||||
},
|
||||
],
|
||||
"cd".repeat(32),
|
||||
),
|
||||
null,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -123,12 +123,13 @@ function parseWorktreeAdd(args: string[]): string | null {
|
||||
if (positional.length >= 2) {
|
||||
// `git worktree add <path> <branch>` — a commit-ish second arg (sha)
|
||||
// isn't a branch name worth showing.
|
||||
return looksLikeSha(positional[1]) ? null : positional[1];
|
||||
return isPlausibleBranchName(positional[1]) ? positional[1] : null;
|
||||
}
|
||||
if (positional.length === 1) {
|
||||
// `git worktree add <path>` creates a branch named after the basename.
|
||||
const parts = positional[0].split("/").filter(Boolean);
|
||||
return parts[parts.length - 1] || null;
|
||||
const basename = parts[parts.length - 1] ?? "";
|
||||
return isPlausibleBranchName(basename) ? basename : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -145,7 +146,7 @@ function parseCheckoutOrSwitch(args: string[]): string | null {
|
||||
return null;
|
||||
}
|
||||
const positional = args.filter((token) => !token.startsWith("-"));
|
||||
if (positional.length !== 1 || looksLikeSha(positional[0])) {
|
||||
if (positional.length !== 1 || !isPlausibleBranchName(positional[0])) {
|
||||
return null;
|
||||
}
|
||||
return positional[0];
|
||||
@@ -155,7 +156,7 @@ function valueOfFlag(args: string[], flags: string[]): string | null {
|
||||
for (let index = 0; index < args.length; index += 1) {
|
||||
if (flags.includes(args[index])) {
|
||||
const value = args[index + 1];
|
||||
if (value && !value.startsWith("-")) {
|
||||
if (value && isPlausibleBranchName(value)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -163,6 +164,15 @@ function valueOfFlag(args: string[], flags: string[]): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Real git ref charset, no placeholders: template text like
|
||||
* `git checkout -b <branch>` in an explanatory message must never surface
|
||||
* "<branch>" as the chip's branch.
|
||||
*/
|
||||
function isPlausibleBranchName(token: string): boolean {
|
||||
return /^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(token) && !looksLikeSha(token);
|
||||
}
|
||||
|
||||
function looksLikeSha(token: string): boolean {
|
||||
return /^[0-9a-f]{7,40}$/i.test(token);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user