Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge experimental / refactor #146

Merged
merged 26 commits into from
Jan 5, 2018
Merged

Merge experimental / refactor #146

merged 26 commits into from
Jan 5, 2018

Conversation

gcmurphy
Copy link
Member

I've had a number of changes that I've been sitting on for a while that I think need to get merged to move forward.

The most notable:

  • gas root repository acts more like a library, with the cmd being moved off to cmd/gas directory.
  • gas will only process valid go packages rather than individual files. This significantly simplifies the file include/exclude file logic as it works as the compiler does. To recursively evaluate packages you can still run: gas $GOPATH/src/github.com/GoASTScanner/gas/... for example. The vendor directory and any test files will be excluded by default.
  • Moved to using ginkgo for writing tests.

There is still much to do but this change is getting too big, and am getting pinged with issues & PR's that won't be relevant under this model.

gcmurphy and others added 19 commits April 25, 2017 16:01
Initial commit to change GAS to process packages rather than standalone
files. This is to address issues with type resolution for external
dependencies.

Uses golang.org/x/tools/go/loader to prepare analyzer input rather than
finding the individual files.
The analyzer now only handles packages rather than one off files. This
simplifies the CLI functionality significantly.
- Get rid of 'core' and move CLI to cmd/gas directory
- Migrate (most) tests to use Ginkgo and testutils framework
- GAS now expects package to reside in $GOPATH
- GAS now can resolve dependencies for better type checking (if package
  on GOPATH)
- Simplified public API
output/formatter: Issue.Line was already a string
cmd/gas/main.go Outdated
}

func loadRules(include, exclude string) rules.RuleList {
filters := make([]rules.RuleFilter, 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably use "var filters []rules.RuleFilter" instead

}
}

func (t *ImportTracker) TrackImport(n ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method ImportTracker.TrackImport should have comment or be unexported

}
}

func (t *ImportTracker) TrackPackages(pkgs ...*types.Package) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method ImportTracker.TrackPackages should have comment or be unexported

InitOnly map[string]bool
}

func NewImportTracker() *ImportTracker {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewImportTracker should have comment or be unexported

"strings"
)

type ImportTracker struct {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported type ImportTracker should have comment or be unexported

rules/tls.go Outdated
@@ -162,12 +169,12 @@ func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node)
}, []ast.Node{(*ast.CompositeLit)(nil)}
}

func NewCompatTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewCompatTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewCompatTlsCheck should have comment or be unexported
func NewCompatTlsCheck should be NewCompatTLSCheck

rules/tls.go Outdated
@@ -136,12 +143,12 @@ func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
}, []ast.Node{(*ast.CompositeLit)(nil)}
}

func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewIntermediateTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewIntermediateTlsCheck should have comment or be unexported
func NewIntermediateTlsCheck should be NewIntermediateTLSCheck

rules/tls.go Outdated
@@ -121,12 +128,12 @@ func (t *InsecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, er
return
}

func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewModernTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewModernTlsCheck should have comment or be unexported
func NewModernTlsCheck should be NewModernTLSCheck

@@ -37,9 +36,10 @@ func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err er
return nil, nil
}

func NewTemplateCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewTemplateCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewTemplateCheck should have comment or be unexported

}

func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
if node := gas.MatchCall(n, t.call); node != nil {
func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method TemplateCheck.Match should have comment or be unexported

cmd/gas/main.go Outdated
}

func loadRules(include, exclude string) rules.RuleList {
filters := make([]rules.RuleFilter, 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably use "var filters []rules.RuleFilter" instead

}
}

func (t *ImportTracker) TrackImport(n ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method ImportTracker.TrackImport should have comment or be unexported

}
}

func (t *ImportTracker) TrackPackages(pkgs ...*types.Package) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method ImportTracker.TrackPackages should have comment or be unexported

InitOnly map[string]bool
}

func NewImportTracker() *ImportTracker {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewImportTracker should have comment or be unexported

"strings"
)

type ImportTracker struct {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported type ImportTracker should have comment or be unexported

rules/tls.go Outdated
@@ -162,12 +169,12 @@ func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node)
}, []ast.Node{(*ast.CompositeLit)(nil)}
}

func NewCompatTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewCompatTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewCompatTlsCheck should have comment or be unexported
func NewCompatTlsCheck should be NewCompatTLSCheck

rules/tls.go Outdated
@@ -136,12 +143,12 @@ func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
}, []ast.Node{(*ast.CompositeLit)(nil)}
}

func NewIntermediateTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewIntermediateTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewIntermediateTlsCheck should have comment or be unexported
func NewIntermediateTlsCheck should be NewIntermediateTLSCheck

rules/tls.go Outdated
@@ -121,12 +128,12 @@ func (t *InsecureConfigTLS) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, er
return
}

func NewModernTlsCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewModernTlsCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewModernTlsCheck should have comment or be unexported
func NewModernTlsCheck should be NewModernTLSCheck

@@ -37,9 +36,10 @@ func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err er
return nil, nil
}

func NewTemplateCheck(conf map[string]interface{}) (gas.Rule, []ast.Node) {
func NewTemplateCheck(conf gas.Config) (gas.Rule, []ast.Node) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported function NewTemplateCheck should have comment or be unexported

}

func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (gi *gas.Issue, err error) {
if node := gas.MatchCall(n, t.call); node != nil {
func (t *TemplateCheck) Match(n ast.Node, c *gas.Context) (*gas.Issue, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method TemplateCheck.Match should have comment or be unexported

Copy link
Member

@ccojocar ccojocar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! I would love to see this merge.

I would like to help you out to complete this. What are the top work items which you would like to get done?

gas.logger.Println("Checking package:", pkg.String())
for _, file := range pkg.Files {
gas.logger.Println("Checking file:", builtPackage.Fset.File(file.Pos()).Name())
gas.context.FileSet = builtPackage.Fset
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice in future to build the context locally instead of providing it into a global shared state. In this way the processing can be done in parallel.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is something that we can look at, although some of the context like type information is relevant between files in a package I think. Parallel processing is something I'd like to work towards.

})

Context("when processing a package", func() {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a test for a package consisting of multiple files.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Done.

cmd/gas/main.go Outdated
flag.PrintDefaults()
fmt.Fprint(os.Stderr, "\n\nRULES:\n\n")

// sorted rule list for eas of reading
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: ease

}

// Load enabled rule definitions
ruleDefinitions := loadRules(*flagRulesInclude, *flagRulesExclude)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all rules included if both flags are empty? If all are included, I would print a info messages here. If all are excluded, I would print an error.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Done.

analyzer := gas.NewAnalyzer(config, logger)
analyzer.LoadRules(ruleDefinitions.Builders()...)

vendor := regexp.MustCompile(`[\\/]vendor([\\/]|$)`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe is worth make it this configurable. I think we can get a list of folders which could be potentially excluded. I would add vendor folder by defualt to this list.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file inclusion / exclusion logic in the past has been a major source of bugs and confusion. The aim here was to basically make gas work as simply as possible.

However I agree it would make sense to be able to configure package directories in the recursive case. Do you think we should fix this as a separate PR or try to sneak it in with change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion the vendor folder exclusion is enough. A more complex logic can be added after the merge.

abspath, _ := filepath.Abs(pkg)
logger.Println("Searching directory:", abspath)
if err := analyzer.Process(pkg); err != nil {
logger.Fatal(err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is worth continuing the processing if only one package fails.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the causes of errors here are:

  1. It is a valid go package but it doesn't compile
  2. It is not a valid go package

I think I was trying to mimic the compiler behaviour here. For the purposes of a mass scan I
could see how this would be useful to continue processing.

However I would typically do something like to scan everything in my workspace:

# (mac osx)
$ cd $GOPATH/src && go list ./... | xargs  -I {} gas $GOPATH/src/{}/...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The workaround is fair enough.

config.go Outdated

// GetGlobal returns value associated with global configuration option
func (c Config) GetGlobal(option string) (string, error) {
if globals, ok := c["global"]; ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would extract this string into a constant.

config.go Outdated

// SetGlobal associates a value with a global configuration ooption
func (c Config) SetGlobal(option, value string) {
if globals, ok := c["global"]; ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same here.


func NewRuleFilter(action bool, ruleIDs ...string) RuleFilter {
rulelist := make(map[string]bool)
for _, rule := range ruleIDs {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would validate if the ruleID is really defined in the list. If not, I will skip it.

Errors int
}

var (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan to add more code samples here to cover all the rules? I am asking this because the tests of each rule were removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is something I need to finish doing. There are also some placeholder tests that I need to get finished also (currently skipping).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!

analyzer.go Outdated
}

packageConfig := loader.Config{Build: &build.Default, ParserMode: parser.ParseComments}
packageFiles := make([]string, 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can probably use "var packageFiles []string" instead

}
}`, 1}}

// SampleCode502 - Blacklisted import DES

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported var SampleCodeG502 should be of the form "SampleCodeG502 ..."

println(i)
}`, 0}}

// SampleCode501 - Blacklisted import MD5

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported var SampleCodeG501 should be of the form "SampleCodeG501 ..."

The tests are running extremely slow at the moment, and these extra
options add to the problem.
@@ -2,13 +2,13 @@ package gas_test

import (
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ben hiç bir şey anlamadım işe geç kalacağım yardım

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yardım edin biraz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants