fix: require module path boundaries when matching packages (#7957)

Signed-off-by: wangjingshuiku <wangjingshuiku@163.com>
pull/8017/head
wangjingshuiku 2026-09-13 11:08:09 +09:00 committed by GitHub
parent 425a3381fd
commit a75817f550
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 2 deletions

View File

@ -253,7 +253,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
// longest matching prefix in case there are nested modules
var matched *debug.Module
for _, dep := range bi.Deps {
if strings.HasPrefix(modPkgPath, dep.Path) {
if moduleContainsPackage(dep.Path, modPkgPath) {
if matched == nil || len(dep.Path) > len(matched.Path) {
matched = dep
}
@ -262,7 +262,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
caddyModGoMod := moduleInfo{caddyModuleID: modID, goModule: matched}
if strings.HasPrefix(modPkgPath, caddy.ImportPath) {
if moduleContainsPackage(caddy.ImportPath, modPkgPath) {
standard = append(standard, caddyModGoMod)
} else {
nonstandard = append(nonstandard, caddyModGoMod)
@ -271,6 +271,10 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
return standard, nonstandard, unknown, err
}
func moduleContainsPackage(modulePath, packagePath string) bool {
return packagePath == modulePath || strings.HasPrefix(packagePath, modulePath+"/")
}
func listModules(path string) error {
cmd := exec.Command(path, "list-modules", "--versions", "--skip-standard")
cmd.Stdout = os.Stdout

View File

@ -39,6 +39,28 @@ func TestDownloadBuildClosesErrorResponseBody(t *testing.T) {
}
}
func TestModuleContainsPackage(t *testing.T) {
tests := []struct {
name string
modulePath string
packagePath string
want bool
}{
{name: "module root", modulePath: "example.com/mod", packagePath: "example.com/mod", want: true},
{name: "module package", modulePath: "example.com/mod", packagePath: "example.com/mod/pkg", want: true},
{name: "shared prefix", modulePath: "example.com/mod", packagePath: "example.com/module", want: false},
{name: "caddy module shared prefix", modulePath: "github.com/caddyserver/caddy/v2", packagePath: "github.com/caddyserver/caddy/v20", want: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := moduleContainsPackage(tt.modulePath, tt.packagePath); got != tt.want {
t.Fatalf("moduleContainsPackage(%q, %q) = %v, want %v", tt.modulePath, tt.packagePath, got, tt.want)
}
})
}
}
type roundTripperFunc func(*http.Request) (*http.Response, error)
func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {