@@ -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,23 @@ 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+ if pathStat .Mode ()& os .ModeSymlink != 0 {
150+ symlinkDepth ++
151+ }
152+
153+ foundProjects = append (foundProjects , findProjectsUnderPath (potentialProjectDirectory , projectTypeFilter , recursive , symlinkDepth )... )
142154 }
143155 }
144156
@@ -184,7 +196,7 @@ func findSubprojects(superproject Type, apexSuperprojectType projecttype.Type) [
184196 directoryListing .FilterDirs ()
185197
186198 for _ , subprojectPath := range directoryListing {
187- immediateSubprojects = append (immediateSubprojects , findProjectsUnderPath (subprojectPath , subProjectType , searchPathsRecursively )... )
199+ immediateSubprojects = append (immediateSubprojects , findProjectsUnderPath (subprojectPath , subProjectType , searchPathsRecursively , 0 )... )
188200 }
189201 }
190202 }
0 commit comments