@@ -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 )
@@ -133,12 +134,24 @@ func findProjectsUnderPath(targetPath *paths.Path, projectTypeFilter projecttype
133134 return foundProjects
134135 }
135136
136- if recursive {
137+ if recursive && symlinkDepth < 10 {
137138 // targetPath was not a project, so search the subfolders.
138139 directoryListing , _ := targetPath .ReadDir ()
139140 directoryListing .FilterDirs ()
140141 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+ depthDelta := 0
150+ if pathStat .Mode ()& os .ModeSymlink != 0 {
151+ depthDelta = 1
152+ }
153+
154+ foundProjects = append (foundProjects , findProjectsUnderPath (potentialProjectDirectory , projectTypeFilter , recursive , symlinkDepth + depthDelta )... )
142155 }
143156 }
144157
@@ -184,7 +197,7 @@ func findSubprojects(superproject Type, apexSuperprojectType projecttype.Type) [
184197 directoryListing .FilterDirs ()
185198
186199 for _ , subprojectPath := range directoryListing {
187- immediateSubprojects = append (immediateSubprojects , findProjectsUnderPath (subprojectPath , subProjectType , searchPathsRecursively )... )
200+ immediateSubprojects = append (immediateSubprojects , findProjectsUnderPath (subprojectPath , subProjectType , searchPathsRecursively , 0 )... )
188201 }
189202 }
190203 }
0 commit comments