diff --git a/plugin/client.go b/plugin/client.go index 299af12..5bf0141 100644 --- a/plugin/client.go +++ b/plugin/client.go @@ -193,7 +193,7 @@ func NewIdentityWithoutData(name string, ui *ClientUI) (*Identity, error) { return nil, fmt.Errorf("invalid plugin name: %q", name) } return &Identity{ - name: name, encoding: s, ui: ui, + name: strings.ToLower(name), encoding: s, ui: ui, }, nil } diff --git a/plugin/client_test.go b/plugin/client_test.go index 04f6335..3fc8482 100644 --- a/plugin/client_test.go +++ b/plugin/client_test.go @@ -84,6 +84,26 @@ func TestIdentityV1NegativeIndex(t *testing.T) { } } +func TestPluginNameCase(t *testing.T) { + p, err := New("MixedCase") + if err != nil { + t.Fatal(err) + } + if p.Name() != "mixedcase" { + t.Errorf("Plugin.Name = %q", p.Name()) + } + id, err := NewIdentityWithoutData("MixedCase", &ClientUI{}) + if err != nil { + t.Fatal(err) + } + if id.Name() != "mixedcase" { + t.Errorf("Identity.Name = %q", id.Name()) + } + if _, err := New("\u212a"); err == nil { + t.Error("New accepted a non-ASCII name") + } +} + func TestLabels(t *testing.T) { if runtime.GOOS == "windows" { t.Skip("Windows support is TODO") diff --git a/plugin/plugin.go b/plugin/plugin.go index c1a650d..c9d28fe 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -16,6 +16,7 @@ import ( "os" "slices" "strconv" + "strings" "filippo.io/age" "filippo.io/age/internal/format" @@ -44,11 +45,14 @@ type Plugin struct { broken bool } -// New creates a new Plugin with the given name. +// New creates a new Plugin with the given case-insensitive name. // // For example, a plugin named "frood" would be invoked as "age-plugin-frood". func New(name string) (*Plugin, error) { - return &Plugin{name: name, stdin: os.Stdin, + if !validPluginName(name) { + return nil, fmt.Errorf("invalid plugin name: %q", name) + } + return &Plugin{name: strings.ToLower(name), stdin: os.Stdin, stdout: os.Stdout, stderr: os.Stderr}, nil }