-
-
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
Conversation
import_tracker.go
Outdated
Imported map[string]string | ||
Aliased map[string]string | ||
// Imported is a map of imports with their associated names/aliases. | ||
Imported map[string][]string | ||
InitOnly map[string]bool |
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.
I should mention that this change is not backward compatible if there's external users of the ImportTracker
type; not sure if there's users, and if that's a concern (if it is, we can probably add back the old fields, and introduce a new field (which could be non-exported); https://grep.app/search?q=%22github.com/securego/gosec/v2
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.
I think is fine, this is not supposed to be used outside of the project. We didn't do a good job to isolate this as internal
.
helpers.go
Outdated
// Deprecated: use GetImportedNames | ||
func GetImportedName(path string, ctx *Context) (string, bool) { |
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.
I deprecated the old ones, but not sure if there's external consumers (if we don't expect there to be, these could be removed).
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.
I think this can be removed, it is not supposed to be used outside of the project.
Alright, this needs some work; have a false positive on package main
import (
"crypto/rand"
mrand "math/rand"
)
func main() {
good, _ := rand.Read(nil)
println(good)
bad := mrand.Int31()
println(bad)
} |
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.
Thanks for working on this. It looks good so far.
helpers.go
Outdated
// Deprecated: use GetImportedNames | ||
func GetImportedName(path string, ctx *Context) (string, bool) { |
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.
I think this can be removed, it is not supposed to be used outside of the project.
import_tracker.go
Outdated
Imported map[string]string | ||
Aliased map[string]string | ||
// Imported is a map of imports with their associated names/aliases. | ||
Imported map[string][]string | ||
InitOnly map[string]bool |
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.
I think is fine, this is not supposed to be used outside of the project. We didn't do a good job to isolate this as internal
.
any update? |
Hi @thaJeztah, Do you still plan to finish this pull request? Thanks |
d52d68c
to
98158f4
Compare
Codecov ReportBase: 73.89% // Head: 74.19% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #865 +/- ##
==========================================
+ Coverage 73.89% 74.19% +0.30%
==========================================
Files 51 51
Lines 3195 3186 -9
==========================================
+ Hits 2361 2364 +3
+ Misses 763 752 -11
+ Partials 71 70 -1
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
import_tracker.go
Outdated
path := strings.Trim(imp.Path.Value, `"`) | ||
parts := strings.Split(path, "/") | ||
if len(parts) > 0 { | ||
name := parts[len(parts)-1] | ||
t.Imported[path] = name | ||
importPath := strings.Trim(imp.Path.Value, `"`) |
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.
This was part of the problem; the old code needed to manually track the file, to get the "un-aliased" import, and then used the ImportTracker.TrackImport to get the aliased versions. But the TrackFile
would ignore aliases.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
Which can be seen here (the file tested has fm
as alias for fmt
, but TrackFile()
doesn't detect that.
gosec.context.Imports.TrackFile(file) | ||
gosec.context.PassedValues = make(map[string]interface{}) | ||
ast.Walk(gosec, file) |
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 both TrackFile()
and ast.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 calling TrackFile
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.
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).
Actually, perhaps it should be the reverse; use TrackFile
once, instead of during Visit()
(we only need it once per file). Could perhaps be as part as Visit()
though.
if !imported { | ||
return "", false | ||
} | ||
|
||
if _, initonly := ctx.Imports.InitOnly[path]; initonly { | ||
return "", false | ||
} |
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.
The initOnly
seemed redundant; all tests seem to pass without it, so I removed it, but maybe there was a reason it was there 😅
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.
lgtm, please could you please rebase it now? Is this still a draft?
Working on some last changes; perhaps it's better after all to handle imports at the File level, otherwise we're calling it for every Node; let me push those changes 👍 |
98158f4
to
61bbb83
Compare
The existing code assumed imports to be either imported, or imported with an alias. Badly formatted files may have duplicate imports for a package, using different aliases. This patch refactors the code, and; Introduces a new `GetImportedNames` function, which returns all name(s) and aliase(s) for a package, which effectively combines `GetAliasedName` and `GetImportedName`, but adding support for duplicate imports. The old `GetAliasedName` and `GetImportedName` functions have been rewritten to use the new function and marked deprecated, but could be removed if there are no external consumers. With this patch, the linter is able to detect issues in files such as; package main import ( crand "crypto/rand" "math/big" "math/rand" rand2 "math/rand" rand3 "math/rand" ) func main() { _, _ = crand.Int(crand.Reader, big.NewInt(int64(2))) // good _ = rand.Intn(2) // bad _ = rand2.Intn(2) // bad _ = rand3.Intn(2) // bad } Before this patch, only a single issue would be detected: gosec --quiet . [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad With this patch, all issues are identified: gosec --quiet . [main.go:16] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 15: _ = rand2.Intn(2) // bad > 16: _ = rand3.Intn(2) // bad 17: } [main.go:15] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 14: _ = rand.Intn(2) // bad > 15: _ = rand2.Intn(2) // bad 16: _ = rand3.Intn(2) // bad [main.go:14] - G404 (CWE-338): Use of weak random number generator (math/rand instead of crypto/rand) (Confidence: MEDIUM, Severity: HIGH) 13: > 14: _ = rand.Intn(2) // bad 15: _ = rand2.Intn(2) // bad While working on this change, I noticed that ImportTracker.TrackFile() was not able to find import aliases; Analyser.Check() called both ImportTracker.TrackFile() and ast.Walk(), which (with the updated ImportTracker) resulted in importes to be in- correctly included multiple times (once with the correct alias, once with the default). I updated ImportTracker.TrackFile() to fix this, but with the updated ImportTracker, Analyser.Check() no longer has to call ImportTracker.TrackFile() separately, as ast.Walk() already handles the file, and will find all imports. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
61bbb83
to
473f548
Compare
@ccojocar should be good now; PTAL 🤗 |
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.
Perfect! Thanks!
YW! Was fun digging a bit into how the ast Parsing works 😄 |
The existing code assumed imports to be either imported, or imported with an
alias. Badly formatted files may have duplicate imports for a package, using
different aliases.
This patch refactors the code, and;
Introduces a new
GetImportedNames
function, which returns all name(s) andaliase(s) for a package, which effectively combines
GetAliasedName
andGetImportedName
, but adding support for duplicate imports.The old
GetAliasedName
andGetImportedName
functions have been rewritten touse the new function and marked deprecated, but could be removed if there are no
external consumers.
With this patch, the linter is able to detect issues in files such as;
Before this patch, only a single issue would be detected:
With this patch, all issues are identified: