Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Validate and format bundle names to exclude special characters #914

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/pkg/bundle/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ func (b *Bundle) Create() error {
return err
}

// validate bundle name to avoid bad characters
name, err := utils.FormatBundleName(b.bundle.Metadata.Name)
if err != nil {
return err
}
b.bundle.Metadata.Name = name

// confirm creation
if ok := b.confirmBundleCreation(); !ok {
return fmt.Errorf("bundle creation cancelled")
Expand Down
13 changes: 13 additions & 0 deletions src/pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package utils
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -223,3 +224,15 @@ func JSONValue(value any) (string, error) {
}
return string(bytes), nil
}

// formatBundleName first validates the bundle name does not have bad characters
// and then returns a lowercased version, with spaces (" ") replaced with "-".
func FormatBundleName(src string) (string, error) {
if regexp.MustCompile(`[^a-zA-Z0-9 -]+`).MatchString(src) {
return "", errors.New("bundle names should only include letters, numbers, and hypens")
}
src = strings.TrimSpace(src)
src = regexp.MustCompile(` +`).ReplaceAllString(src, "-")
src = strings.ToLower(src)
return src, nil
}
52 changes: 52 additions & 0 deletions src/pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,55 @@ func Test_IsRegistryURL(t *testing.T) {
})
}
}

func Test_formatBundleName(t *testing.T) {
tests := map[string]struct {
src string
expected string
shouldErr bool // not used yet
}{
"valid": {
src: "wordpress",
expected: "wordpress",
},
"valid mixed caps": {
src: "woRdprEsS",
expected: "wordpress",
},
"valid spaces": {
src: "woRdprEsS version 1",
expected: "wordpress-version-1",
},
"valid leading spaces": {
// leading spaces trimmed but the space after the first "-" is
// converted to "-"
src: " - woRdprEsS version 1 ",
expected: "--wordpress-version-1",
},
"invalid chars": {
src: "woRdprEsS*version 1",
shouldErr: true,
},
"more invalid chars": {
src: "&*^woRdprEsS*version 1",
shouldErr: true,
},
}

for name, tt := range tests {
t.Run(name, func(t *testing.T) {
result, err := FormatBundleName(tt.src)
if tt.shouldErr && err != nil {
// expected error
return
}
if tt.shouldErr && err == nil {
t.Fatalf("expected error but got none")
}
if !tt.shouldErr && err != nil {
t.Fatalf("got error but expected none: %s", err)
}
require.Equal(t, tt.expected, result)
})
}
}
Loading