Skip to content

Commit cf1c3ab

Browse files
d-a-vRoberto Sora
authored and
Roberto Sora
committed
Use a local Walk function (#421)
* Use a local Walk function Because arduino-cli segfaults when sketchDir is a symbolic link, a simple walk function is introduced with a twofold effect: - fix the segfault - allow to use symlinks ref: https://www.google.com/search?q=golang+Walk+does+not+follow+symbolic+links * tabs * style * comment * retrigger CI * retrigger CI * style * check sketch for being a file * check sketch is not a directory * additions: - act on error in walk function (OS can detect symbolic links loops (lnk -> lnk)) - add a deepness detector for non trivial loops (dir/lnk -> ../..) * fixes from "task check" * updates per review * style * Update arduino/builder/sketch.go Co-Authored-By: Roberto Sora <[email protected]> * fixes
1 parent e51df0d commit cf1c3ab

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

Diff for: arduino/builder/sketch.go

+54-1
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ import (
2525

2626
"github.com/arduino/arduino-cli/arduino/globals"
2727
"github.com/arduino/arduino-cli/arduino/sketch"
28+
"github.com/arduino/arduino-cli/cli/errorcodes"
29+
"github.com/arduino/arduino-cli/cli/feedback"
2830

2931
"github.com/pkg/errors"
3032
)
3133

34+
// As currently implemented on Linux,
35+
// the maximum number of symbolic links that will be followed while resolving a pathname is 40
36+
const maxFileSystemDepth = 40
37+
3238
var includesArduinoH = regexp.MustCompile(`(?m)^\s*#\s*include\s*[<\"]Arduino\.h[>\"]`)
3339

3440
// QuoteCppString returns the given string as a quoted string for use with the C
@@ -58,6 +64,39 @@ func SketchSaveItemCpp(item *sketch.Item, destPath string) error {
5864
return nil
5965
}
6066

67+
// simpleLocalWalk locally replaces filepath.Walk and/but goes through symlinks
68+
func simpleLocalWalk(root string, maxDepth int, walkFn func(path string, info os.FileInfo, err error) error) error {
69+
70+
info, err := os.Stat(root)
71+
72+
if err != nil {
73+
return walkFn(root, nil, err)
74+
}
75+
76+
err = walkFn(root, info, err)
77+
if err == filepath.SkipDir {
78+
return nil
79+
}
80+
81+
if info.IsDir() {
82+
if maxDepth <= 0 {
83+
return walkFn(root, info, errors.New("Filesystem bottom is too deep (directory recursion or filesystem really deep): "+root))
84+
}
85+
maxDepth--
86+
files, err := ioutil.ReadDir(root)
87+
if err == nil {
88+
for _, file := range files {
89+
err = simpleLocalWalk(root+string(os.PathSeparator)+file.Name(), maxDepth, walkFn)
90+
if err == filepath.SkipDir {
91+
return nil
92+
}
93+
}
94+
}
95+
}
96+
97+
return nil
98+
}
99+
61100
// SketchLoad collects all the files composing a sketch.
62101
// The parameter `sketchPath` holds a path pointing to a single sketch file or a sketch folder,
63102
// the path must be absolute.
@@ -79,14 +118,28 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) {
79118
return nil, errors.Wrap(err, "unable to find the main sketch file")
80119
}
81120
f.Close()
121+
// ensure it is not a directory
122+
info, err := os.Stat(mainSketchFile)
123+
if err != nil {
124+
return nil, errors.Wrap(err, "unable to check the main sketch file")
125+
}
126+
if info.IsDir() {
127+
return nil, errors.Wrap(errors.New(mainSketchFile), "sketch must not be a directory")
128+
}
82129
} else {
83130
sketchFolder = filepath.Dir(sketchPath)
84131
mainSketchFile = sketchPath
85132
}
86133

87134
// collect all the sketch files
88135
var files []string
89-
err = filepath.Walk(sketchFolder, func(path string, info os.FileInfo, err error) error {
136+
err = simpleLocalWalk(sketchFolder, maxFileSystemDepth, func(path string, info os.FileInfo, err error) error {
137+
138+
if err != nil {
139+
feedback.Errorf("Error during sketch processing: %v", err)
140+
os.Exit(errorcodes.ErrGeneric)
141+
}
142+
90143
// ignore hidden files and skip hidden directories
91144
if strings.HasPrefix(info.Name(), ".") {
92145
if info.IsDir() {

0 commit comments

Comments
 (0)