diff --git a/lib/versioner/external.go b/lib/versioner/external.go index 37e6fa03d..c43a81a00 100644 --- a/lib/versioner/external.go +++ b/lib/versioner/external.go @@ -111,6 +111,9 @@ func (v external) prepareCommand(filePath string) (*exec.Cmd, error) { if err != nil { return nil, fmt.Errorf("command is invalid: %w", err) } + if len(words) == 0 { + return nil, errors.New("command is empty") + } context := map[string]string{ "%FOLDER_FILESYSTEM%": string(v.filesystem.Type()), diff --git a/lib/versioner/external_test.go b/lib/versioner/external_test.go index 396b0d88b..1b1573f26 100644 --- a/lib/versioner/external_test.go +++ b/lib/versioner/external_test.go @@ -109,6 +109,20 @@ func TestExternalCommandSplit(t *testing.T) { } } +func TestExternalWhitespaceCommand(t *testing.T) { + // A whitespace-only command splits into zero words; prepareCommand must + // return an error rather than panicking on words[0]. + e := external{ + filesystem: fs.NewFilesystem(fs.FilesystemTypeFake, "TestExternalWhitespaceCommand"), + } + for _, cmd := range []string{" ", "\t", "\n", " \t \n"} { + e.command = cmd + if _, err := e.prepareCommand("file"); err == nil { + t.Errorf("expected error for command %q, got nil", cmd) + } + } +} + func prepForRemoval(t *testing.T, file string) { if err := os.RemoveAll("testdata"); err != nil { t.Fatal(err)