From 539b6c51b9909bca462df0a86fa5c2fdc0d21ab6 Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Fri, 7 Apr 2023 14:05:39 +0300 Subject: [PATCH] Add unit testcase Signed-off-by: Hollow Man --- .../printer/v2/sarifprinter.go | 97 +++++++++++------- .../printer/v2/sarifprinter_test.go | 98 ++++++++++++++++++- 2 files changed, 156 insertions(+), 39 deletions(-) diff --git a/core/pkg/resultshandling/printer/v2/sarifprinter.go b/core/pkg/resultshandling/printer/v2/sarifprinter.go index f39b4e6d..934713f7 100644 --- a/core/pkg/resultshandling/printer/v2/sarifprinter.go +++ b/core/pkg/resultshandling/printer/v2/sarifprinter.go @@ -210,6 +210,64 @@ func addFix(result *sarif.Result, filepath string, startLine int, startColumn in ) } +func calculateMove(str string, file []string, endColumn int, endLine int) (int, int, bool) { + num, err := strconv.Atoi(str) + if err != nil { + logger.L().Debug("failed to get move from string "+str, helpers.Error(err)) + return 0, 0, false + } + for num+endColumn-1 > len(file[endLine-1]) { + num -= len(file[endLine-1]) - endColumn + 2 + endLine++ + endColumn = 1 + } + endColumn += num + return endLine, endColumn, true +} + +func collectDiffs(dmp *diffmatchpatch.DiffMatchPatch, diffs []diffmatchpatch.Diff, result *sarif.Result, filepath string, fileAsString string) { + file := strings.Split(fileAsString, "\n") + text := "" + startLine := 1 + startColumn := 1 + endLine := 1 + endColumn := 1 + + delta := strings.Split(dmp.DiffToDelta(diffs), "\t") + for index, seg := range delta { + switch seg[0] { + case '+': + var err error + text, err = url.QueryUnescape(seg[1:]) + if err != nil { + logger.L().Debug("failed to unescape string", helpers.Error(err)) + continue + } + if index >= len(delta)-1 || delta[index+1][0] == '=' { + addFix(result, filepath, startLine, startColumn, endLine, endColumn, text) + } + case '-': + var ok bool + endLine, endColumn, ok = calculateMove(seg[1:], file, endColumn, endLine) + if !ok { + continue + } + if index >= len(delta)-1 || delta[index+1][0] == '=' { + addFix(result, filepath, startLine, startColumn, endLine, endColumn, text) + } + case '=': + var ok bool + endLine, endColumn, ok = calculateMove(seg[1:], file, endColumn, endLine) + if !ok { + continue + } + startLine = endLine + startColumn = endColumn + text = "" + } + } +} + func collectFixes(ctx context.Context, result *sarif.Result, ac resourcesresults.ResourceAssociatedControl, opaSessionObj *cautils.OPASessionObj, resourceID string, filepath string) { for _, rule := range ac.ResourceAssociatedRules { if !rule.GetStatus(nil).IsFailed() { @@ -244,44 +302,7 @@ func collectFixes(ctx context.Context, result *sarif.Result, ac resourcesresults dmp := diffmatchpatch.New() diffs := dmp.DiffMain(fileAsString, fixedYamlString, false) - - file := strings.Split(fileAsString, "\n") - text := "" - startLine := 1 - startColumn := 1 - endLine := 1 - endColumn := 1 - - delta := strings.Split(dmp.DiffToDelta(diffs), "\t") - for index, seg := range delta { - switch seg[0] { - case '+': - text, _ = url.QueryUnescape(seg[1:]) - if index >= len(delta)-1 || delta[index+1][0] == '=' { - addFix(result, filepath, startLine, startColumn, endLine, endColumn, text) - } - case '-': - num, _ := strconv.Atoi(seg[1:]) - for num > len(file[endLine-1]) { - num -= len(file[endLine-1]) + 1 - endLine++ - } - endColumn = num + 1 - if index >= len(delta)-1 || delta[index+1][0] == '=' { - addFix(result, filepath, startLine, startColumn, endLine, endColumn, text) - } - case '=': - num, _ := strconv.Atoi(seg[1:]) - for num > len(file[startLine-1]) { - num -= len(file[startLine-1]) + 1 - startLine++ - } - startColumn = num + 1 - endLine = startLine - endColumn = startColumn - text = "" - } - } + collectDiffs(dmp, diffs, result, filepath, fileAsString) } } } diff --git a/core/pkg/resultshandling/printer/v2/sarifprinter_test.go b/core/pkg/resultshandling/printer/v2/sarifprinter_test.go index 40986fce..d390177a 100644 --- a/core/pkg/resultshandling/printer/v2/sarifprinter_test.go +++ b/core/pkg/resultshandling/printer/v2/sarifprinter_test.go @@ -1,6 +1,11 @@ package printer -import "testing" +import ( + "testing" + + "github.com/owenrumney/go-sarif/v2/sarif" + "github.com/sergi/go-diff/diffmatchpatch" +) func Test_scoreToSeverityLevel(t *testing.T) { tc := []struct { @@ -25,3 +30,94 @@ func Test_scoreToSeverityLevel(t *testing.T) { }) } } + +func Test_collectDiffs(t *testing.T) { + tc := []struct { + Name string + fileString string + fixedString string + fixesNum int + region [][4]int + text []string + }{ + { + "Collect Diffs should work for add, delete and equal", + + `apiVersion: v1 +kind: Pod +metadata: + name: test + +spec: + containers: + - name: nginx_container + image: nginx + securityContext: + capabilities: + drop: [NET_RAW] + runAsRoot: true`, + + `apiVersion: v1 +kind: Pod +metadata: + name: test + +spec: + containers: + - name: nginx_container + image: nginx + securityContext: + capabilities: + drop: [NET_RAW, SYS_ADM] + runAsRoot: false + allowPrivilegeEscalation: false`, + 3, + [][4]int{ + {12, 23, 12, 23}, + {13, 18, 13, 19}, + {13, 20, 13, 21}, + }, + []string{ + ", SYS_ADM", + `false + allowP`, + "ivilegeEscalation: fals", + }, + }, + } + + for _, testCase := range tc { + t.Run(testCase.Name, func(t *testing.T) { + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(testCase.fileString, testCase.fixedString, false) + run := sarif.NewRunWithInformationURI(toolName, toolInfoURI) + result := run.CreateResultForRule("0") + collectDiffs(dmp, diffs, result, "", testCase.fileString) + if len(result.Fixes) != testCase.fixesNum { + t.Errorf("wrong Number of fixes, got %d, want %d", len(result.Fixes), testCase.fixesNum) + } + for index, fix := range result.Fixes { + if len(fix.ArtifactChanges) != 1 { + t.Errorf("wrong Number of artifactChanges in fix %d, got %d, want %d", index, len(fix.ArtifactChanges), 1) + } + replacements := fix.ArtifactChanges[0].Replacements + if len(replacements) != 1 { + t.Errorf("wrong Number of replacements in fix %d, got %d, want %d", index, len(replacements), 1) + } + startLine := *replacements[0].DeletedRegion.StartLine + startColumn := *replacements[0].DeletedRegion.StartColumn + endLine := *replacements[0].DeletedRegion.EndLine + endColumn := *replacements[0].DeletedRegion.EndColumn + location := testCase.region[index] + if location[0] != startLine || location[1] != startColumn || location[2] != endLine || location[3] != endColumn { + t.Errorf("wrong delete region in fix %d, got (%d, %d, %d, %d) want (%d, %d, %d, %d)", + index, startLine, startColumn, endLine, endColumn, location[0], location[1], location[2], location[3]) + } + if testCase.text[index] != *replacements[0].InsertedContent.Text { + t.Errorf("wrong add text in fix %d, got (%s) want (%s)", + index, *replacements[0].InsertedContent.Text, testCase.text[index]) + } + } + }) + } +}