-
Notifications
You must be signed in to change notification settings - Fork 316
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dockerfile): Added Ignore lines by comments to Dockerfile #4420
Signed-off-by: João Reigota <[email protected]>
- Loading branch information
1 parent
f7c6b80
commit 69ccaa6
Showing
5 changed files
with
461 additions
and
1 deletion.
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
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,137 @@ | ||
package docker | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/Checkmarx/kics/pkg/model" | ||
"github.com/moby/buildkit/frontend/dockerfile/parser" | ||
) | ||
|
||
// ignoreLine is a structure that contains information if the line/multi-line should be ignored. | ||
type ignoreLine struct { | ||
shouldIgnore bool | ||
shouldIgnoreBlock bool | ||
line []int | ||
} | ||
|
||
// ignore is a structure that contains information about the lines that are being ignored. | ||
type ignore struct { | ||
from map[string][]int | ||
lines []int | ||
} | ||
|
||
// newIgnore returns a new ignore struct. | ||
func newIgnore() *ignore { | ||
return &ignore{ | ||
from: make(map[string][]int), | ||
lines: make([]int, 0), | ||
} | ||
} | ||
|
||
// setIgnore adds a new entry to the ignore struct for the 'FROM' block to be ignored | ||
func (i *ignore) setIgnore(from string, shouldIgnoreBlock bool) { | ||
if !shouldIgnoreBlock { | ||
return | ||
} | ||
i.from[from] = make([]int, 0) | ||
} | ||
|
||
// ignoreLine adds lines to be ignored to the ignore struct. | ||
func (i *ignore) ignoreLine(lines []int) { | ||
i.lines = append(i.lines, lines...) | ||
} | ||
|
||
// ignoreBlock adds block lines to be ignored to the ignore struct. | ||
func (i *ignore) ignoreBlock(node *parser.Node, from string) { | ||
if _, ok := i.from[from]; ok { | ||
i.from[from] = append(i.from[from], commentRange(node.StartLine, node.EndLine)...) | ||
} | ||
} | ||
|
||
// getIgnoreLines returns the lines that are being ignored. | ||
func (i *ignore) getIgnoreLines() []int { | ||
for _, value := range i.from { | ||
i.lines = append(i.lines, value...) | ||
} | ||
return removeDups(i.lines) | ||
} | ||
|
||
// removeDups removes duplicates from a slice of ints. | ||
func removeDups(lines []int) []int { | ||
seen := make(map[int]bool) | ||
var result []int | ||
for _, line := range lines { | ||
if !seen[line] { | ||
result = append(result, line) | ||
seen[line] = true | ||
} | ||
} | ||
return result | ||
} | ||
|
||
// getIgnoreComments returns lines to be ignored for each node of the dockerfile | ||
func getIgnoreComments(node *parser.Node) (ignore ignoreLine) { | ||
if len(node.PrevComment) == 0 { | ||
return ignoreLine{ | ||
shouldIgnore: false, | ||
} | ||
} | ||
|
||
ignore = ignoreLine{ | ||
shouldIgnore: true, | ||
shouldIgnoreBlock: false, | ||
line: make([]int, 0), | ||
} | ||
|
||
for idx, comment := range node.PrevComment { | ||
switch processComment(comment) { | ||
case model.IgnoreLine: | ||
ignore.line = append(ignore.line, commentRange(node.StartLine-(idx+1), node.EndLine)...) | ||
case model.IgnoreBlock: | ||
ignore.line = append(ignore.line, node.StartLine-(idx+1)) | ||
ignore.shouldIgnoreBlock = true | ||
default: | ||
ignore.line = append(ignore.line, node.StartLine-(idx+1)) | ||
} | ||
} | ||
|
||
return | ||
} | ||
|
||
// processComment returns the type of comment given. | ||
func processComment(comment string) (value model.CommentCommand) { | ||
commentLower := strings.ToLower(comment) | ||
|
||
if model.KICSCommentRgxp.MatchString(commentLower) { | ||
commentLower = model.KICSCommentRgxp.ReplaceAllString(commentLower, "") | ||
commands := strings.Split(strings.Trim(commentLower, "\n"), " ") | ||
value = processCommands(commands) | ||
return | ||
} | ||
return model.CommentCommand(comment) | ||
} | ||
|
||
// processCommands goes over kics commands in a line and returns the type of command given | ||
func processCommands(commands []string) model.CommentCommand { | ||
for _, command := range commands { | ||
switch com := model.CommentCommand(command); com { | ||
case model.IgnoreLine: | ||
return model.IgnoreLine | ||
case model.IgnoreBlock: | ||
return model.IgnoreBlock | ||
default: | ||
continue | ||
} | ||
} | ||
|
||
return model.CommentCommand(commands[0]) | ||
} | ||
|
||
// commentRange returns the range of the comment between the start and end lines. | ||
func commentRange(start, end int) (lines []int) { | ||
lines = make([]int, end-start+1) | ||
for i := range lines { | ||
lines[i] = start + i | ||
} | ||
return | ||
} |
Oops, something went wrong.