-
Notifications
You must be signed in to change notification settings - Fork 43
Description
I'm still trying to narrow this down to a reproducer, but figured I'd file an issue just to get started.
I've been running capslock-git-diff on internal pipelines at work, and by and large it doesn't report changes -- which is to be expected, most libraries don't change capabilities that often. However, today, I upgraded one internal service to start using 1.26, and ran go fix as part of that. Among other changes, it updated two usages of a range over strings.Split to instead range over strings.SplitSeq; a straightforward enough change.
However, capslock-git-diff reports:
❯ capslock-git-diff -v master .
2026/02/25 23:19:27 analyzing at revision "master"
2026/02/25 23:19:27 running git with args ["rev-parse" "--git-dir"]
2026/02/25 23:19:27 git directory: ".git"
2026/02/25 23:19:27 running git with args ["rev-parse" "--show-prefix"]
2026/02/25 23:19:27 current path in repository: ""
2026/02/25 23:19:27 running git with args ["clone" "--shared" "--no-checkout" "--" ".git" "/var/folders/vl/k9dw37lx0x5bbtzj98plsqbh0000gp/T/2381433021"]
Cloning into '/var/folders/vl/k9dw37lx0x5bbtzj98plsqbh0000gp/T/2381433021'...
done.
2026/02/25 23:19:27 switched to directory "/var/folders/vl/k9dw37lx0x5bbtzj98plsqbh0000gp/T/2381433021"
2026/02/25 23:19:27 running git with args ["checkout" "master" "--"]
Switched to a new branch 'master'
2026/02/25 23:19:27 switched to directory "/var/folders/vl/k9dw37lx0x5bbtzj98plsqbh0000gp/T/2381433021"
2026/02/25 23:19:27 running capslock with args ["-packages=./..." "-output=json" "-granularity=intermediate" "-capabilities=-UNANALYZED"]
2026/02/25 23:19:29 capslock returned "{\n\t\"capabilityInfo\": [\n\t\t{\n\t\t\t\"packageName\": \"bufio\",\n\t\t\t\"capabilityName\": \"FILES\",\n\t\t\t\"capabilit..."
2026/02/25 23:19:29 parsed CapabilityInfoList with 1032 entries
2026/02/25 23:19:29 returned to working directory "/Users/pwd"
2026/02/25 23:19:29 analyzing at revision "."
2026/02/25 23:19:29 running capslock with args ["-packages=./..." "-output=json" "-granularity=intermediate" "-capabilities=-UNANALYZED"]
2026/02/25 23:19:32 capslock returned "{\n\t\"capabilityInfo\": [\n\t\t{\n\t\t\t\"packageName\": \"bufio\",\n\t\t\t\"capabilityName\": \"FILES\",\n\t\t\t\"capabilit..."
2026/02/25 23:19:32 parsed CapabilityInfoList with 1033 entries
Comparing capabilities in "./..." between revisions "master" and "."
Added 1 new use of existing capability:
NETWORK: Access to the network
New packages in call paths to capability NETWORK:
Package internal.service.snip/model has capability NETWORK:
internal.service.snip/model.ParseLicenses
strings.splitSeq$1
iter.go:41:14 net/http.containsDotDot$1
I've gone and looked at line 41 of iter.go; it certainly does not appear to have any reference to http.containsDotDot in it (which is unexported anyway).
More curiously, if I run capslock directly against the fix'd code:
❯ capslock -packages internal.service.snip/model
Capslock is an experimental tool for static analysis of Go packages.
Share feedback and file bugs at https://github.com/google/capslock.
For additional debugging signals, use verbose mode with -output=verbose
To get machine-readable full analysis output, use -output=json
Analyzed packages:
internal.library.package v0.0.0-snip
Capslock found no capabilities in this package.
Capslock doesn't think that the package in question has any capabilities at all.
When I run capslock -granularity=intermediate -packages=./... -output=json on both commits and compare the output, the only change is indeed the new appearance of
{
"packageName": "model",
"capabilityName": "NETWORK",
"capability": "CAPABILITY_NETWORK",
"path": [
{
"name": "internal.service.snip/model.ParseLicenses",
"package": "internal.service.snip/model"
},
{
"name": "strings.splitSeq$1",
"package": "strings"
},
{
"name": "net/http.containsDotDot$1",
"site": {
"filename": "iter.go",
"line": "41",
"column": "14"
},
"package": "net/http"
}
],
"packageDir": "internal.service.snip/model"
}
So somehow, capslock is convinced that the strings package imports and uses a private function from net/http.
I've tried a narrow reproducer of a git repo that just has
func main() {
// doesn't actually matter what we do
for _, s := range strings.Split("a,b,c", ",") {
fmt.Println(s)
}
}
and
func main() {
// doesn't actually matter what we do
for s := range strings.SplitSeq("a,b,c", ",") {
fmt.Println(s)
}
}
as the two commits, but that doesn't seem to trigger it.
Do you have any further guidance on how I can debug this strange behavior?