github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/go/parser/gosecparser.go (about) 1 package parser 2 3 import ( 4 "go/ast" 5 "go/token" 6 ) 7 8 // parseGosecCalls returns the stmt that contain the gosecure keyword. 9 // These are then stored in the File describing the package. 10 // We reload the source which is not efficient, but avoids modifying too much 11 // of the existing code. 12 // This function panics if called on a package that is not main. 13 func parseGosecCalls(fset *token.FileSet, filename string) (m map[string][]string) { 14 bytes, err := readSource(filename, nil) 15 if err != nil { 16 panic(err) 17 } 18 19 var p parser 20 var s []*ast.GosecStmt 21 22 p.init(fset, filename, bytes, ImportsOnly|ParseComments) 23 24 p.expect(token.PACKAGE) 25 ident := p.parseIdent() 26 27 if ident.Name != "main" { 28 p.error(p.pos, "should not parse gosecure calls outside of package main.") 29 return 30 } 31 32 for p.tok != token.EOF { 33 if p.tok == token.GOSEC { 34 a := p.parseGosecStmt().(*ast.GosecStmt) 35 s = append(s, a) 36 } else { 37 p.next() 38 } 39 } 40 41 if len(s) != 0 { 42 m = make(map[string][]string) 43 } 44 45 // Convert to the expected output format. 46 for _, e := range s { 47 switch v := e.Call.Fun.(type) { 48 case *ast.Ident: 49 m["main"] = append(m["main"], v.Name) 50 case *ast.SelectorExpr: 51 n, ok := v.X.(*ast.Ident) 52 if !ok || v.Sel == nil { 53 p.error(v.Pos(), "invalid selector expression for gosecure call.") 54 continue 55 } 56 m[n.Name] = append(m[n.Name], v.Sel.Name) 57 default: 58 p.error(v.Pos(), "Unable to verify the expression type for the gosecure callee.") 59 } 60 } 61 62 return 63 }