google / google/capslock

Strange capacity misreporting by capslock and capslock-git-diff

Open
#295 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
1.2k
Forks
52
Avg merge
2d 16h
Merged PRs (30d)
4

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](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#hdr-Analyzer_stringsseq) 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](https://cs.opensource.google/go/go/+/refs/tags/go1.26.0:src/strings/iter.go;l=41); it certainly does not appear to have any reference to [http.containsDotDot](https://cs.opensource.google/go/go/+/refs/tags/go1.26.0:src/net/http/fs.go;l=861) 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?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.