@@ -18,6 +18,7 @@ package project
1818
1919import (
2020 "fmt"
21+ "os"
2122
2223 "github.com/arduino/arduino-lint/internal/configuration"
2324 "github.com/arduino/arduino-lint/internal/project/library"
@@ -87,7 +88,7 @@ func findProjects(targetPath *paths.Path) ([]Type, error) {
8788 } else {
8889 if configuration .SuperprojectTypeFilter () == projecttype .All || configuration .Recursive () {
8990 // 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 )
9192 } else {
9293 // Project was explicitly defined by user.
9394 foundParentProjects = append (foundParentProjects ,
@@ -115,7 +116,7 @@ func findProjects(targetPath *paths.Path) ([]Type, error) {
115116}
116117
117118// 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 {
119120 var foundProjects []Type
120121
121122 isProject , foundProjectType := isProject (targetPath , projectTypeFilter )
@@ -134,11 +135,26 @@ func findProjectsUnderPath(targetPath *paths.Path, projectTypeFilter projecttype
134135 }
135136
136137 if recursive {
138+ if symlinkDepth > 10 {
139+ panic (fmt .Sprintf ("symlink depth exceeded maximum while finding projects under %s" , targetPath ))
140+ }
137141 // targetPath was not a project, so search the subfolders.
138142 directoryListing , _ := targetPath .ReadDir ()
139143 directoryListing .FilterDirs ()
140144 for _ , potentialProjectDirectory := range directoryListing {
141- foundProjects = append (foundProjects , findProjectsUnderPath (potentialProjectDirectory , projectTypeFilter , recursive )... )
145+ // It is possible for a combination of symlinks to parent paths to cause project discovery to get stuck in
146+ // an endless loop of recursion. This is avoided by keeping count of the depth of symlinks and discontinuing
147+ // recursion when it exceeds reason.
148+ pathStat , err := os .Lstat (potentialProjectDirectory .String ())
149+ if err != nil {
150+ panic (err )
151+ }
152+ depthDelta := 0
153+ if pathStat .Mode ()& os .ModeSymlink != 0 {
154+ depthDelta = 1
155+ }
156+
157+ foundProjects = append (foundProjects , findProjectsUnderPath (potentialProjectDirectory , projectTypeFilter , recursive , symlinkDepth + depthDelta )... )
142158 }
143159 }
144160
@@ -184,7 +200,7 @@ func findSubprojects(superproject Type, apexSuperprojectType projecttype.Type) [
184200 directoryListing .FilterDirs ()
185201
186202 for _ , subprojectPath := range directoryListing {
187- immediateSubprojects = append (immediateSubprojects , findProjectsUnderPath (subprojectPath , subProjectType , searchPathsRecursively )... )
203+ immediateSubprojects = append (immediateSubprojects , findProjectsUnderPath (subprojectPath , subProjectType , searchPathsRecursively , 0 )... )
188204 }
189205 }
190206 }
0 commit comments