Skip to content

Commit

Permalink
ruleguard: pass imports table to gogrep pattern compiler (#343)
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 4538cb2
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 4538cb2

Please sign in to comment.