-
-
Notifications
You must be signed in to change notification settings - Fork 621
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
Refactor to support duplicate imports with different aliases #865
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,20 +37,20 @@ import ( | |
// | ||
// node, matched := MatchCallByPackage(n, ctx, "math/rand", "Read") | ||
func MatchCallByPackage(n ast.Node, c *Context, pkg string, names ...string) (*ast.CallExpr, bool) { | ||
importedName, found := GetAliasedName(pkg, c) | ||
importedNames, found := GetImportedNames(pkg, c) | ||
if !found { | ||
importedName, found = GetImportedName(pkg, c) | ||
if !found { | ||
return nil, false | ||
} | ||
return nil, false | ||
} | ||
|
||
if callExpr, ok := n.(*ast.CallExpr); ok { | ||
packageName, callName, err := GetCallInfo(callExpr, c) | ||
if err != nil { | ||
return nil, false | ||
} | ||
if packageName == importedName { | ||
for _, in := range importedNames { | ||
if packageName != in { | ||
continue | ||
} | ||
for _, name := range names { | ||
if callName == name { | ||
return callExpr, true | ||
|
@@ -247,48 +247,23 @@ func GetBinaryExprOperands(be *ast.BinaryExpr) []ast.Node { | |
return result | ||
} | ||
|
||
// GetImportedName returns the name used for the package within the | ||
// code. It will ignore initialization only imports. | ||
func GetImportedName(path string, ctx *Context) (string, bool) { | ||
importName, imported := ctx.Imports.Imported[path] | ||
if !imported { | ||
return "", false | ||
} | ||
|
||
if _, initonly := ctx.Imports.InitOnly[path]; initonly { | ||
return "", false | ||
} | ||
|
||
return importName, true | ||
} | ||
|
||
// GetAliasedName returns the aliased name used for the package within the | ||
// code. It will ignore initialization only imports. | ||
func GetAliasedName(path string, ctx *Context) (string, bool) { | ||
importName, imported := ctx.Imports.Aliased[path] | ||
if !imported { | ||
return "", false | ||
} | ||
|
||
if _, initonly := ctx.Imports.InitOnly[path]; initonly { | ||
return "", false | ||
} | ||
Comment on lines
-269
to
-275
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
return importName, true | ||
// GetImportedNames returns the name(s)/alias(es) used for the package within | ||
// the code. It ignores initialization-only imports. | ||
func GetImportedNames(path string, ctx *Context) (names []string, found bool) { | ||
importNames, imported := ctx.Imports.Imported[path] | ||
return importNames, imported | ||
} | ||
|
||
// GetImportPath resolves the full import path of an identifier based on | ||
// the imports in the current context(including aliases). | ||
func GetImportPath(name string, ctx *Context) (string, bool) { | ||
for path := range ctx.Imports.Imported { | ||
if imported, ok := GetImportedName(path, ctx); ok && imported == name { | ||
return path, true | ||
} | ||
} | ||
|
||
for path := range ctx.Imports.Aliased { | ||
if imported, ok := GetAliasedName(path, ctx); ok && imported == name { | ||
return path, true | ||
if imported, ok := GetImportedNames(path, ctx); ok { | ||
for _, n := range imported { | ||
if n == name { | ||
return path, true | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,7 @@ var _ = Describe("Import Tracker", func() { | |
files := pkgs[0].Syntax | ||
Expect(files).Should(HaveLen(1)) | ||
tracker.TrackFile(files[0]) | ||
Expect(tracker.Imported).Should(Equal(map[string]string{"fmt": "fmt"})) | ||
Expect(tracker.Imported).Should(Equal(map[string][]string{"fmt": {"fmt"}})) | ||
}) | ||
It("should parse the named imports from file", func() { | ||
tracker := gosec.NewImportTracker() | ||
|
@@ -47,7 +47,7 @@ var _ = Describe("Import Tracker", func() { | |
files := pkgs[0].Syntax | ||
Expect(files).Should(HaveLen(1)) | ||
tracker.TrackFile(files[0]) | ||
Expect(tracker.Imported).Should(Equal(map[string]string{"fmt": "fmt"})) | ||
Expect(tracker.Imported).Should(Equal(map[string][]string{"fmt": {"fm"}})) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which can be seen here (the file tested has |
||
}) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and because
Analyzer.Check()
called bothTrackFile()
andast.Walk()
, the incorrect import name would be added (so a non-aliased import would be added, even though the package used an alias), which broke detection.With the new code,
CheckImports()
finds both, so callingTrackFile
is no longer needed.I wasn't sure if that function could be removed altogether (it's slightly easier to use than starting an Analyzer, so perhaps it's useful as a utility still).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, perhaps it should be the reverse; use
TrackFile
once, instead of duringVisit()
(we only need it once per file). Could perhaps be as part asVisit()
though.