@marcel91200 / caddy Mirror · read-only / commits / a75817f5
Fork 0

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) {