Say a build source only for the trunk's head, and hold what C, assembly and a new go.mod reach (hq ADR 0267, review)
A hand build of an older trunk commit said a closure lacking what was imported since, and the planner would have mapped the next merge onto it. C and assembly beside Go may include files below their directory, and a go.mod made above a package moves it out of its module: each is now held.
This commit is contained in:
@@ -185,6 +185,10 @@ func GoBuildSource(root, pkg string) ([]string, error) {
|
||||
}
|
||||
seen[dir] = true
|
||||
entries[goPackageDirEntry(dir)] = true
|
||||
// A go.mod made between the module's root and a package moves that package out of the module.
|
||||
for up := dir; up != modRoot && up != "." && up != "/" && !strings.HasPrefix(up, "../"); up = path.Dir(up) {
|
||||
file(up, "go.mod")
|
||||
}
|
||||
listing, err := os.ReadDir(filepath.Join(root, filepath.FromSlash(dir)))
|
||||
if err != nil {
|
||||
// A package that is not there fails the build that imports it; its directory is held, so
|
||||
@@ -193,6 +197,18 @@ func GoBuildSource(root, pkg string) ([]string, error) {
|
||||
}
|
||||
for _, f := range listing {
|
||||
name := f.Name()
|
||||
// **C and assembly beside Go** may include files from below the package's directory: the
|
||||
// directory is held whole, and an include reaching above it is refused.
|
||||
if !f.IsDir() && nativeSource(name) {
|
||||
entries[strings.TrimPrefix(dir+"/**", "./")] = true
|
||||
if dir == "." {
|
||||
entries["**"] = true
|
||||
}
|
||||
if err := includesStayWithin(filepath.Join(root, filepath.FromSlash(dir), name)); err != nil {
|
||||
return nil, fmt.Errorf("%s: %w", path.Join(dir, name), err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if f.IsDir() || !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
|
||||
continue
|
||||
}
|
||||
@@ -359,6 +375,31 @@ func goFileReads(file string) (imports, embeds []string, err error) {
|
||||
return imports, embeds, scanner.Err()
|
||||
}
|
||||
|
||||
// nativeSource is a file the Go command compiles or links beside Go: C, C++, Objective-C, Fortran,
|
||||
// assembly, their headers and a system object.
|
||||
func nativeSource(name string) bool {
|
||||
switch strings.ToLower(path.Ext(name)) {
|
||||
case ".c", ".h", ".cc", ".cpp", ".cxx", ".hh", ".hpp", ".hxx", ".m", ".s", ".sx", ".f", ".f90", ".for", ".syso":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// includesStayWithin refuses a native source whose #include names a path above its directory.
|
||||
func includesStayWithin(file string) error {
|
||||
body, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, line := range strings.Split(string(body), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "#") && strings.Contains(line, "include") && strings.Contains(line, "..") {
|
||||
return errors.New("it includes a path outside its directory: " + line)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// embedPatterns splits a //go:embed line's patterns: separated by spaces, each possibly quoted.
|
||||
func embedPatterns(s string) ([]string, error) {
|
||||
var out []string
|
||||
|
||||
Reference in New Issue
Block a user