From a06a8d0a1b23505698e8237628eb349907d274ec Mon Sep 17 00:00:00 2001 From: Rumen Vasilev Date: Mon, 13 Nov 2023 00:22:42 +0100 Subject: [PATCH] use more io functions, eliminating duplicity Signed-off-by: Rumen Vasilev --- internal/config/config.go | 2 +- internal/core/analysis.go | 9 +- internal/pkg/signatures/signatures.go | 16 +-- internal/util/io.go | 181 +++++++++++--------------- internal/util/io_test.go | 4 +- 5 files changed, 90 insertions(+), 122 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 4b84ded..2e7677d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -142,7 +142,7 @@ func SetConfig(cmd *cobra.Command) { cf := viper.GetString("global.config-file") noconfig := false if cf != "" && cf != configFile { - if util.FileExists(cf) { + if util.PathExists(cf) { viper.SetConfigFile(cf) } else { noconfig = true diff --git a/internal/core/analysis.go b/internal/core/analysis.go index c7e8551..46e6351 100644 --- a/internal/core/analysis.go +++ b/internal/core/analysis.go @@ -246,8 +246,7 @@ func AnalyzeObject(ctx context.Context, sess *session.Session, change *object.Ch func isIgnoredFile(cfgScanTests bool, cfgMaxFileSize int64, fullFilePath string, mf matchfile.MatchFile, cfgSkippableExt, cfgSkippablePath []string) (bool, string) { // Check if file exist before moving on - _, err := os.Stat(fullFilePath) - if err != nil { + if !util.PathExists(fullFilePath) { return true, "file does not exist" } @@ -272,13 +271,12 @@ func isIgnoredFile(cfgScanTests bool, cfgMaxFileSize int64, fullFilePath string, // Check the file size of the file. If it is greater than the default size then // then we increment the ignored file count and pass on through. - yes, msg := util.IsMaxFileSize(fullFilePath, cfgMaxFileSize) - if yes { + if yes, msg := util.IsMaxFileSize(fullFilePath, cfgMaxFileSize); yes { return true, msg } // Check if it is a binary file - yes, err = util.IsBinaryFile(fullFilePath) + yes, err := util.IsBinaryFile(fullFilePath) if yes || err != nil { return true, "is a binary file, ignoring" } @@ -286,6 +284,7 @@ func isIgnoredFile(cfgScanTests bool, cfgMaxFileSize int64, fullFilePath string, if mf.IsSkippable(cfgSkippableExt, cfgSkippablePath) { return true, "is skippable, ignoring" } + return false, "" } diff --git a/internal/pkg/signatures/signatures.go b/internal/pkg/signatures/signatures.go index c77d1ab..9ca05e7 100644 --- a/internal/pkg/signatures/signatures.go +++ b/internal/pkg/signatures/signatures.go @@ -80,21 +80,13 @@ func updateSignatures(rRepo string, sess *session.Session) bool { tempSignaturesDir := rRepo + "/signatures" // ensure we have the proper home directory - home, err := util.SetHomeDir(sess.Config.Signatures.Path) + // if the signatures path does not exist then we create it + home, err := util.MakeHomeDir(sess.Config.Signatures.Path) if err != nil { - log.Error("failed setting the home directory for signatures to %q, error %s", sess.Config.Signatures.Path, err.Error()) + log.Error("couldn't create signatures directory %q, error %s", sess.Config.Signatures.Path, err.Error()) return false } - // if the signatures path does not exist then we create it - if !util.PathExists(home) { - err := os.MkdirAll(home, 0700) - if err != nil { - log.Error("couldn't create directory for signatures %q", home, err.Error()) - return false - } - } - // if we want to test the signatures before we install them if sess.Config.Signatures.Test { if !executeTests(tempSignaturesDir) { @@ -118,7 +110,7 @@ func updateSignatures(rRepo string, sess *session.Session) bool { func executeTests(dir string) bool { log := log.Log log.Debug("Running tests on acquired signature files...") - sigFiles, err := util.GetSignatureFiles(dir) + sigFiles, err := util.GetYamlFiles(dir) if err != nil { log.Error("Failed to get signature files from target path %q, error: %q", dir, err.Error()) return false diff --git a/internal/util/io.go b/internal/util/io.go index 741863b..c55b5f7 100644 --- a/internal/util/io.go +++ b/internal/util/io.go @@ -15,74 +15,28 @@ import ( cp "github.com/otiai10/copy" ) -var magicNumbers = [][]byte{ - {0x1F, 0x8B, 0x08, 0x00}, // GZip - {0x42, 0x5A, 0x68, 0x32}, // BZip2 - {0x50, 0x4B, 0x03, 0x04}, // ZIP - {0x89, 0x50, 0x4E, 0x47}, // PNG - {0x4D, 0x5A}, // Windows EXE - {0x7F, 'E', 'L', 'F'}, // Linux ELF Executable - {0xFE, 0xED, 0xFA, 0xCE, 0xCE, 0xFA, 0xED, 0xFE}, // macOS Mach-O Binary - {0xFE, 0xED, 0xFA, 0xCF, 0x0C, 0x00, 0x00, 0x01}, // Mach-O 64-bit (x86_64) -} - // TODO THIS FUNC HAS TO RETURN ERROR, OTHERWISE WE DO THE SAME CHECK AGAIN LATER // PathExists will check if a path exists or not and is used to validate user input func PathExists(path string) bool { - _, err := os.Stat(path) - if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENOSPC { - return false - } - - if err == nil { - return true - } - - if os.IsNotExist(err) { - // logger.Debug("Path does not exist: %s", err.Error()) - return false - } - - return true -} - -// FileExists will check for the existence of a file and return a bool depending -// on if it exists in a given path or not. -func FileExists(path string) bool { _, err := os.Stat(path) if err != nil { - // File does not exist? - return !errors.Is(err, fs.ErrNotExist) - } - return true -} - -// SetHomeDir will set the correct homedir. -func SetHomeDir(h string) (string, error) { - if strings.Contains(h, "$HOME") { - home, err := homedir.Dir() - if err != nil { - return "", err + if errors.Is(err, fs.ErrNotExist) { + return false } - h = strings.Replace(h, "$HOME", home, -1) - } - - if strings.Contains(h, "~") { - home, err := homedir.Dir() - if err != nil { - return "", err + var e *os.PathError + if errors.As(err, &e) { + return e.Err == syscall.ENOSPC } - h = strings.Replace(h, "~", home, -1) } - return h, nil + + return true } // IsMaxFileSize will determine if the file size is under the max limit set by maxFileSize func IsMaxFileSize(filename string, maxFileSize int64) (bool, string) { fi, err := os.Stat(filename) - // This error occurs when the file is not found. // The source of truth for files traversed comes from: // git - the commit history (or) @@ -93,65 +47,61 @@ func IsMaxFileSize(filename string, maxFileSize int64) (bool, string) { // // In the case of git, it can be assumed that the file will exist somewhere in the commit history. // Thereforce, we assume that the file size is within the limit and return false. - if _, ok := err.(*os.PathError); ok { - return false, "does not exist" + if err != nil { + return false, err.Error() } - fileSize := fi.Size() mfs := maxFileSize * 1024 * 1024 - - if fileSize > mfs { + if fi.Size() > mfs { return true, "is too large" } + return false, "" } -// IsTestFileOrPath will run various regex's against a target to determine if it is a test file or contained in a test directory. -func IsTestFileOrPath(fullPath string) bool { - fName := filepath.Base(fullPath) - - // If the directory contains "test" - // Ex. foo/test/bar - r := regexp.MustCompile(`(?i)[/\\]test?[/\\]`) - if r.MatchString(fullPath) { - return true - } - - // If the directory starts with test, the leading slash gets dropped by default - // Ex. test/foo/bar - r = regexp.MustCompile(`(?i)test?[/\\]`) - if r.MatchString(fullPath) { - return true - } - - // If the directory path starts with a different root but has the word test in it somewhere - // Ex. foo/test-secrets/bar - r = regexp.MustCompile(`/test.*/`) - if r.MatchString(fullPath) { - return true +var ( + testPathRegex = []string{ + // If the directory contains "test" + // Ex. foo/test/bar + `(?i)[/\\]test?[/\\]`, + // If the directory starts with test, the leading slash gets dropped by default + // Ex. test/foo/bar + `(?i)test?[/\\]`, + // If the directory path starts with a different root but has the word test in it somewhere + // Ex. foo/test-secrets/bar + `/test.*/`, + } + testFileRegex = []string{ + // A the word Test is in the string, case sensitive + // Ex. ghTestlk + // Ex. Testllfhe + // Ex. Test + `Test`, + // A file has a suffix of _test + // Golang uses this as the default test file naming convention + //Ex. foo_test.go + `(?i)_test`, + // If the pattern _test_ is in the string + // Ex. foo_test_baz + `(?i)_test?_`, } +) - // A the word Test is in the string, case sensitive - // Ex. ghTestlk - // Ex. Testllfhe - // Ex. Test - r = regexp.MustCompile(`Test`) - if r.MatchString(fName) { - return true +// IsTestFileOrPath will run various regex's against a target to determine if it is a test file or contained in a test directory. +func IsTestFileOrPath(fullPath string) bool { + var r *regexp.Regexp + for _, pattern := range testPathRegex { + r = regexp.MustCompile(pattern) + return r.MatchString(fullPath) } - // A file has a suffix of _test - // Golang uses this as the default test file naming convention - //Ex. foo_test.go - r = regexp.MustCompile(`(?i)_test`) - if r.MatchString(fName) { - return true + fName := filepath.Base(fullPath) + for _, pattern := range testFileRegex { + r = regexp.MustCompile(pattern) + return r.MatchString(fName) } - // If the pattern _test_ is in the string - // Ex. foo_test_baz - r = regexp.MustCompile(`(?i)_test?_`) - return r.MatchString(fName) + return false } func MakeHomeDir(path string) (string, error) { @@ -171,6 +121,22 @@ func MakeHomeDir(path string) (string, error) { return dir, nil } +// SetHomeDir will set the correct homedir. +func SetHomeDir(h string) (string, error) { + for _, v := range []string{"$HOME", "~"} { + if strings.Contains(h, v) { + home, err := homedir.Dir() + if err != nil { + return "", err + } + + h = strings.Replace(h, v, home, -1) + } + } + + return h, nil +} + // WriteToFile will create a new file or truncate the existing one and write the input byte stream. func WriteToFile(path string, input []byte) error { fh, err := os.Create(path) @@ -179,7 +145,7 @@ func WriteToFile(path string, input []byte) error { } _, err = fh.Write(input) if err != nil { - return fmt.Errorf("failed writing to configuration file, %w", err) + return fmt.Errorf("failed writing to file %q, %w", path, err) } return nil } @@ -190,7 +156,7 @@ func CopyFiles(src, dest string) error { return err } - sigs, err := GetSignatureFiles(dest) + sigs, err := GetYamlFiles(dest) if err != nil { return err } @@ -204,8 +170,8 @@ func CopyFiles(src, dest string) error { return nil } -// GetSignatureFiles will find all the yaml files in the signatures directory -func GetSignatureFiles(dir string) ([]string, error) { +// GetYamlFiles will find all the yaml files in the provided directory path and return a string slice with all findings +func GetYamlFiles(dir string) ([]string, error) { files, err := os.ReadDir(dir) if err != nil { return nil, err @@ -222,6 +188,17 @@ func GetSignatureFiles(dir string) ([]string, error) { return sigs, nil } +var magicNumbers = [][]byte{ + {0x1F, 0x8B, 0x08, 0x00}, // GZip + {0x42, 0x5A, 0x68, 0x32}, // BZip2 + {0x50, 0x4B, 0x03, 0x04}, // ZIP + {0x89, 0x50, 0x4E, 0x47}, // PNG + {0x4D, 0x5A}, // Windows EXE + {0x7F, 'E', 'L', 'F'}, // Linux ELF Executable + {0xFE, 0xED, 0xFA, 0xCE, 0xCE, 0xFA, 0xED, 0xFE}, // macOS Mach-O Binary + {0xFE, 0xED, 0xFA, 0xCF, 0x0C, 0x00, 0x00, 0x01}, // Mach-O 64-bit (x86_64) +} + func IsBinaryFile(filePath string) (bool, error) { file, err := os.Open(filePath) if err != nil { diff --git a/internal/util/io_test.go b/internal/util/io_test.go index b7ea476..144079f 100644 --- a/internal/util/io_test.go +++ b/internal/util/io_test.go @@ -18,7 +18,7 @@ func TestFileExists(t *testing.T) { Convey("When the file exists", func() { f := "../../README.md" - b := FileExists(f) + b := PathExists(f) Convey("The function should return true", func() { So(b, ShouldEqual, true) @@ -30,7 +30,7 @@ func TestFileExists(t *testing.T) { Convey("When the file does not exist", func() { f := "../NOPE.md" - b := FileExists(f) + b := PathExists(f) Convey("The function should return false", func() { So(b, ShouldEqual, false)