fix(skillpack): address review — symlink read, git arg-injection, dup-subscribe, nil panics
executus CI / test (pull_request) Successful in 3m30s
executus CI / test (pull_request) Successful in 3m30s
Real issues from the PR review: - security: readTree now skips symlinks (a pack with SKILL.md -> /etc/passwd or scripts/x -> ../../.ssh/id_rsa could read host files); covers file and dir symlinks, incl. within a git subpath - security: GitSource rejects url/ref beginning with '-' (git arg injection) and clones with '--' separator; --filter=blob:none (blobless partial clone) instead of full-history clone - correctness: Subscribe no longer swallows a non-ErrNotFound store error from GetByName (would create a duplicate subscription); handles *GitSource as well as GitSource in the URL/subpath extraction - correctness: pinTo no longer renames a subscription, so Apply can't silently collide two subscriptions when an upstream pack changes its name - validation: isKebab rejects leading/trailing/consecutive hyphens; BOM- prefixed SKILL.md now parses (matches the doc comment) - robustness: Catalog/Activate/renderPackBody/Stage guard nil/malformed packs - test cleanup: Syncer.Store field renamed Cache (collided with the Store interface); test NewID returns distinct ids - tests: symlink-skip, BOM, strict-kebab, nil-pack-safety Deferred (advisory perf, documented): PackCache stores raw trees so activation re-parses; CheckAll is serial. Both fine at expected scale. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,25 @@ func TestActivate_Empty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilPackElementsAreSafe(t *testing.T) {
|
||||
packs := []*Pack{nil, mustPack(t, "real", "b", nil), {Manifest: nil}}
|
||||
// Neither Catalog nor Activate may panic on nil / malformed elements.
|
||||
if got := Catalog(packs); !strings.Contains(got, "real") {
|
||||
t.Errorf("catalog should include the valid pack and skip nils: %q", got)
|
||||
}
|
||||
sk := Activate(packs, "")
|
||||
if sk == nil {
|
||||
t.Fatal("a valid pack among nils should still activate")
|
||||
}
|
||||
if _, ok := sk.Tools().Get("skill_use"); !ok {
|
||||
t.Error("skill_use missing")
|
||||
}
|
||||
// All-nil activates to nothing rather than panicking.
|
||||
if Activate([]*Pack{nil, {Manifest: nil}}, "") != nil {
|
||||
t.Error("only-nil packs should activate to nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveFromCache(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cache := NewMemoryPackCache()
|
||||
|
||||
Reference in New Issue
Block a user