Skip to content

Commit 17c7b7c

Browse files
committed
Panic when symlink loop encountered during project discovery
Even though the previous commit caused the project discovery code to gracefully avoid perpetual recursion when specific configurations of symlinks are present in the linting target path, it turned out that the project data phase that comes after is also not able to handle this correctly, and fixing that is more difficult since the incompatible code is in Arduino CLI. So for now the provisional fix is to panic during the project discovery phase, which will at least avoid the far worse behavior of a permanent hang.
1 parent f96e65b commit 17c7b7c

File tree

2 files changed

+5
-24
lines changed

2 files changed

+5
-24
lines changed

internal/project/project.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ func findProjectsUnderPath(targetPath *paths.Path, projectTypeFilter projecttype
134134
return foundProjects
135135
}
136136

137-
if recursive && symlinkDepth < 10 {
137+
if recursive {
138+
if symlinkDepth > 10 {
139+
panic(fmt.Sprintf("symlink depth exceeded maximum while finding projects under %s", targetPath))
140+
}
138141
// targetPath was not a project, so search the subfolders.
139142
directoryListing, _ := targetPath.ReadDir()
140143
directoryListing.FilterDirs()

internal/project/project_test.go

+1-23
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"os"
2121
"reflect"
2222
"testing"
23-
"time"
2423

2524
"github.com/arduino/arduino-lint/internal/configuration"
2625
"github.com/arduino/arduino-lint/internal/project/projecttype"
@@ -60,28 +59,7 @@ func TestSymlinkLoop(t *testing.T) {
6059

6160
configuration.Initialize(test.ConfigurationFlags(), []string{libraryPath.String()})
6261

63-
// The failure condition is FindProjects() never returning, testing for which requires setting up a timeout.
64-
done := make(chan bool)
65-
go func() {
66-
_, err = FindProjects()
67-
done <- true
68-
}()
69-
70-
assert.Eventually(
71-
t,
72-
func() bool {
73-
select {
74-
case <-done:
75-
return true
76-
default:
77-
return false
78-
}
79-
},
80-
20*time.Second,
81-
10*time.Millisecond,
82-
"Infinite symlink loop during project discovery",
83-
)
84-
require.Nil(t, err)
62+
assert.Panics(t, func() { FindProjects() }, "Infinite symlink loop encountered during project discovery")
8563
}
8664

8765
func TestFindProjects(t *testing.T) {

0 commit comments

Comments
 (0)