-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lint: detect captured loop var in go/defer statement (#4202)
Detect loop variable captured by function in go or defer statement. The loop variable is reassigned when stepping in the loop, and so by the time the go routine is run, the value may have changed. Fix the single occurrence of the pattern. Update semgrep, as the rules did not appear to work as expected with the older version. With this newer version, we now need an (empty) .semgrepignore file, as by default semgrep ignores all _test.go files, which seems undesirable. The docker command for semgrep is also changed to explicitly invoke `semgrep`, as directed by a deprecation warning. fixes #2164.
- Loading branch information
Showing
4 changed files
with
50 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Empty .semgrepignore; the default one skips all _test.go. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
rules: | ||
- id: loopvar_capture | ||
patterns: | ||
- pattern-either: | ||
- pattern-inside: | | ||
for $X := ...; ...; <... $X ...> { ... } | ||
- pattern-inside: | | ||
for $X := range $SLICE { ... } | ||
- pattern-inside: | | ||
for $X, ... := range $SLICE { ... } | ||
- pattern-inside: | | ||
for ..., $X := range $SLICE { ... } | ||
- pattern-either: | ||
- pattern: | | ||
go func(...){ ...; <... $X ...>; ... }(...) | ||
- pattern: | | ||
defer func(...){ ...; <... $X ...>; ... }(...) | ||
- pattern: | | ||
$ERRGROUP.Go(func() error { ...; <... $X ...>; ...}) | ||
# These additional patterns are a workaround to exclude certain false | ||
# positives, which appear to be caused by semgrep not fully handling | ||
# multi-variable assignment. | ||
# These two patterns exclude this case: | ||
# for i, x := range values { | ||
# i, x := i, x | ||
# go func() { fmt.Println(i,x) }() | ||
# } | ||
- pattern-not-inside: | | ||
for ... { $X, ... := $X, ...; ... } | ||
- pattern-not-inside: | | ||
for ... { ..., $X := ..., $X; ... } | ||
# This pattern excludes odd matches of the _ variable, | ||
# for example | ||
# for _, x := range values { | ||
# go func() { v, _ := foo() }() | ||
# } | ||
- metavariable-pattern: | ||
metavariable: $X | ||
patterns: | ||
- pattern-not: _ | ||
message: | | ||
Captured loop variable `$X` in go or defer statement | ||
severity: WARNING | ||
languages: | ||
- go |