Skip to content

Commit

Permalink
[breaking] Check cross-platform compatibility of sketch names (arduin…
Browse files Browse the repository at this point in the history
…o#2216)

* Exclude sketch names ending with a dot

* Fail with error if a reserved name is used as sketch name

* Update sketch name specifications in docs
  • Loading branch information
MatteoPologruto authored Jun 20, 2023
1 parent 223d3fa commit a71415f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
12 changes: 10 additions & 2 deletions commands/sketch/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ 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_-]|)$`)

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) {
Expand Down Expand Up @@ -80,8 +83,13 @@ 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))}
}
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
}
16 changes: 14 additions & 2 deletions commands/sketch/new_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func Test_SketchNameWrongPattern(t *testing.T) {
".hello",
"-hello",
"hello*",
"hello.",
"||||||||||||||",
",`hack[}attempt{];",
}
Expand All @@ -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))
}
}
Expand Down Expand Up @@ -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),
Expand All @@ -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))
}
}
7 changes: 7 additions & 0 deletions docs/UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion docs/sketch-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
[<sup>1</sup>](#leading-number-note), or underscore (`_`) [<sup>2</sup>](#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).

<a id="leading-number-note"></a> <sup>1</sup> Supported from Arduino IDE 1.8.4. <br />
<a id="leading-underscore-note"></a> <sup>2</sup> Supported in all versions except Arduino IDE 2.0.4/Arduino CLI
Expand Down

0 comments on commit a71415f

Please sign in to comment.