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

` }

`