@@ -26,8 +26,10 @@ import (
26
26
"path"
27
27
"path/filepath"
28
28
"regexp"
29
+ "runtime" // #nosec
29
30
"sort"
30
31
"strconv"
32
+ "sync"
31
33
32
34
"strings"
33
35
@@ -157,6 +159,69 @@ func (gosec *Analyzer) Process(buildTags []string, packagePaths ...string) error
157
159
return nil
158
160
}
159
161
162
+ var reGeneratedGoFile = regexp .MustCompile (`^// Code generated .* DO NOT EDIT\.` )
163
+
164
+ // filterOutGeneratedGoFiles parallelizes the proocess of checking the contents
165
+ // of the files in fullPaths for the presence of generated Go headers to avoid
166
+ // reporting on generated code, per https://github.com/cosmos/gosec/issues/30
167
+ func filterOutGeneratedGoFiles (fullPaths []string ) (filtered []string ) {
168
+ // position stores the order "pos" which will later be
169
+ // used to sort the paths to maintain original order
170
+ // despite the concurrent filtering that'll take place.
171
+ type position struct {
172
+ pos int
173
+ fullPath string
174
+ }
175
+
176
+ posCh := make (chan * position , 10 )
177
+ go func () {
178
+ defer close (posCh )
179
+ for i , fullPath := range fullPaths {
180
+ posCh <- & position {pos : i , fullPath : fullPath }
181
+ }
182
+ }()
183
+
184
+ filteredCh := make (chan * position , 10 )
185
+ var wg sync.WaitGroup
186
+ // Spin up NumCPU goroutines that'll each open up a file
187
+ // for as long as there is one to be read on posCh.
188
+ for i := 0 ; i < runtime .NumCPU (); i ++ {
189
+ wg .Add (1 )
190
+ go func () {
191
+ defer wg .Done ()
192
+ for pi := range posCh {
193
+ blob , err := os .ReadFile (pi .fullPath )
194
+ if err != nil {
195
+ panic (err )
196
+ }
197
+ if ! reGeneratedGoFile .Match (blob ) {
198
+ filteredCh <- pi
199
+ }
200
+ }
201
+ }()
202
+ }
203
+
204
+ go func () {
205
+ wg .Wait ()
206
+ close (filteredCh )
207
+ }()
208
+
209
+ ordered := make ([]* position , 0 , len (fullPaths ))
210
+ for nonGeneratedGoFilePath := range filteredCh {
211
+ ordered = append (ordered , nonGeneratedGoFilePath )
212
+ }
213
+ sort .Slice (ordered , func (i , j int ) bool {
214
+ oi , oj := ordered [i ], ordered [j ]
215
+ return oi .pos < oj .pos
216
+ })
217
+
218
+ filtered = make ([]string , 0 , len (ordered ))
219
+ for _ , oi := range ordered {
220
+ filtered = append (filtered , oi .fullPath )
221
+ }
222
+ return filtered
223
+ }
224
+
160
225
func (gosec * Analyzer ) load (pkgPath string , conf * packages.Config ) ([]* packages.Package , error ) {
161
226
abspath , err := GetPkgAbsPath (pkgPath )
162
227
if err != nil {
@@ -183,9 +248,9 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
183
248
}
184
249
}
185
250
186
- // step 1/3 create build context.
251
+ // step 1/4 create build context.
187
252
buildD := build .Default
188
- // step 2/3 : add build tags to get env dependent files into basePackage.
253
+ // step 2/4 : add build tags to get env dependent files into basePackage.
189
254
buildD .BuildTags = conf .BuildFlags
190
255
buildD .Dir = absGoModPath
191
256
basePackage , err := buildD .ImportDir (abspath , build .ImportComment )
@@ -197,6 +262,7 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
197
262
for _ , filename := range basePackage .GoFiles {
198
263
packageFiles = append (packageFiles , path .Join (abspath , filename ))
199
264
}
265
+
200
266
for _ , filename := range basePackage .CgoFiles {
201
267
packageFiles = append (packageFiles , path .Join (abspath , filename ))
202
268
}
@@ -210,7 +276,12 @@ func (gosec *Analyzer) load(pkgPath string, conf *packages.Config) ([]*packages.
210
276
}
211
277
}
212
278
213
- // step 3/3 remove build tags from conf to proceed build correctly.
279
+ // step 3/4: now filter out generated go files as we definitely don't
280
+ // want to report on generated code, which is out of our direct control.
281
+ // Please see: https://github.com/cosmos/gosec/issues/30
282
+ packageFiles = filterOutGeneratedGoFiles (packageFiles )
283
+
284
+ // step 4/4: remove build tags from conf to proceed build correctly.
214
285
conf .BuildFlags = nil
215
286
conf .Dir = absGoModPath
216
287
pkgs , err := packages .Load (conf , packageFiles ... )
0 commit comments