in zip/zip.go [200:322]
func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []int64) {
errPaths := make(map[string]struct{})
addError := func(path string, omitted bool, err error) {
if _, ok := errPaths[path]; ok {
return
}
errPaths[path] = struct{}{}
fe := FileError{Path: path, Err: err}
if omitted {
cf.Omitted = append(cf.Omitted, fe)
} else {
cf.Invalid = append(cf.Invalid, fe)
}
}
// Find directories containing go.mod files (other than the root).
// Files in these directories will be omitted.
// These directories will not be included in the output zip.
haveGoMod := make(map[string]bool)
for _, f := range files {
p := f.Path()
dir, base := path.Split(p)
if strings.EqualFold(base, "go.mod") {
info, err := f.Lstat()
if err != nil {
addError(p, false, err)
continue
}
if info.Mode().IsRegular() {
haveGoMod[dir] = true
}
}
}
inSubmodule := func(p string) bool {
for {
dir, _ := path.Split(p)
if dir == "" {
return false
}
if haveGoMod[dir] {
return true
}
p = dir[:len(dir)-1]
}
}
collisions := make(collisionChecker)
maxSize := int64(MaxZipFile)
for _, f := range files {
p := f.Path()
if p != path.Clean(p) {
addError(p, false, errPathNotClean)
continue
}
if path.IsAbs(p) {
addError(p, false, errPathNotRelative)
continue
}
if isVendoredPackage(p) {
// Skip files in vendored packages.
addError(p, true, errVendored)
continue
}
if inSubmodule(p) {
// Skip submodule files.
addError(p, true, errSubmoduleFile)
continue
}
if p == ".hg_archival.txt" {
// Inserted by hg archive.
// The go command drops this regardless of the VCS being used.
addError(p, true, errHgArchivalTxt)
continue
}
if err := module.CheckFilePath(p); err != nil {
addError(p, false, err)
continue
}
if strings.ToLower(p) == "go.mod" && p != "go.mod" {
addError(p, false, errGoModCase)
continue
}
info, err := f.Lstat()
if err != nil {
addError(p, false, err)
continue
}
if err := collisions.check(p, info.IsDir()); err != nil {
addError(p, false, err)
continue
}
if info.Mode()&os.ModeType == os.ModeSymlink {
// Skip symbolic links (golang.org/issue/27093).
addError(p, true, errSymlink)
continue
}
if !info.Mode().IsRegular() {
addError(p, true, errNotRegular)
continue
}
size := info.Size()
if size >= 0 && size <= maxSize {
maxSize -= size
} else if cf.SizeError == nil {
cf.SizeError = fmt.Errorf("module source tree too large (max size is %d bytes)", MaxZipFile)
}
if p == "go.mod" && size > MaxGoMod {
addError(p, false, errGoModSize)
continue
}
if p == "LICENSE" && size > MaxLICENSE {
addError(p, false, errLICENSESize)
continue
}
cf.Valid = append(cf.Valid, p)
validFiles = append(validFiles, f)
validSizes = append(validSizes, info.Size())
}
return cf, validFiles, validSizes
}