Skip to content

Commit

Permalink
ruleguard: pass imports table to gogrep pattern compiler
Browse files Browse the repository at this point in the history
This avoids any miscompiled patterns as well as allows
more precise matching of package symbols in function call contexts.
  • Loading branch information
quasilyte committed Jan 3, 2022
1 parent 6b5664f commit 9815083
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 5 deletions.
1 change: 1 addition & 0 deletions analyzer/analyzer_test.go
Expand Up @@ -45,6 +45,7 @@ var tests = []struct {
{name: "uber"},
{name: "localfunc"},
{name: "goversion", flags: map[string]string{"go": "1.16"}},
{name: "imports"},
}

func TestDirectiveComments(t *testing.T) {
Expand Down
27 changes: 27 additions & 0 deletions analyzer/testdata/src/imports/f1.go
@@ -0,0 +1,27 @@
package imports

import (
crand "crypto/rand"
"math/rand"
)

func _() {
_, _ = crand.Read(nil) // want `\Qcrypto/rand`
_, _ = rand.Read(nil) // want `\Qmath/rand`
}

func _() {
_, _ = rand.Read(nil) // want `\Qmath/rand`
_, _ = crand.Read(nil) // want `\Qcrypto/rand`
}

func _() {
var rand distraction
_, _ = rand.Read(nil)
}

type distraction struct{}

func (distraction) Read(p []byte) (int, error) {
return 0, nil
}
17 changes: 17 additions & 0 deletions analyzer/testdata/src/imports/rules.go
@@ -0,0 +1,17 @@
//go:build ignore
// +build ignore

package gorules

import (
"github.com/quasilyte/go-ruleguard/dsl"
)

func testMathRand(m dsl.Matcher) {
m.Match(`rand.Read($*_)`).Report(`math/rand`)
}

func testCryptoRand(m dsl.Matcher) {
m.Import(`crypto/rand`)
m.Match(`rand.Read($*_)`).Report(`crypto/rand`)
}
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -7,6 +7,6 @@ require (
github.com/google/go-cmp v0.5.6
github.com/quasilyte/go-ruleguard/dsl v0.3.12-0.20220101150716-969a394a9451
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71
github.com/quasilyte/gogrep v0.0.0-20211226113550-e12a97c7d96d
github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3
golang.org/x/tools v0.0.0-20201230224404-63754364767c
)
4 changes: 4 additions & 0 deletions go.sum
Expand Up @@ -23,6 +23,10 @@ github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 h1:CN
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=
github.com/quasilyte/gogrep v0.0.0-20211226113550-e12a97c7d96d h1:HUyLC9v8wzT8PBFdZjGehLLNSPzQMXDsbREsMHxwma8=
github.com/quasilyte/gogrep v0.0.0-20211226113550-e12a97c7d96d/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM=
github.com/quasilyte/gogrep v0.0.0-20220103102714-b302ec19c4fe h1:4QqQfYkJRjKR94aebELDiHFj/f+5lFKtQTVOt7luT20=
github.com/quasilyte/gogrep v0.0.0-20220103102714-b302ec19c4fe/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM=
github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3 h1:P4QPNn+TK49zJjXKERt/vyPbv/mCHB/zQ4flDYOMN+M=
github.com/quasilyte/gogrep v0.0.0-20220103110004-ffaa07af02e3/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down
17 changes: 13 additions & 4 deletions ruleguard/ir_loader.go
Expand Up @@ -253,15 +253,15 @@ func (l *irLoader) loadRuleGroup(group *ir.RuleGroup) error {
}

for _, rule := range group.Rules {
if err := l.loadRule(rule); err != nil {
if err := l.loadRule(group, rule); err != nil {
return err
}
}

return nil
}

func (l *irLoader) loadRule(rule ir.Rule) error {
func (l *irLoader) loadRule(group *ir.RuleGroup, rule ir.Rule) error {
proto := goRule{
line: rule.Line,
group: l.group,
Expand All @@ -282,7 +282,7 @@ func (l *irLoader) loadRule(rule ir.Rule) error {
}

for _, pat := range rule.SyntaxPatterns {
if err := l.loadSyntaxRule(proto, info, rule, pat.Value, pat.Line); err != nil {
if err := l.loadSyntaxRule(group, proto, info, rule, pat.Value, pat.Line); err != nil {
return err
}
}
Expand Down Expand Up @@ -312,15 +312,24 @@ func (l *irLoader) loadCommentRule(resultProto goRule, rule ir.Rule, src string,
return nil
}

func (l *irLoader) loadSyntaxRule(resultProto goRule, filterInfo filterInfo, rule ir.Rule, src string, line int) error {
func (l *irLoader) loadSyntaxRule(group *ir.RuleGroup, resultProto goRule, filterInfo filterInfo, rule ir.Rule, src string, line int) error {
result := resultProto
result.line = line

var imports map[string]string
if len(group.Imports) != 0 {
imports = make(map[string]string)
for _, imported := range group.Imports {
imports[imported.Name] = imported.Path
}
}

gogrepConfig := gogrep.CompileConfig{
Fset: l.gogrepFset,
Src: src,
Strict: false,
WithTypes: true,
Imports: imports,
}
pat, info, err := gogrep.Compile(gogrepConfig)
if err != nil {
Expand Down

0 comments on commit 9815083

Please sign in to comment.