claude-code: read front matter as YAML and refuse a file reference outside the item
A byte-order mark, a flow mapping or a merged key hid a key the line scan looked for, and @path read any file into every session the item reached (hq issue 340 review).
This commit is contained in:
@@ -289,3 +289,53 @@ func TestThePluginsOnlyHookIsTheGuard(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Front matter is read as the agent's own reader might read it (novox/hq issue 340): after a byte-order mark, in
|
||||
// flow style, with quoted or merged keys. What does not parse, does not close, or is not a mapping is refused
|
||||
// rather than guessed at.
|
||||
func TestFrontMatterIsReadAsYAMLOrRefused(t *testing.T) {
|
||||
skill := func(md string) Item {
|
||||
return Item{Kind: KindSkill, Name: "x", Scope: ScopeMesh, Files: map[string]string{"SKILL.md": md}}
|
||||
}
|
||||
for label, md := range map[string]string{
|
||||
"a byte-order mark": "\ufeff---\nname: x\nallowed-tools: Bash\n---\nbody\n",
|
||||
"a flow mapping": "---\n{name: x, allowed-tools: Bash}\n---\nbody\n",
|
||||
"a quoted key": "---\nname: x\n\"hooks\": {}\n---\nbody\n",
|
||||
"a merged key": "---\nbase: &b {hooks: {}}\n<<: *b\nname: x\n---\nbody\n",
|
||||
"blank lines before it": "\n\n---\nname: x\nallowed_tools: Bash\n---\nbody\n",
|
||||
"carriage returns": "---\r\nname: x\r\nallowed-tools: Bash\r\n---\r\nbody\r\n",
|
||||
"no YAML": "---\nname: x\n bad: [\n---\nbody\n",
|
||||
"not a mapping": "---\n- allowed-tools\n---\nbody\n",
|
||||
"never closed": "---\nname: x\nallowed-tools: Bash\n",
|
||||
"a duplicate key": "---\nname: x\nname: y\n---\nbody\n",
|
||||
} {
|
||||
if problem := skill(md).Problem(); !strings.Contains(problem, "issue 340") {
|
||||
t.Errorf("%s was taken: %q", label, problem)
|
||||
}
|
||||
}
|
||||
if problem := skill("---\nname: x\ndescription: \"a: b\"\nwhen_to_use: [a, b]\n---\nbody\n").Problem(); problem != "" {
|
||||
t.Errorf("plain front matter was refused: %s", problem)
|
||||
}
|
||||
}
|
||||
|
||||
// A skill or a command refers only to its own files (novox/hq issue 340): `@path` reads a file into the prompt when
|
||||
// the item loads, so one outside it would put another file's words, or a secret, in every session it reaches.
|
||||
func TestAFileReferenceOutsideTheItemIsRefused(t *testing.T) {
|
||||
for _, ref := range []string{"@~/.ssh/id_ed25519", "@/etc/shadow", "@../other/SKILL.md", "@README.md", "(@./notes.md)",
|
||||
"@scripts/../../x.sh", "@Makefile", "@$HOME/.netrc"} {
|
||||
it := Item{Kind: KindSkill, Name: "x", Scope: ScopeMesh, Files: map[string]string{
|
||||
"SKILL.md": "---\nname: x\n---\nRead " + ref + " first.\n", "scripts/run.sh": "#!/bin/sh\n"}}
|
||||
if problem := it.Problem(); !strings.Contains(problem, "outside") {
|
||||
t.Errorf("%s was taken: %q", ref, problem)
|
||||
}
|
||||
cmd := Item{Kind: KindCommand, Name: "x", Scope: ScopeHome, Files: one("x", "Look at "+ref)}
|
||||
if problem := cmd.Problem(); !strings.Contains(problem, "outside") {
|
||||
t.Errorf("%s in a command was taken: %q", ref, problem)
|
||||
}
|
||||
}
|
||||
own := Item{Kind: KindSkill, Name: "x", Scope: ScopeMesh, Files: map[string]string{
|
||||
"SKILL.md": "---\nname: x\n---\nRun @scripts/run.sh. Mail jochen@example.org.\n", "scripts/run.sh": "#!/bin/sh\n"}}
|
||||
if problem := own.Problem(); problem != "" {
|
||||
t.Errorf("a reference to its own file or a mail address was refused: %s", problem)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user