[bug-0zkpwxbsdxcn] Own canonical offline private Go module tooling #2
@@ -99,13 +99,9 @@ func generate() error {
|
|||||||
return errors.New("private module must have exact unreplaced version")
|
return errors.New("private module must have exact unreplaced version")
|
||||||
}
|
}
|
||||||
mod := module{Path: src.Path, Version: src.Version, Files: []artifact{}}
|
mod := module{Path: src.Path, Version: src.Version, Files: []artifact{}}
|
||||||
rel, err := filepath.Rel(cacheRoot, src.GoMod)
|
stem, err := cacheStem(cacheRoot, src.Path, src.Version, src.GoMod)
|
||||||
if err != nil || !safePath(rel) || !strings.HasSuffix(rel, ".mod") || !strings.HasSuffix(filepath.Dir(rel), "/@v") {
|
if err != nil {
|
||||||
return errors.New("unexpected native module cache layout")
|
return err
|
||||||
}
|
|
||||||
stem, err := moduleStem(src.Path, src.Version)
|
|
||||||
if err != nil || filepath.ToSlash(rel) != stem+".mod" {
|
|
||||||
return errors.New("native artifact path differs from module identity")
|
|
||||||
}
|
}
|
||||||
for _, ext := range []string{".info", ".mod", ".zip"} {
|
for _, ext := range []string{".info", ".mod", ".zip"} {
|
||||||
name := stem + ext
|
name := stem + ext
|
||||||
@@ -185,6 +181,22 @@ func moduleStem(path, version string) (string, error) {
|
|||||||
return escape(path) + "/@v/" + escape(version), nil
|
return escape(path) + "/@v/" + escape(version), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cacheStem(cacheRoot, path, version, goMod string) (string, error) {
|
||||||
|
stem, err := moduleStem(path, version)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// Lazy module graphs omit GoMod for selected but unexpanded modules.
|
||||||
|
// Their canonical cache path is still determined by exact identity.
|
||||||
|
if goMod != "" {
|
||||||
|
rel, err := filepath.Rel(cacheRoot, goMod)
|
||||||
|
if err != nil || filepath.ToSlash(rel) != stem+".mod" {
|
||||||
|
return "", errors.New("native artifact path differs from module identity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stem, nil
|
||||||
|
}
|
||||||
|
|
||||||
func safePath(p string) bool {
|
func safePath(p string) bool {
|
||||||
return p != "" && filepath.Clean(p) == p && !filepath.IsAbs(p) && p != ".." && !strings.HasPrefix(p, "../") && !strings.ContainsAny(p, "\\\x00")
|
return p != "" && filepath.Clean(p) == p && !filepath.IsAbs(p) && p != ".." && !strings.HasPrefix(p, "../") && !strings.ContainsAny(p, "\\\x00")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,3 +164,17 @@ func TestCanonicalModuleArtifactPathBinding(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLazyGraphModuleCacheIdentity(t *testing.T) {
|
||||||
|
cache := t.TempDir()
|
||||||
|
path, version := "code.fritzlab.net/fixture/module", "v0.1.0"
|
||||||
|
stem, err := cacheStem(cache, path, version, "")
|
||||||
|
if err != nil || stem != path+"/@v/"+version {
|
||||||
|
t.Fatalf("selected lazy module rejected: %q %v", stem, err)
|
||||||
|
}
|
||||||
|
for _, metadata := range []string{filepath.Join(cache, "foreign/@v/v0.1.0.mod"), filepath.Join(cache, "../escaped.mod"), filepath.Join(cache, path, "@v/v0.2.0.mod")} {
|
||||||
|
if _, err := cacheStem(cache, path, version, metadata); err == nil {
|
||||||
|
t.Fatal("contradictory cache identity accepted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user