Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 04:45 UTC
fix: require module path boundaries when matching packages (#7957)
Signed-off-by: wangjingshuiku <wangjingshuiku@163.com>
wangjingshuiku committed
Sep 13, 2026 at 11:08 UTC
a75817f5500c5210a3892a21e4e712477b2fdadc
2 files changed
+28
-2
cmd/packagesfuncs.go
+6
-2
@@ -253,7 +253,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
253
// longest matching prefix in case there are nested modules
254
var matched *debug.Module
255
for _, dep := range bi.Deps {
256
- if strings.HasPrefix(modPkgPath, dep.Path) {
256
+ if moduleContainsPackage(dep.Path, modPkgPath) {
257
if matched == nil || len(dep.Path) > len(matched.Path) {
258
matched = dep
259
}
@@ -262,7 +262,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
262
263
caddyModGoMod := moduleInfo{caddyModuleID: modID, goModule: matched}
264
265
- if strings.HasPrefix(modPkgPath, caddy.ImportPath) {
265
+ if moduleContainsPackage(caddy.ImportPath, modPkgPath) {
266
standard = append(standard, caddyModGoMod)
267
} else {
268
nonstandard = append(nonstandard, caddyModGoMod)
@@ -271,6 +271,10 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
271
return standard, nonstandard, unknown, err
272
}
273
274
+func moduleContainsPackage(modulePath, packagePath string) bool {
275
+ return packagePath == modulePath || strings.HasPrefix(packagePath, modulePath+"/")
276
+}
277
+
278
func listModules(path string) error {
279
cmd := exec.Command(path, "list-modules", "--versions", "--skip-standard")
280
cmd.Stdout = os.Stdout
cmd/packagesfuncs_test.go
+22
@@ -39,6 +39,28 @@ func TestDownloadBuildClosesErrorResponseBody(t *testing.T) {
39
}
40
}
41
42
+func TestModuleContainsPackage(t *testing.T) {
43
+ tests := []struct {
44
+ name string
45
+ modulePath string
46
+ packagePath string
47
+ want bool
48
+ }{
49
+ {name: "module root", modulePath: "example.com/mod", packagePath: "example.com/mod", want: true},
50
+ {name: "module package", modulePath: "example.com/mod", packagePath: "example.com/mod/pkg", want: true},
51
+ {name: "shared prefix", modulePath: "example.com/mod", packagePath: "example.com/module", want: false},
52
+ {name: "caddy module shared prefix", modulePath: "github.com/caddyserver/caddy/v2", packagePath: "github.com/caddyserver/caddy/v20", want: false},
53
+ }
54
+
55
+ for _, tt := range tests {
56
+ t.Run(tt.name, func(t *testing.T) {
57
+ if got := moduleContainsPackage(tt.modulePath, tt.packagePath); got != tt.want {
58
+ t.Fatalf("moduleContainsPackage(%q, %q) = %v, want %v", tt.modulePath, tt.packagePath, got, tt.want)
59
+ }
60
+ })
61
+ }
62
+}
63
+
64
type roundTripperFunc func(*http.Request) (*http.Response, error)
65
66
func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {