From 7d93ecfc49d51ab640dbf71d47212ac83c008864 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Fri, 26 Feb 2021 15:02:15 +0100 Subject: [PATCH 1/2] Exit with error when a sketch file is unreadable When any sketch file that would normally be compiled is unreadable, SketchLoad would previously just silently skip it, leading to potentially unexpected results. It is probably better to just error out and let the user sort out the problem instead. Additionally, this prepares for improving the handling of broken symlinks in the next commit. --- arduino/builder/sketch.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arduino/builder/sketch.go b/arduino/builder/sketch.go index a1a761f795d..e9db65215cd 100644 --- a/arduino/builder/sketch.go +++ b/arduino/builder/sketch.go @@ -197,7 +197,8 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) { // check if file is readable f, err := os.Open(path) if err != nil { - return nil + feedback.Errorf("Failed to open sketch file: %v", err) + os.Exit(errorcodes.ErrGeneric) } f.Close() From 021b4496aba2ad0509fa44c1e3c47ef4f276d327 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Fri, 26 Feb 2021 15:06:44 +0100 Subject: [PATCH 2/2] Ignore invalid symlinks for files that would be skipped anyway Previously, SketchLoad would error out on *any* error during file enumeration, including broken symlinks (where `os.Stat` returns `ErrNotExist`), even when that symlink would not be loaded (i.e. no valid extension) anyway. Now, `ErrNotExist` errors are ignored and a broken symlink is processed as normal. This changes the code to assume broken symlinks are not directories and to use the `path` value instead of the `info.Name()`, since the latter is not available when the `Stat()` call failed. If, based on the name of the broken symlink, the file would be skipped, processing continues as normal. If the file would be loaded, then the existing `os.Open()` call fails (and since the previous commit, returns an error like before for all broken symlinks). --- arduino/builder/sketch.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arduino/builder/sketch.go b/arduino/builder/sketch.go index e9db65215cd..81fed1c5547 100644 --- a/arduino/builder/sketch.go +++ b/arduino/builder/sketch.go @@ -154,12 +154,15 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) { var files []string rootVisited := false err = simpleLocalWalk(sketchFolder, maxFileSystemDepth, func(path string, info os.FileInfo, err error) error { - if err != nil { + // Ignore ErrNotExist (broken symlinks), which will be + // reported by os.Open below if the file would not be + // skipped based on the name + if err != nil && !errors.Is(err, os.ErrNotExist) { feedback.Errorf("Error during sketch processing: %v", err) os.Exit(errorcodes.ErrGeneric) } - if info.IsDir() { + if info != nil && info.IsDir() { // Filters in this if-block are NOT applied to the sketch folder itself. // Since the sketch folder is the first one processed by simpleLocalWalk, // we can set the `rootVisited` guard to exclude it. @@ -182,7 +185,7 @@ func SketchLoad(sketchPath, buildPath string) (*sketch.Sketch, error) { } // ignore hidden files - if strings.HasPrefix(info.Name(), ".") { + if strings.HasPrefix(filepath.Base(path), ".") { return nil }