From 818e0b2fcf1ec69b28a215526a2682ed042044c4 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 14 Jul 2020 14:02:54 +0200 Subject: [PATCH 1/2] pkg/parsers: add unit test for Darwin Signed-off-by: Sebastiaan van Stijn --- pkg/parsers/kernel/kernel_darwin_test.go | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 pkg/parsers/kernel/kernel_darwin_test.go diff --git a/pkg/parsers/kernel/kernel_darwin_test.go b/pkg/parsers/kernel/kernel_darwin_test.go new file mode 100644 index 0000000000..8fe58642e9 --- /dev/null +++ b/pkg/parsers/kernel/kernel_darwin_test.go @@ -0,0 +1,28 @@ +package kernel + +import ( + "testing" + + "gotest.tools/v3/assert" +) + +func TestGetRelease(t *testing.T) { + // example output of "system_profiler SPSoftwareDataType" + const spSoftwareDataType = `Software: + + System Software Overview: + + System Version: macOS 10.14.6 (18G4032) + Kernel Version: Darwin 18.7.0 + Boot Volume: fastfood + Boot Mode: Normal + Computer Name: Macintosh + User Name: Foobar (foobar) + Secure Virtual Memory: Enabled + System Integrity Protection: Enabled + Time since boot: 6 days 23:16 +` + release, err := getRelease(spSoftwareDataType) + assert.NilError(t, err) + assert.Equal(t, release, "18.7.0") +} From c9c9e0ab90e902bfea72af04f85b4d087f8f163f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 14 Jul 2020 14:03:10 +0200 Subject: [PATCH 2/2] pkg/parsers: remove uses of mattn/go-shellwords Signed-off-by: Sebastiaan van Stijn --- pkg/parsers/kernel/kernel_darwin.go | 60 +++--- .../operatingsystem/operatingsystem_linux.go | 11 +- .../operatingsystem_linux_test.go | 26 --- vendor.conf | 1 - vendor/github.com/mattn/go-shellwords/LICENSE | 21 -- .../github.com/mattn/go-shellwords/README.md | 47 ----- vendor/github.com/mattn/go-shellwords/go.mod | 1 - .../mattn/go-shellwords/shellwords.go | 193 ------------------ .../mattn/go-shellwords/util_go15.go | 29 --- .../mattn/go-shellwords/util_posix.go | 26 --- .../mattn/go-shellwords/util_windows.go | 26 --- 11 files changed, 32 insertions(+), 409 deletions(-) delete mode 100644 vendor/github.com/mattn/go-shellwords/LICENSE delete mode 100644 vendor/github.com/mattn/go-shellwords/README.md delete mode 100644 vendor/github.com/mattn/go-shellwords/go.mod delete mode 100644 vendor/github.com/mattn/go-shellwords/shellwords.go delete mode 100644 vendor/github.com/mattn/go-shellwords/util_go15.go delete mode 100644 vendor/github.com/mattn/go-shellwords/util_posix.go delete mode 100644 vendor/github.com/mattn/go-shellwords/util_windows.go diff --git a/pkg/parsers/kernel/kernel_darwin.go b/pkg/parsers/kernel/kernel_darwin.go index 6a302dcee2..652a2ce31e 100644 --- a/pkg/parsers/kernel/kernel_darwin.go +++ b/pkg/parsers/kernel/kernel_darwin.go @@ -8,49 +8,51 @@ import ( "fmt" "os/exec" "strings" - - shellwords "github.com/mattn/go-shellwords" ) // GetKernelVersion gets the current kernel version. func GetKernelVersion() (*VersionInfo, error) { - release, err := getRelease() + osName, err := getSPSoftwareDataType() + if err != nil { + return nil, err + } + release, err := getRelease(osName) if err != nil { return nil, err } - return ParseRelease(release) } // getRelease uses `system_profiler SPSoftwareDataType` to get OSX kernel version -func getRelease() (string, error) { +func getRelease(osName string) (string, error) { + var release string + data := strings.Split(osName, "\n") + for _, line := range data { + if !strings.Contains(line, "Kernel Version") { + continue + } + // It has the format like ' Kernel Version: Darwin 14.5.0' + content := strings.SplitN(line, ":", 2) + if len(content) != 2 { + return "", fmt.Errorf("Kernel Version is invalid") + } + + prettyNames := strings.SplitN(strings.TrimSpace(content[1]), " ", 2) + + if len(prettyNames) != 2 { + return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ") + } + release = prettyNames[1] + } + + return release, nil +} + +func getSPSoftwareDataType() (string, error) { cmd := exec.Command("system_profiler", "SPSoftwareDataType") osName, err := cmd.Output() if err != nil { return "", err } - - var release string - data := strings.Split(string(osName), "\n") - for _, line := range data { - if strings.Contains(line, "Kernel Version") { - // It has the format like ' Kernel Version: Darwin 14.5.0' - content := strings.SplitN(line, ":", 2) - if len(content) != 2 { - return "", fmt.Errorf("Kernel Version is invalid") - } - - prettyNames, err := shellwords.Parse(content[1]) - if err != nil { - return "", fmt.Errorf("Kernel Version is invalid: %s", err.Error()) - } - - if len(prettyNames) != 2 { - return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ") - } - release = prettyNames[1] - } - } - - return release, nil + return string(osName), nil } diff --git a/pkg/parsers/operatingsystem/operatingsystem_linux.go b/pkg/parsers/operatingsystem/operatingsystem_linux.go index 18dc39472c..c3b0634bcf 100644 --- a/pkg/parsers/operatingsystem/operatingsystem_linux.go +++ b/pkg/parsers/operatingsystem/operatingsystem_linux.go @@ -9,8 +9,6 @@ import ( "io/ioutil" "os" "strings" - - shellwords "github.com/mattn/go-shellwords" ) var ( @@ -63,14 +61,7 @@ func getValueFromOsRelease(key string) (string, error) { line := scanner.Text() if strings.HasPrefix(line, keyWithTrailingEqual) { data := strings.SplitN(line, "=", 2) - values, err := shellwords.Parse(data[1]) - if err != nil { - return "", fmt.Errorf("%s is invalid: %s", key, err.Error()) - } - if len(values) != 1 { - return "", fmt.Errorf("%s needs to be enclosed by quotes if they have spaces: %s", key, data[1]) - } - value = values[0] + value = strings.Trim(data[1], `"' `) // remove leading/trailing quotes and whitespace } } diff --git a/pkg/parsers/operatingsystem/operatingsystem_linux_test.go b/pkg/parsers/operatingsystem/operatingsystem_linux_test.go index ec761b669e..75d608a598 100644 --- a/pkg/parsers/operatingsystem/operatingsystem_linux_test.go +++ b/pkg/parsers/operatingsystem/operatingsystem_linux_test.go @@ -20,26 +20,6 @@ type EtcReleaseParsingTest struct { func TestGetOperatingSystem(t *testing.T) { tests := []EtcReleaseParsingTest{ - { - content: `PRETTY_NAME=Source Mage GNU/Linux -PRETTY_NAME=Ubuntu 14.04.LTS`, - expectedErr: "PRETTY_NAME needs to be enclosed by quotes if they have spaces: Source Mage GNU/Linux", - }, - { - content: `PRETTY_NAME="Ubuntu Linux -PRETTY_NAME=Ubuntu 14.04.LTS`, - expectedErr: "PRETTY_NAME is invalid: invalid command line string", - }, - { - content: `PRETTY_NAME=Ubuntu' -PRETTY_NAME=Ubuntu 14.04.LTS`, - expectedErr: "PRETTY_NAME is invalid: invalid command line string", - }, - { - content: `PRETTY_NAME' -PRETTY_NAME=Ubuntu 14.04.LTS`, - expectedErr: "PRETTY_NAME needs to be enclosed by quotes if they have spaces: Ubuntu 14.04.LTS", - }, { content: `NAME="Ubuntu" PRETTY_NAME_AGAIN="Ubuntu 14.04.LTS" @@ -111,12 +91,6 @@ PRETTY_NAME="Source Mage"`, func TestGetOperatingSystemVersion(t *testing.T) { tests := []EtcReleaseParsingTest{ - { - name: "invalid version id", - content: `VERSION_ID="18.04 -VERSION_ID=18.04`, - expectedErr: "VERSION_ID is invalid: invalid command line string", - }, { name: "ubuntu 14.04", content: `NAME="Ubuntu" diff --git a/vendor.conf b/vendor.conf index b1e1f15e67..5623ca449d 100644 --- a/vendor.conf +++ b/vendor.conf @@ -10,7 +10,6 @@ github.com/moby/term 73f35e472e8f0a3f91347164138c github.com/creack/pty 3a6a957789163cacdfe0e291617a1c8e80612c11 # v1.1.9 github.com/konsorten/go-windows-terminal-sequences edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3 -github.com/mattn/go-shellwords 36a9b3c57cb5caa559ff63fb7e9b585f1c00df75 # v1.0.6 github.com/sirupsen/logrus 60c74ad9be0d874af0ab0daef6ab07c5c5911f0d # v1.6.0 github.com/tchap/go-patricia a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0 golang.org/x/net 0de0cce0169b09b364e001f108dc0399ea8630b3 diff --git a/vendor/github.com/mattn/go-shellwords/LICENSE b/vendor/github.com/mattn/go-shellwords/LICENSE deleted file mode 100644 index 740fa93132..0000000000 --- a/vendor/github.com/mattn/go-shellwords/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-shellwords/README.md b/vendor/github.com/mattn/go-shellwords/README.md deleted file mode 100644 index 9e1e650457..0000000000 --- a/vendor/github.com/mattn/go-shellwords/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# go-shellwords - -[![codecov](https://codecov.io/gh/mattn/go-shellwords/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-shellwords) -[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords) - -Parse line as shell words. - -## Usage - -```go -args, err := shellwords.Parse("./foo --bar=baz") -// args should be ["./foo", "--bar=baz"] -``` - -```go -os.Setenv("FOO", "bar") -p := shellwords.NewParser() -p.ParseEnv = true -args, err := p.Parse("./foo $FOO") -// args should be ["./foo", "bar"] -``` - -```go -p := shellwords.NewParser() -p.ParseBacktick = true -args, err := p.Parse("./foo `echo $SHELL`") -// args should be ["./foo", "/bin/bash"] -``` - -```go -shellwords.ParseBacktick = true -p := shellwords.NewParser() -args, err := p.Parse("./foo `echo $SHELL`") -// args should be ["./foo", "/bin/bash"] -``` - -# Thanks - -This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine). - -# License - -under the MIT License: http://mattn.mit-license.org/2017 - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-shellwords/go.mod b/vendor/github.com/mattn/go-shellwords/go.mod deleted file mode 100644 index 8d96dbd5fa..0000000000 --- a/vendor/github.com/mattn/go-shellwords/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/mattn/go-shellwords diff --git a/vendor/github.com/mattn/go-shellwords/shellwords.go b/vendor/github.com/mattn/go-shellwords/shellwords.go deleted file mode 100644 index 2dca7f1361..0000000000 --- a/vendor/github.com/mattn/go-shellwords/shellwords.go +++ /dev/null @@ -1,193 +0,0 @@ -package shellwords - -import ( - "errors" - "os" - "regexp" - "strings" -) - -var ( - ParseEnv bool = false - ParseBacktick bool = false -) - -var envRe = regexp.MustCompile(`\$({[a-zA-Z0-9_]+}|[a-zA-Z0-9_]+)`) - -func isSpace(r rune) bool { - switch r { - case ' ', '\t', '\r', '\n': - return true - } - return false -} - -func replaceEnv(getenv func(string) string, s string) string { - if getenv == nil { - getenv = os.Getenv - } - - return envRe.ReplaceAllStringFunc(s, func(s string) string { - s = s[1:] - if s[0] == '{' { - s = s[1 : len(s)-1] - } - return getenv(s) - }) -} - -type Parser struct { - ParseEnv bool - ParseBacktick bool - Position int - Dir string - - // If ParseEnv is true, use this for getenv. - // If nil, use os.Getenv. - Getenv func(string) string -} - -func NewParser() *Parser { - return &Parser{ - ParseEnv: ParseEnv, - ParseBacktick: ParseBacktick, - Position: 0, - Dir: "", - } -} - -func (p *Parser) Parse(line string) ([]string, error) { - args := []string{} - buf := "" - var escaped, doubleQuoted, singleQuoted, backQuote, dollarQuote bool - backtick := "" - - pos := -1 - got := false - -loop: - for i, r := range line { - if escaped { - buf += string(r) - escaped = false - continue - } - - if r == '\\' { - if singleQuoted { - buf += string(r) - } else { - escaped = true - } - continue - } - - if isSpace(r) { - if singleQuoted || doubleQuoted || backQuote || dollarQuote { - buf += string(r) - backtick += string(r) - } else if got { - if p.ParseEnv { - buf = replaceEnv(p.Getenv, buf) - } - args = append(args, buf) - buf = "" - got = false - } - continue - } - - switch r { - case '`': - if !singleQuoted && !doubleQuoted && !dollarQuote { - if p.ParseBacktick { - if backQuote { - out, err := shellRun(backtick, p.Dir) - if err != nil { - return nil, err - } - buf = buf[:len(buf)-len(backtick)] + out - } - backtick = "" - backQuote = !backQuote - continue - } - backtick = "" - backQuote = !backQuote - } - case ')': - if !singleQuoted && !doubleQuoted && !backQuote { - if p.ParseBacktick { - if dollarQuote { - out, err := shellRun(backtick, p.Dir) - if err != nil { - return nil, err - } - buf = buf[:len(buf)-len(backtick)-2] + out - } - backtick = "" - dollarQuote = !dollarQuote - continue - } - backtick = "" - dollarQuote = !dollarQuote - } - case '(': - if !singleQuoted && !doubleQuoted && !backQuote { - if !dollarQuote && strings.HasSuffix(buf, "$") { - dollarQuote = true - buf += "(" - continue - } else { - return nil, errors.New("invalid command line string") - } - } - case '"': - if !singleQuoted && !dollarQuote { - doubleQuoted = !doubleQuoted - continue - } - case '\'': - if !doubleQuoted && !dollarQuote { - singleQuoted = !singleQuoted - continue - } - case ';', '&', '|', '<', '>': - if !(escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote) { - if r == '>' && len(buf) > 0 { - if c := buf[0]; '0' <= c && c <= '9' { - i -= 1 - got = false - } - } - pos = i - break loop - } - } - - got = true - buf += string(r) - if backQuote || dollarQuote { - backtick += string(r) - } - } - - if got { - if p.ParseEnv { - buf = replaceEnv(p.Getenv, buf) - } - args = append(args, buf) - } - - if escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote { - return nil, errors.New("invalid command line string") - } - - p.Position = pos - - return args, nil -} - -func Parse(line string) ([]string, error) { - return NewParser().Parse(line) -} diff --git a/vendor/github.com/mattn/go-shellwords/util_go15.go b/vendor/github.com/mattn/go-shellwords/util_go15.go deleted file mode 100644 index ddcbf229e6..0000000000 --- a/vendor/github.com/mattn/go-shellwords/util_go15.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build !go1.6 - -package shellwords - -import ( - "os" - "os/exec" - "runtime" - "strings" -) - -func shellRun(line, dir string) (string, error) { - var b []byte - var err error - var cmd *exec.Cmd - if runtime.GOOS == "windows" { - cmd = exec.Command(os.Getenv("COMSPEC"), "/c", line) - } else { - cmd = exec.Command(os.Getenv("SHELL"), "-c", line) - } - if dir != "" { - cmd.Dir = dir - } - b, err = cmd.Output() - if err != nil { - return "", err - } - return strings.TrimSpace(string(b)), nil -} diff --git a/vendor/github.com/mattn/go-shellwords/util_posix.go b/vendor/github.com/mattn/go-shellwords/util_posix.go deleted file mode 100644 index 3aef2c4d79..0000000000 --- a/vendor/github.com/mattn/go-shellwords/util_posix.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build !windows,go1.6 - -package shellwords - -import ( - "errors" - "os" - "os/exec" - "strings" -) - -func shellRun(line, dir string) (string, error) { - shell := os.Getenv("SHELL") - cmd := exec.Command(shell, "-c", line) - if dir != "" { - cmd.Dir = dir - } - b, err := cmd.Output() - if err != nil { - if eerr, ok := err.(*exec.ExitError); ok { - b = eerr.Stderr - } - return "", errors.New(err.Error() + ":" + string(b)) - } - return strings.TrimSpace(string(b)), nil -} diff --git a/vendor/github.com/mattn/go-shellwords/util_windows.go b/vendor/github.com/mattn/go-shellwords/util_windows.go deleted file mode 100644 index cda6850910..0000000000 --- a/vendor/github.com/mattn/go-shellwords/util_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -// +build windows,go1.6 - -package shellwords - -import ( - "errors" - "os" - "os/exec" - "strings" -) - -func shellRun(line, dir string) (string, error) { - shell := os.Getenv("COMSPEC") - cmd := exec.Command(shell, "/c", line) - if dir != "" { - cmd.Dir = dir - } - b, err := cmd.Output() - if err != nil { - if eerr, ok := err.(*exec.ExitError); ok { - b = eerr.Stderr - } - return "", errors.New(err.Error() + ":" + string(b)) - } - return strings.TrimSpace(string(b)), nil -}