Skip to content

Commit

Permalink
feat(dockerfile): Added Ignore lines by comments to Dockerfile #4420
Browse files Browse the repository at this point in the history
Signed-off-by: João Reigota <[email protected]>
  • Loading branch information
joaoReigota1 committed Nov 8, 2021
1 parent f7c6b80 commit 69ccaa6
Show file tree
Hide file tree
Showing 5 changed files with 461 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ var (

var (
// KICSCommentRgxp is the regexp to identify if a comment is a KICS comment
KICSCommentRgxp = regexp.MustCompile(`^((/{2})|#)\s*kics\s*`)
KICSCommentRgxp = regexp.MustCompile(`^((/{2})|#)*\s*kics\s*`)
)

// Version - is the model for the version response
Expand Down
137 changes: 137 additions & 0 deletions pkg/parser/docker/comments.go
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
}
Loading

0 comments on commit 69ccaa6

Please sign in to comment.