From 478a3a4e4d8b10adc541cc6fbf03e614d1cb212e Mon Sep 17 00:00:00 2001 From: MatteoPologruto Date: Wed, 14 Jun 2023 12:52:17 +0200 Subject: [PATCH 1/3] Exclude sketch names ending with a dot --- commands/sketch/new.go | 4 ++-- commands/sketch/new_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/commands/sketch/new.go b/commands/sketch/new.go index ff2828b4e6f..df539ec2a20 100644 --- a/commands/sketch/new.go +++ b/commands/sketch/new.go @@ -37,7 +37,7 @@ void loop() { // sketchNameMaxLength could be part of the regex, but it's intentionally left out for clearer error reporting var sketchNameMaxLength = 63 -var sketchNameValidationRegex = regexp.MustCompile(`^[0-9a-zA-Z_][0-9a-zA-Z_\.-]*$`) +var sketchNameValidationRegex = regexp.MustCompile(`^[0-9a-zA-Z_](?:[0-9a-zA-Z_\.-]*[0-9a-zA-Z_-]|)$`) // NewSketch creates a new sketch via gRPC func NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { @@ -80,7 +80,7 @@ func validateSketchName(name string) error { sketchNameMaxLength))} } if !sketchNameValidationRegex.MatchString(name) { - return &arduino.CantCreateSketchError{Cause: errors.New(tr(`invalid sketch name "%[1]s": the first character must be alphanumeric or "_", the following ones can also contain "-" and ".".`, + return &arduino.CantCreateSketchError{Cause: errors.New(tr(`invalid sketch name "%[1]s": the first character must be alphanumeric or "_", the following ones can also contain "-" and ".". The last one cannot be ".".`, name))} } return nil diff --git a/commands/sketch/new_test.go b/commands/sketch/new_test.go index a0812448c6f..78f19dbff09 100644 --- a/commands/sketch/new_test.go +++ b/commands/sketch/new_test.go @@ -30,6 +30,7 @@ func Test_SketchNameWrongPattern(t *testing.T) { ".hello", "-hello", "hello*", + "hello.", "||||||||||||||", ",`hack[}attempt{];", } @@ -39,7 +40,7 @@ func Test_SketchNameWrongPattern(t *testing.T) { SketchDir: t.TempDir(), }) - require.EqualError(t, err, fmt.Sprintf(`Can't create sketch: invalid sketch name "%s": the first character must be alphanumeric or "_", the following ones can also contain "-" and ".".`, + require.EqualError(t, err, fmt.Sprintf(`Can't create sketch: invalid sketch name "%s": the first character must be alphanumeric or "_", the following ones can also contain "-" and ".". The last one cannot be ".".`, name)) } } @@ -78,7 +79,6 @@ func Test_SketchNameOk(t *testing.T) { "h", "h.ello", "h..ello-world", - "h..ello-world.", "hello_world__", "_hello_world", string(lengthLimitName), From 7959b91be9df8f7c2dbc5c840f4fc87288192a3c Mon Sep 17 00:00:00 2001 From: MatteoPologruto Date: Wed, 14 Jun 2023 15:08:45 +0200 Subject: [PATCH 2/3] Fail with error if a reserved name is used as sketch name --- commands/sketch/new.go | 8 ++++++++ commands/sketch/new_test.go | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/commands/sketch/new.go b/commands/sketch/new.go index df539ec2a20..b4fe3ab0e82 100644 --- a/commands/sketch/new.go +++ b/commands/sketch/new.go @@ -39,6 +39,9 @@ void loop() { var sketchNameMaxLength = 63 var sketchNameValidationRegex = regexp.MustCompile(`^[0-9a-zA-Z_](?:[0-9a-zA-Z_\.-]*[0-9a-zA-Z_-]|)$`) +var invalidNames = []string{"CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", + "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} + // NewSketch creates a new sketch via gRPC func NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { var sketchesDir string @@ -83,5 +86,10 @@ func validateSketchName(name string) error { return &arduino.CantCreateSketchError{Cause: errors.New(tr(`invalid sketch name "%[1]s": the first character must be alphanumeric or "_", the following ones can also contain "-" and ".". The last one cannot be ".".`, name))} } + for _, invalid := range invalidNames { + if name == invalid { + return &arduino.CantCreateSketchError{Cause: errors.New(tr(`sketch name cannot be the reserved name "%[1]s"`, invalid))} + } + } return nil } diff --git a/commands/sketch/new_test.go b/commands/sketch/new_test.go index 78f19dbff09..00ae7856732 100644 --- a/commands/sketch/new_test.go +++ b/commands/sketch/new_test.go @@ -91,3 +91,15 @@ func Test_SketchNameOk(t *testing.T) { require.Nil(t, err) } } + +func Test_SketchNameReserved(t *testing.T) { + invalidNames := []string{"CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", + "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} + for _, name := range invalidNames { + _, err := NewSketch(context.Background(), &commands.NewSketchRequest{ + SketchName: name, + SketchDir: t.TempDir(), + }) + require.EqualError(t, err, fmt.Sprintf(`Can't create sketch: sketch name cannot be the reserved name "%s"`, name)) + } +} From a2aab0540237017cae16287777fff663f69b4b63 Mon Sep 17 00:00:00 2001 From: MatteoPologruto Date: Wed, 14 Jun 2023 17:27:36 +0200 Subject: [PATCH 3/3] Update sketch name specifications in docs --- docs/UPGRADING.md | 7 +++++++ docs/sketch-specification.md | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index 39d0ef5b992..63071bb2f50 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -4,6 +4,13 @@ Here you can find a list of migration guides to handle breaking changes between ## 0.34.0 +### Updated sketch name specifications + +[Sketch name specifications](https://arduino.github.io/arduino-cli/dev/sketch-specification) have been updated to +achieve cross-platform compatibility. + +Existing sketch names violating the new constraint need to be updated. + ### golang API: `LoadSketch` function has been moved The function `github.com/arduino/arduino-cli/commands.LoadSketch` has been moved to package diff --git a/docs/sketch-specification.md b/docs/sketch-specification.md index f7488c794ca..316787476c6 100644 --- a/docs/sketch-specification.md +++ b/docs/sketch-specification.md @@ -7,7 +7,9 @@ The programs that run on Arduino boards are called "sketches". This term was inh The sketch root folder name and code file names must start with a basic letter (`A`-`Z` or `a`-`z`), number (`0`-`9`) [1](#leading-number-note), or underscore (`_`) [2](#leading-underscore-note) followed by basic -letters, numbers, underscores, dots (`.`) and dashes (`-`). The maximum length is 63 characters. +letters, numbers, underscores, dots (`.`) and dashes (`-`). The maximum length is 63 characters. The sketch name cannot +end with a dot (`.`) and cannot be a +[reserved name](https://learn.microsoft.com/windows/win32/fileio/naming-a-file#naming-conventions). 1 Supported from Arduino IDE 1.8.4.
2 Supported in all versions except Arduino IDE 2.0.4/Arduino CLI