Address unhandled error conditions

Closes #95
This commit is contained in:
Grant Murphy 2016-12-02 10:20:23 -08:00
parent 8f78248b61
commit 6ace60b950
8 changed files with 69 additions and 10 deletions

View file

@ -23,6 +23,7 @@ import (
"go/types" "go/types"
"log" "log"
"os" "os"
"path"
"reflect" "reflect"
"strings" "strings"
) )
@ -222,8 +223,9 @@ func (gas *Analyzer) Visit(n ast.Node) ast.Visitor {
for _, rule := range val { for _, rule := range val {
ret, err := rule.Match(n, &gas.context) ret, err := rule.Match(n, &gas.context)
if err != nil { if err != nil {
// will want to give more info than this ... file, line := GetLocation(n, &gas.context)
gas.logger.Println("internal error running rule:", err) file = path.Base(file)
gas.logger.Printf("Rule error: %v => %s (%s:%d)\n", reflect.TypeOf(rule), err, file, line)
} }
if ret != nil { if ret != nil {
gas.Issues = append(gas.Issues, *ret) gas.Issues = append(gas.Issues, *ret)

View file

@ -212,3 +212,9 @@ func GetImportPath(name string, ctx *Context) (string, bool) {
} }
return "", false return "", false
} }
// GetLocation returns the filename and line number of an ast.Node
func GetLocation(n ast.Node, ctx *Context) (string, int) {
fobj := ctx.FileSet.File(n.Pos())
return fobj.Name(), fobj.Line(n.Pos())
}

View file

@ -15,6 +15,8 @@
package main package main
import ( import (
"fmt"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
) )
@ -32,7 +34,10 @@ func newFileList(paths ...string) *filelist {
} }
for _, path := range paths { for _, path := range paths {
f.Set(path) if e := f.Set(path); e != nil {
// #nosec
fmt.Fprintf(os.Stderr, "Unable to add %s to filelist: %s\n", path, e)
}
} }
return f return f
} }

View file

@ -117,7 +117,9 @@ func buildConfig(incRules string, excRules string) map[string]interface{} {
return config return config
} }
// #nosec
func usage() { func usage() {
fmt.Fprintln(os.Stderr, usageText) fmt.Fprintln(os.Stderr, usageText)
fmt.Fprint(os.Stderr, "OPTIONS:\n\n") fmt.Fprint(os.Stderr, "OPTIONS:\n\n")
flag.PrintDefaults() flag.PrintDefaults()

View file

@ -36,7 +36,11 @@ func getConfiguredMode(conf map[string]interface{}, configKey string, defaultMod
case int64: case int64:
mode = value.(int64) mode = value.(int64)
case string: case string:
mode, _ = strconv.ParseInt(value.(string), 0, 64) if m, e := strconv.ParseInt(value.(string), 0, 64); e != nil {
mode = defaultMode
} else {
mode = m
}
} }
} }
return mode return mode

View file

@ -42,7 +42,7 @@ func (s *SqlStrConcat) checkObject(n *ast.Ident) bool {
func (s *SqlStrConcat) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) { func (s *SqlStrConcat) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {
if node, ok := n.(*ast.BinaryExpr); ok { if node, ok := n.(*ast.BinaryExpr); ok {
if start, ok := node.X.(*ast.BasicLit); ok { if start, ok := node.X.(*ast.BasicLit); ok {
if str, _ := gas.GetString(start); s.pattern.MatchString(str) { if str, e := gas.GetString(start); s.pattern.MatchString(str) && e == nil {
if _, ok := node.Y.(*ast.BasicLit); ok { if _, ok := node.Y.(*ast.BasicLit); ok {
return nil, nil // string cat OK return nil, nil // string cat OK
} }
@ -77,7 +77,7 @@ type SqlStrFormat struct {
// Looks for "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)" // Looks for "fmt.Sprintf("SELECT * FROM foo where '%s', userInput)"
func (s *SqlStrFormat) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { func (s *SqlStrFormat) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
if node := gas.MatchCall(n, s.call); node != nil { if node := gas.MatchCall(n, s.call); node != nil {
if arg, _ := gas.GetString(node.Args[0]); s.pattern.MatchString(arg) { if arg, e := gas.GetString(node.Args[0]); s.pattern.MatchString(arg) && e == nil {
return gas.NewIssue(c, n, s.What, s.Severity, s.Confidence), nil return gas.NewIssue(c, n, s.What, s.Severity, s.Confidence), nil
} }
} }

View file

@ -29,7 +29,7 @@ type BadTempFile struct {
func (t *BadTempFile) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) { func (t *BadTempFile) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
if node := gas.MatchCall(n, t.call); node != nil { if node := gas.MatchCall(n, t.call); node != nil {
if arg, _ := gas.GetString(node.Args[0]); t.args.MatchString(arg) { if arg, e := gas.GetString(node.Args[0]); t.args.MatchString(arg) && e == nil {
return gas.NewIssue(c, n, t.What, t.Severity, t.Confidence), nil return gas.NewIssue(c, n, t.What, t.Severity, t.Confidence), nil
} }
} }

View file

@ -74,10 +74,12 @@ func (u *utilities) run(args ...string) {
func shouldSkip(path string) bool { func shouldSkip(path string) bool {
st, e := os.Stat(path) st, e := os.Stat(path)
if e != nil { if e != nil {
// #nosec
fmt.Fprintf(os.Stderr, "Skipping: %s - %s\n", path, e) fmt.Fprintf(os.Stderr, "Skipping: %s - %s\n", path, e)
return true return true
} }
if st.IsDir() { if st.IsDir() {
// #nosec
fmt.Fprintf(os.Stderr, "Skipping: %s - directory\n", path) fmt.Fprintf(os.Stderr, "Skipping: %s - directory\n", path)
return true return true
} }
@ -95,11 +97,12 @@ func dumpAst(files ...string) {
fset := token.NewFileSet() // positions are relative to fset fset := token.NewFileSet() // positions are relative to fset
f, err := parser.ParseFile(fset, arg, nil, 0) f, err := parser.ParseFile(fset, arg, nil, 0)
if err != nil { if err != nil {
// #nosec
fmt.Fprintf(os.Stderr, "Unable to parse file %s\n", err) fmt.Fprintf(os.Stderr, "Unable to parse file %s\n", err)
continue continue
} }
// Print the AST. // Print the AST. #nosec
ast.Print(fset, f) ast.Print(fset, f)
} }
} }
@ -115,7 +118,12 @@ type context struct {
func createContext(filename string) *context { func createContext(filename string) *context {
fileset := token.NewFileSet() fileset := token.NewFileSet()
root, _ := parser.ParseFile(fileset, filename, nil, parser.ParseComments) root, e := parser.ParseFile(fileset, filename, nil, parser.ParseComments)
if e != nil {
// #nosec
fmt.Fprintf(os.Stderr, "Unable to parse file: %s. Reason: %s\n", filename, e)
return nil
}
comments := ast.NewCommentMap(fileset, root, root.Comments) comments := ast.NewCommentMap(fileset, root, root.Comments)
info := &types.Info{ info := &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue), Types: make(map[ast.Expr]types.TypeAndValue),
@ -126,7 +134,12 @@ func createContext(filename string) *context {
Implicits: make(map[ast.Node]types.Object), Implicits: make(map[ast.Node]types.Object),
} }
config := types.Config{Importer: importer.Default()} config := types.Config{Importer: importer.Default()}
pkg, _ := config.Check("main.go", fileset, []*ast.File{root}, info) pkg, e := config.Check("main.go", fileset, []*ast.File{root}, info)
if e != nil {
// #nosec
fmt.Fprintf(os.Stderr, "Type check failed for file: %s. Reason: %s\n", filename, e)
return nil
}
return &context{fileset, comments, info, pkg, &config, root} return &context{fileset, comments, info, pkg, &config, root}
} }
@ -147,6 +160,15 @@ func printObject(obj types.Object) {
fmt.Printf(" Id = %v\n", obj.Id()) fmt.Printf(" Id = %v\n", obj.Id())
} }
func checkContext(ctx *context, file string) bool {
// #nosec
if ctx == nil {
fmt.Fprintln(os.Stderr, "Failed to create context for file: ", file)
return false
}
return true
}
func dumpCallObj(files ...string) { func dumpCallObj(files ...string) {
for _, file := range files { for _, file := range files {
@ -154,6 +176,9 @@ func dumpCallObj(files ...string) {
continue continue
} }
context := createContext(file) context := createContext(file)
if !checkContext(context, file) {
return
}
ast.Inspect(context.root, func(n ast.Node) bool { ast.Inspect(context.root, func(n ast.Node) bool {
var obj types.Object var obj types.Object
switch node := n.(type) { switch node := n.(type) {
@ -178,6 +203,9 @@ func dumpUses(files ...string) {
continue continue
} }
context := createContext(file) context := createContext(file)
if !checkContext(context, file) {
return
}
for ident, obj := range context.info.Uses { for ident, obj := range context.info.Uses {
fmt.Printf("IDENT: %v, OBJECT: %v\n", ident, obj) fmt.Printf("IDENT: %v, OBJECT: %v\n", ident, obj)
} }
@ -190,6 +218,9 @@ func dumpTypes(files ...string) {
continue continue
} }
context := createContext(file) context := createContext(file)
if !checkContext(context, file) {
return
}
for expr, tv := range context.info.Types { for expr, tv := range context.info.Types {
fmt.Printf("EXPR: %v, TYPE: %v\n", expr, tv) fmt.Printf("EXPR: %v, TYPE: %v\n", expr, tv)
} }
@ -202,6 +233,9 @@ func dumpDefs(files ...string) {
continue continue
} }
context := createContext(file) context := createContext(file)
if !checkContext(context, file) {
return
}
for ident, obj := range context.info.Defs { for ident, obj := range context.info.Defs {
fmt.Printf("IDENT: %v, OBJ: %v\n", ident, obj) fmt.Printf("IDENT: %v, OBJ: %v\n", ident, obj)
} }
@ -214,6 +248,9 @@ func dumpComments(files ...string) {
continue continue
} }
context := createContext(file) context := createContext(file)
if !checkContext(context, file) {
return
}
for _, group := range context.comments.Comments() { for _, group := range context.comments.Comments() {
fmt.Println(group.Text()) fmt.Println(group.Text())
} }
@ -226,6 +263,9 @@ func dumpImports(files ...string) {
continue continue
} }
context := createContext(file) context := createContext(file)
if !checkContext(context, file) {
return
}
for _, pkg := range context.pkg.Imports() { for _, pkg := range context.pkg.Imports() {
fmt.Println(pkg.Path(), pkg.Name()) fmt.Println(pkg.Path(), pkg.Name())
for _, name := range pkg.Scope().Names() { for _, name := range pkg.Scope().Names() {