@@ -57,10 +57,78 @@ const aliasOfAllRules = "*"
57
57
58
58
var generatedCodePattern = regexp .MustCompile (`^// Code generated .* DO NOT EDIT\.$` )
59
59
60
- // ignoreLocation keeps the location of an ignored rule
61
- type ignoreLocation struct {
62
- file string
63
- line string
60
+ type ignore struct {
61
+ start int
62
+ end int
63
+ suppressions map [string ][]issue.SuppressionInfo
64
+ }
65
+
66
+ type ignores map [string ][]ignore
67
+
68
+ func newIgnores () ignores {
69
+ return make (map [string ][]ignore )
70
+ }
71
+
72
+ func (i ignores ) parseLine (line string ) (int , int ) {
73
+ parts := strings .Split (line , "-" )
74
+ start , err := strconv .Atoi (parts [0 ])
75
+ if err != nil {
76
+ start = 0
77
+ }
78
+ end := start
79
+ if len (parts ) > 1 {
80
+ if e , err := strconv .Atoi (parts [1 ]); err == nil {
81
+ end = e
82
+ }
83
+ }
84
+ return start , end
85
+ }
86
+
87
+ func (i ignores ) add (file string , line string , suppressions map [string ]issue.SuppressionInfo ) {
88
+ is := []ignore {}
89
+ if _ , ok := i [file ]; ok {
90
+ is = i [file ]
91
+ }
92
+ found := false
93
+ start , end := i .parseLine (line )
94
+ for _ , ig := range is {
95
+ if ig .start <= start && ig .end >= end {
96
+ found = true
97
+ for r , s := range suppressions {
98
+ ss , ok := ig .suppressions [r ]
99
+ if ! ok {
100
+ ss = []issue.SuppressionInfo {}
101
+ }
102
+ ss = append (ss , s )
103
+ ig .suppressions [r ] = ss
104
+ }
105
+ break
106
+ }
107
+ }
108
+ if ! found {
109
+ ig := ignore {
110
+ start : start ,
111
+ end : end ,
112
+ suppressions : map [string ][]issue.SuppressionInfo {},
113
+ }
114
+ for r , s := range suppressions {
115
+ ig .suppressions [r ] = []issue.SuppressionInfo {s }
116
+ }
117
+ is = append (is , ig )
118
+ }
119
+ i [file ] = is
120
+ }
121
+
122
+ func (i ignores ) get (file string , line string ) map [string ][]issue.SuppressionInfo {
123
+ start , end := i .parseLine (line )
124
+ if is , ok := i [file ]; ok {
125
+ for _ , i := range is {
126
+ if i .start <= start && i .end >= end {
127
+ return i .suppressions
128
+ }
129
+ }
130
+ }
131
+ return map [string ][]issue.SuppressionInfo {}
64
132
}
65
133
66
134
// The Context is populated with data parsed from the source code as it is scanned.
@@ -75,7 +143,7 @@ type Context struct {
75
143
Root * ast.File
76
144
Imports * ImportTracker
77
145
Config Config
78
- Ignores map [ ignoreLocation ] map [ string ][]issue. SuppressionInfo
146
+ Ignores ignores
79
147
PassedValues map [string ]interface {}
80
148
}
81
149
@@ -318,6 +386,8 @@ func (gosec *Analyzer) CheckRules(pkg *packages.Package) {
318
386
gosec .context .PkgFiles = pkg .Syntax
319
387
gosec .context .Imports = NewImportTracker ()
320
388
gosec .context .PassedValues = make (map [string ]interface {})
389
+ gosec .context .Ignores = newIgnores ()
390
+ gosec .updateIgnores ()
321
391
ast .Walk (gosec , file )
322
392
gosec .stats .NumFiles ++
323
393
gosec .stats .NumLines += pkg .Fset .File (file .Pos ()).LineCount ()
@@ -527,9 +597,6 @@ func (gosec *Analyzer) ignore(n ast.Node) map[string]issue.SuppressionInfo {
527
597
// Visit runs the gosec visitor logic over an AST created by parsing go code.
528
598
// Rule methods added with AddRule will be invoked as necessary.
529
599
func (gosec * Analyzer ) Visit (n ast.Node ) ast.Visitor {
530
- // Update any potentially ignored rules at the node location
531
- gosec .updateIgnoredRules (n )
532
-
533
600
// Using ast.File instead of ast.ImportSpec, so that we can track all imports at once.
534
601
switch i := n .(type ) {
535
602
case * ast.File :
@@ -548,40 +615,33 @@ func (gosec *Analyzer) Visit(n ast.Node) ast.Visitor {
548
615
return gosec
549
616
}
550
617
551
- func (gosec * Analyzer ) updateIgnoredRules (n ast.Node ) {
618
+ func (gosec * Analyzer ) updateIgnores () {
619
+ for n := range gosec .context .Comments {
620
+ gosec .updateIgnoredRulesForNode (n )
621
+ }
622
+ }
623
+
624
+ func (gosec * Analyzer ) updateIgnoredRulesForNode (n ast.Node ) {
552
625
ignoredRules := gosec .ignore (n )
553
626
if len (ignoredRules ) > 0 {
554
627
if gosec .context .Ignores == nil {
555
- gosec .context .Ignores = make ( map [ ignoreLocation ] map [ string ][]issue. SuppressionInfo )
628
+ gosec .context .Ignores = newIgnores ( )
556
629
}
557
630
line := issue .GetLine (gosec .context .FileSet .File (n .Pos ()), n )
558
- ignoreLocation := ignoreLocation {
559
- file : gosec .context .FileSet .File (n .Pos ()).Name (),
560
- line : line ,
561
- }
562
- current , ok := gosec .context .Ignores [ignoreLocation ]
563
- if ! ok {
564
- current = map [string ][]issue.SuppressionInfo {}
565
- }
566
- for r , s := range ignoredRules {
567
- if current [r ] == nil {
568
- current [r ] = []issue.SuppressionInfo {}
569
- }
570
- current [r ] = append (current [r ], s )
571
- }
572
- gosec .context .Ignores [ignoreLocation ] = current
631
+ gosec .context .Ignores .add (
632
+ gosec .context .FileSet .File (n .Pos ()).Name (),
633
+ line ,
634
+ ignoredRules ,
635
+ )
573
636
}
574
637
}
575
638
576
639
func (gosec * Analyzer ) getSuppressionsAtLineInFile (file string , line string , id string ) ([]issue.SuppressionInfo , bool ) {
577
- ignores , ok := gosec .context .Ignores [ignoreLocation {file : file , line : line }]
578
- if ! ok {
579
- ignores = make (map [string ][]issue.SuppressionInfo )
580
- }
640
+ ignoredRules := gosec .context .Ignores .get (file , line )
581
641
582
642
// Check if the rule was specifically suppressed at this location.
583
- generalSuppressions , generalIgnored := ignores [aliasOfAllRules ]
584
- ruleSuppressions , ruleIgnored := ignores [id ]
643
+ generalSuppressions , generalIgnored := ignoredRules [aliasOfAllRules ]
644
+ ruleSuppressions , ruleIgnored := ignoredRules [id ]
585
645
ignored := generalIgnored || ruleIgnored
586
646
suppressions := append (generalSuppressions , ruleSuppressions ... )
587
647
0 commit comments