mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
Fix reading syft json from stdin by redirect (#1299)
I figured out that running `cat syft.json | grype` works but `grype < syft.json` does not work. This happens, because the IsPipedInput method only checks if stdin is a pipe which will be false if stdin is fed by a redirect. The go idiomatic way to fix this is by just checking if the file produced by stat has a size > 0. Implemented this check, that will recognize stdin by redirect, in the IsPipedInput() method. Renamed the method to IsStdinPipeOrRedirect(). Signed-off-by: Felix Becker <git@felixbecker.name> Co-authored-by: Benjamin Neff <benjamin@coding4coffee.ch>
This commit is contained in:
parent
d74e85385c
commit
e1bdbc7d27
3 changed files with 10 additions and 10 deletions
10
cmd/root.go
10
cmd/root.go
|
@ -283,14 +283,14 @@ func rootExec(_ *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
func isVerbose() (result bool) {
|
||||
isPipedInput, err := internal.IsPipedInput()
|
||||
isStdinPipeOrRedirect, err := internal.IsStdinPipeOrRedirect()
|
||||
if err != nil {
|
||||
// since we can't tell if there was piped input we assume that there could be to disable the ETUI
|
||||
log.Warnf("unable to determine if there is piped input: %+v", err)
|
||||
return true
|
||||
}
|
||||
// verbosity should consider if there is piped input (in which case we should not show the ETUI)
|
||||
return appConfig.CliOptions.Verbosity > 0 || isPipedInput
|
||||
return appConfig.CliOptions.Verbosity > 0 || isStdinPipeOrRedirect
|
||||
}
|
||||
|
||||
//nolint:funlen
|
||||
|
@ -502,13 +502,13 @@ func validateDBLoad(loadErr error, status *db.Status) error {
|
|||
}
|
||||
|
||||
func validateRootArgs(cmd *cobra.Command, args []string) error {
|
||||
isPipedInput, err := internal.IsPipedInput()
|
||||
isStdinPipeOrRedirect, err := internal.IsStdinPipeOrRedirect()
|
||||
if err != nil {
|
||||
log.Warnf("unable to determine if there is piped input: %+v", err)
|
||||
isPipedInput = false
|
||||
isStdinPipeOrRedirect = false
|
||||
}
|
||||
|
||||
if len(args) == 0 && !isPipedInput {
|
||||
if len(args) == 0 && !isStdinPipeOrRedirect {
|
||||
// in the case that no arguments are given and there is no piped input we want to show the help text and return with a non-0 return code.
|
||||
if err := cmd.Help(); err != nil {
|
||||
return fmt.Errorf("unable to display help: %w", err)
|
||||
|
|
|
@ -142,13 +142,13 @@ func fileHasContent(f *os.File) bool {
|
|||
}
|
||||
|
||||
func stdinReader() io.Reader {
|
||||
isPipedInput, err := internal.IsPipedInput()
|
||||
isStdinPipeOrRedirect, err := internal.IsStdinPipeOrRedirect()
|
||||
if err != nil {
|
||||
log.Warnf("unable to determine if there is piped input: %+v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !isPipedInput {
|
||||
if !isStdinPipeOrRedirect {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
// IsPipedInput returns true if there is no input device, which means the user **may** be providing input via a pipe.
|
||||
func IsPipedInput() (bool, error) {
|
||||
// IsStdinPipeOrRedirect returns true if stdin is provided via pipe or redirect
|
||||
func IsStdinPipeOrRedirect() (bool, error) {
|
||||
fi, err := os.Stdin.Stat()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("unable to determine if there is piped input: %w", err)
|
||||
|
@ -16,5 +16,5 @@ func IsPipedInput() (bool, error) {
|
|||
// on stdin, as running grype as a subprocess you would expect no character device to be present but input can
|
||||
// be from either stdin or indicated by the CLI. Checking if stdin is a pipe is the most direct way to determine
|
||||
// if there *may* be bytes that will show up on stdin that should be used for the analysis source.
|
||||
return fi.Mode()&os.ModeNamedPipe != 0, nil
|
||||
return fi.Mode()&os.ModeNamedPipe != 0 || fi.Size() > 0, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue