Avoid hang during discovery in projects with symlink loops · arduino/arduino-lint@ef717d2 (original) (raw)
`@@ -18,6 +18,7 @@ package project
`
18
18
``
19
19
`import (
`
20
20
`"fmt"
`
``
21
`+
"os"
`
21
22
``
22
23
`"github.com/arduino/arduino-lint/internal/configuration"
`
23
24
`"github.com/arduino/arduino-lint/internal/project/library"
`
`@@ -87,7 +88,7 @@ func findProjects(targetPath *paths.Path) ([]Type, error) {
`
87
88
` } else {
`
88
89
`if configuration.SuperprojectTypeFilter() == projecttype.All || configuration.Recursive() {
`
89
90
`// Project discovery and/or type detection is required.
`
90
``
`-
foundParentProjects = findProjectsUnderPath(targetPath, configuration.SuperprojectTypeFilter(), configuration.Recursive())
`
``
91
`+
foundParentProjects = findProjectsUnderPath(targetPath, configuration.SuperprojectTypeFilter(), configuration.Recursive(), 0)
`
91
92
` } else {
`
92
93
`// Project was explicitly defined by user.
`
93
94
`foundParentProjects = append(foundParentProjects,
`
`@@ -115,7 +116,7 @@ func findProjects(targetPath *paths.Path) ([]Type, error) {
`
115
116
`}
`
116
117
``
117
118
`// findProjectsUnderPath finds projects of the given type under the given path. It returns a slice containing the definitions of all found projects.
`
118
``
`-
func findProjectsUnderPath(targetPath *paths.Path, projectTypeFilter projecttype.Type, recursive bool) []Type {
`
``
119
`+
func findProjectsUnderPath(targetPath *paths.Path, projectTypeFilter projecttype.Type, recursive bool, symlinkDepth int) []Type {
`
119
120
`var foundProjects []Type
`
120
121
``
121
122
`isProject, foundProjectType := isProject(targetPath, projectTypeFilter)
`
`@@ -133,12 +134,23 @@ func findProjectsUnderPath(targetPath *paths.Path, projectTypeFilter projecttype
`
133
134
`return foundProjects
`
134
135
` }
`
135
136
``
136
``
`-
if recursive {
`
``
137
`+
if recursive && symlinkDepth < 10 {
`
137
138
`// targetPath was not a project, so search the subfolders.
`
138
139
`directoryListing, _ := targetPath.ReadDir()
`
139
140
`directoryListing.FilterDirs()
`
140
141
`for _, potentialProjectDirectory := range directoryListing {
`
141
``
`-
foundProjects = append(foundProjects, findProjectsUnderPath(potentialProjectDirectory, projectTypeFilter, recursive)...)
`
``
142
`+
// It is possible for a combination of symlinks to parent paths to cause project discovery to get stuck in
`
``
143
`+
// an endless loop of recursion. This is avoided by keeping count of the depth of symlinks and discontinuing
`
``
144
`+
// recursion when it exceeds reason.
`
``
145
`+
pathStat, err := os.Lstat(potentialProjectDirectory.String())
`
``
146
`+
if err != nil {
`
``
147
`+
panic(err)
`
``
148
`+
}
`
``
149
`+
if pathStat.Mode()&os.ModeSymlink != 0 {
`
``
150
`+
symlinkDepth++
`
``
151
`+
}
`
``
152
+
``
153
`+
foundProjects = append(foundProjects, findProjectsUnderPath(potentialProjectDirectory, projectTypeFilter, recursive, symlinkDepth)...)
`
142
154
` }
`
143
155
` }
`
144
156
``
`@@ -184,7 +196,7 @@ func findSubprojects(superproject Type, apexSuperprojectType projecttype.Type) [
`
184
196
`directoryListing.FilterDirs()
`
185
197
``
186
198
`for _, subprojectPath := range directoryListing {
`
187
``
`-
immediateSubprojects = append(immediateSubprojects, findProjectsUnderPath(subprojectPath, subProjectType, searchPathsRecursively)...)
`
``
199
`+
immediateSubprojects = append(immediateSubprojects, findProjectsUnderPath(subprojectPath, subProjectType, searchPathsRecursively, 0)...)
`
188
200
` }
`
189
201
` }
`
190
202
` }
`