Skip to content

Commit

Permalink
Merge pull request #91 from vaikas/tests
Browse files Browse the repository at this point in the history
Refactor, add tests.
  • Loading branch information
tstromberg authored Apr 4, 2024
2 parents 87d6447 + e3231af commit ca08337
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 55 deletions.
112 changes: 57 additions & 55 deletions pkg/action/programkind.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,36 @@ import (
"k8s.io/klog/v2"
)

// map from extensions to program kinds
var extMap = map[string]string{
".scpt": "compiled AppleScript",
".scptd": "compiled AppleScript",
".sh": "Shell script",
".rb": "Ruby script",
".py": "Python script",
".pl": "PERL script",
".yara": "",
".expect": "Expect script",
".php": "PHP file",
".html": "",
".js": "Javascript",
".ts": "Typescript",
".7z": "",
".json": "",
".yml": "",
".yaml": "",
".java": "Java source",
".jar": "Java program",
".asm": "",
".service": "systemd",
".cron": "crontab",
".crontab": "crontab",
".c": "C source",
}

// programKind tries to identify if a path is a program
func programKind(path string) string {
var header [263]byte

f, err := os.Open(path)
if err != nil {
log.Printf("os.Open[%s]: %v", path, err)
Expand All @@ -23,14 +49,26 @@ func programKind(path string) string {
defer f.Close()

desc := ""
if _, err := io.ReadFull(f, header[:]); err == nil {
kind, err := magic.Lookup(header[:])
var headerString string
n, err := io.ReadFull(f, header[:])
switch {
case err == nil || err == io.ErrUnexpectedEOF:
// Read the full buffer, or some bytes, all good
kind, err := magic.Lookup(header[:n])
if err == nil {
desc = kind.Description
} else {
desc = ""
}
headerString = string(header[:n])
case err == io.EOF:
// Nothing was read, so set the buffer so.
desc = ""
headerString = ""
}

klog.V(1).Infof("desc: %q header: %q err: %v", desc, header[:], err)
// TODO: Is it safe to log unsanitized file stuff?
klog.V(1).Infof("desc: %q header: %q err: %v", desc, headerString, err)

// the magic library gets these wrong
if strings.HasSuffix(path, ".json") {
Expand All @@ -57,63 +95,27 @@ func programKind(path string) string {
return "Shell script"
}

switch filepath.Ext(path) {
case ".scpt", "scptd":
return "compiled AppleScript"
case ".sh":
return "Shell script"
case ".rb":
return "Ruby script"
case ".py":
return "Python script"
case ".pl":
return "PERL script"
case ".yara":
return ""
case ".expect":
return "Expect script"
case ".php":
return "PHP file"
case ".html":
return ""
case ".js":
return "Javascript"
case ".ts":
return "Typescript"
case ".7z":
return ""
case ".json":
return ""
case ".yml", ".yaml":
return ""
case ".java":
return "Java source"
case ".jar":
return "Java program"
case ".asm":
return ""
case ".service":
return "systemd"
case ".cron", ".crontab":
return "crontab"
case ".c":
return "C source"
if found, kind := byExtension(path); found {
return kind
}

// By string match
s := string(header[:])
switch {
case strings.Contains(s, "import "):
return "Python"
case strings.HasPrefix(s, "#!/bin/sh") || strings.HasPrefix(s, "#!/bin/bash") || strings.Contains(s, `echo "`) || strings.Contains(s, `if [`) || strings.Contains(s, `grep `) || strings.Contains(s, "if !"):
return "Shell"
case strings.HasPrefix(s, "#!"):
case strings.Contains(headerString, "import "):
return "Python script"
case strings.HasPrefix(headerString, "#!/bin/sh") || strings.HasPrefix(headerString, "#!/bin/bash") || strings.Contains(headerString, `echo "`) || strings.Contains(headerString, `if [`) || strings.Contains(headerString, `grep `) || strings.Contains(headerString, "if !"):
return "Shell script"
case strings.HasPrefix(headerString, "#!"):
return "script"
case strings.Contains(s, "#include <"):
case strings.Contains(headerString, "#include <"):
return "C Program"
}

// fmt.Printf("File %s string: %s", path, s)
// fmt.Printf("File %s: desc: %s\n", path, desc)
return ""
}

// byExtension returns true, and descriptive file type if the extension is
// known, and false otherwise.
func byExtension(path string) (bool, string) {
ret, ok := extMap[filepath.Ext(path)]
return ok, ret
}
133 changes: 133 additions & 0 deletions pkg/action/programkind_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package action

import (
"fmt"
"testing"
)

func TestProgramKindMagic(t *testing.T) {

}

func TestProgramStringMatch(t *testing.T) {
tests := []struct {
filename string
want string
}{{
filename: "python",
want: "Python script",
}, {
filename: "shell",
want: "Shell script",
}, {
filename: "short",
want: "",
}, {
filename: "empty",
want: "",
}, {
filename: "rando", // generated with : `head -c 1024 </dev/urandom >pkg/action/testdata/rando`
}, {
filename: "juttu",
want: "",
}}
for _, tt := range tests {
t.Run(tt.filename, func(t *testing.T) {
got := programKind(fmt.Sprintf("testdata/%s", tt.filename))
if got != tt.want {
t.Errorf("programKind() = %v, want %v", got, tt.want)
}
})
}
}

func TestProgramKindExtensions(t *testing.T) {
tests := []struct {
filename string
want string
notFound bool // true if the file extension is not found in the map
}{{
filename: "applescript.scpt",
want: "compiled AppleScript",
}, {
filename: "applescript.scptd",
want: "compiled AppleScript",
}, {
filename: "shell.sh",
want: "Shell script",
}, {
filename: "ruby.rb",
want: "Ruby script",
}, {
filename: "python.py",
want: "Python script",
}, {
filename: "perl.pl",
want: "PERL script",
}, {
filename: "yara.yara",
want: "",
}, {
filename: "expect.expect",
want: "Expect script",
}, {
filename: "php.php",
want: "PHP file",
}, {
filename: "html.html",
want: "",
}, {
filename: "javascript.js",
want: "Javascript",
}, {
filename: "typescript.ts",
want: "Typescript",
}, {
filename: "7z.7z",
want: "",
}, {
filename: "json.json",
want: "",
}, {
filename: "yaml.yml",
want: "",
}, {
filename: "yaml.yaml",
want: "",
}, {
filename: "java.java",
want: "Java source",
}, {
filename: "java.jar",
want: "Java program",
}, {
filename: "asm.asm",
want: "",
}, {
filename: "systemd.service",
want: "systemd",
}, {
filename: "crontab.cron",
want: "crontab",
}, {
filename: "crontab.crontab",
want: "crontab",
}, {
filename: "c.c",
want: "C source",
}, {
filename: "juttu.juttu",
notFound: true,
}}
for _, tt := range tests {
t.Run(tt.filename, func(t *testing.T) {
exists, kind := byExtension(tt.filename)
if exists != !tt.notFound {
t.Errorf("byExtension() exists = %v, want %v", exists, !tt.notFound)
}
if kind != tt.want {
t.Errorf("byExtension() kind = %v, want %v", kind, tt.want)
}
})
}
}
Empty file added pkg/action/testdata/empty
Empty file.
1 change: 1 addition & 0 deletions pkg/action/testdata/python
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import sumtin
Binary file added pkg/action/testdata/rando
Binary file not shown.
1 change: 1 addition & 0 deletions pkg/action/testdata/shell
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/bin/sh
1 change: 1 addition & 0 deletions pkg/action/testdata/short
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aa

0 comments on commit ca08337

Please sign in to comment.