diff --git a/cli/scancommands.go b/cli/scancommands.go index 3eb215a5d..458f31281 100644 --- a/cli/scancommands.go +++ b/cli/scancommands.go @@ -194,7 +194,14 @@ func EnrichCmd(c *components.Context) error { func ScanCmd(c *components.Context) error { if len(c.Arguments) == 0 && !c.IsFlagSet(flags.SpecFlag) { return pluginsCommon.PrintHelpAndReturnError("providing either a argument or the 'spec' option is mandatory", c) + } else if len(c.Arguments) > 1 { + // If a non-existing flag was provided AFTER the provided source_pattern - it will be captured as another argument. Since 'scan' command + // Expects only a single argument, we use this check to verify all provided flags are valid. + // If a non exiting flag was provided BEFORE the source_pattern, the CLI will return an error before reaching this point. + errorMessage := fmt.Sprintf("Too many arguments provided (%d in total).\nSome flags may be incorrectly specified, causing them to be misinterpreted as arguments and ignored. Please verify that all flags are valid.", len(c.Arguments)) + return pluginsCommon.PrintHelpAndReturnError(errorMessage, c) } + serverDetails, err := createServerDetailsWithConfigOffer(c) if err != nil { return err diff --git a/scans_test.go b/scans_test.go index b3a0cdb5f..d11cc59db 100644 --- a/scans_test.go +++ b/scans_test.go @@ -76,6 +76,44 @@ func TestXrayBinaryScanSimpleJsonWithProgress(t *testing.T) { }) } +// This test verifies the correctness of a use case in 'scan' command, where a user provides the command's arguments before the command's flags, and there is an incorrect flag. +// Since the library that parses the command expects the flags to be provided before the arguments, it cannot recognize a wrongly provided flag when the order is reversed. +// This test checks the fix for this issue. +func TestXrayBinaryScanWithIncorrectFlagsAfterArgs(t *testing.T) { + testCases := []struct { + name string + flagsBeforeArgs bool + }{ + { + name: "flags before args", + flagsBeforeArgs: true, + }, + { + name: "args before flags", + flagsBeforeArgs: false, + }, + } + + callback := commonTests.MockProgressInitialization() + defer callback() + integration.InitScanTest(t, scangraph.GraphScanMinXrayVersion) + binariesPath := filepath.Join(filepath.FromSlash(securityTests.GetTestResourcesPath()), "projects", "binaries", "*") + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + var args []string + if test.flagsBeforeArgs { + args = []string{"scan", "--watch=my-watch", binariesPath} + } else { + args = []string{"scan", binariesPath, "--watch=my-watch"} + } + + err := securityTests.PlatformCli.Exec(args...) + assert.Error(t, err) + }) + } +} + func testXrayBinaryScan(t *testing.T, format, policyName, watchName string, errorExpected bool) string { binariesPath := filepath.Join(filepath.FromSlash(securityTests.GetTestResourcesPath()), "projects", "binaries", "*") args := []string{"scan", binariesPath, "--licenses", "--format=" + format}