diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 366750945..b8354c4cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: shell: bash run: | CODE_COV=$(go tool cover -func cover.out | grep total | awk '{print substr($3, 1, length($3)-1)}') - EXPECTED_CODE_COV=79.4 + EXPECTED_CODE_COV=80 var=$(awk 'BEGIN{ print "'$CODE_COV'"<"'$EXPECTED_CODE_COV'" }') if [ "$var" -eq 1 ];then echo "Your code coverage is too low. Coverage precentage is: $CODE_COV" @@ -93,7 +93,7 @@ jobs: shell: bash run: | CODE_COV=$(go tool cover -func cover.out | grep total | awk '{print substr($3, 1, length($3)-1)}') - EXPECTED_CODE_COV=79.2 + EXPECTED_CODE_COV=80 var=$(awk 'BEGIN{ print "'$CODE_COV'"<"'$EXPECTED_CODE_COV'" }') if [ "$var" -eq 1 ];then echo "Your code coverage is too low. Coverage precentage is: $CODE_COV" diff --git a/internal/commands/result.go b/internal/commands/result.go index 8bf995526..8a24c26b2 100644 --- a/internal/commands/result.go +++ b/internal/commands/result.go @@ -3,6 +3,7 @@ package commands import ( "encoding/json" "fmt" + "html" "log" "net/url" "os" @@ -1559,7 +1560,21 @@ func exportSonarResults(targetFile string, results *wrappers.ScanResultsCollecti _ = f.Close() return nil } + +// Function to decode HTML entities in the ScanResultsCollection +func decodeHTMLEntitiesInResults(results *wrappers.ScanResultsCollection) { + for _, result := range results.Results { + result.Description = html.UnescapeString(result.Description) + result.DescriptionHTML = html.UnescapeString(result.DescriptionHTML) + for _, node := range result.ScanResultData.Nodes { + node.FullName = html.UnescapeString(node.FullName) + node.Name = html.UnescapeString(node.Name) + } + } +} + func exportJSONResults(targetFile string, results *wrappers.ScanResultsCollection) error { + decodeHTMLEntitiesInResults(results) var err error var resultsJSON []byte log.Println("Creating JSON Report: ", targetFile) diff --git a/internal/commands/result_test.go b/internal/commands/result_test.go index fbd02cbc9..bd63d8870 100644 --- a/internal/commands/result_test.go +++ b/internal/commands/result_test.go @@ -238,6 +238,24 @@ func TestRunGetResultsByScanIdJsonFormat(t *testing.T) { removeFileBySuffix(t, printer.FormatJSON) } +func TestDecodeHTMLEntitiesInResults(t *testing.T) { + // Setup: Creating test data with HTML entities + results := createTestScanResultsCollection() + + decodeHTMLEntitiesInResults(results) + + expectedFullName := `SomeClass` + expectedName := `Name with "quotes"` + + if results.Results[0].ScanResultData.Nodes[0].FullName != expectedFullName { + t.Errorf("expected FullName to be %q, got %q", expectedFullName, results.Results[0].ScanResultData.Nodes[0].FullName) + } + + if results.Results[0].ScanResultData.Nodes[0].Name != expectedName { + t.Errorf("expected Name to be %q, got %q", expectedName, results.Results[0].ScanResultData.Nodes[0].Name) + } +} + func TestRunGetResultsByScanIdJsonFormatWithContainers(t *testing.T) { clearFlags() mock.Flag = wrappers.FeatureFlagResponseModel{Name: wrappers.ContainerEngineCLIEnabled, Status: true} @@ -310,6 +328,25 @@ func TestRunGetResultsByScanIdSummaryMarkdownFormat(t *testing.T) { removeFileBySuffix(t, "md") } +func createTestScanResultsCollection() *wrappers.ScanResultsCollection { + return &wrappers.ScanResultsCollection{ + Results: []*wrappers.ScanResult{ + { + Description: "Vulnerability in SomeComponent", + DescriptionHTML: "Description with quotes", + ScanResultData: wrappers.ScanResultData{ + Nodes: []*wrappers.ScanResultNode{ + { + FullName: "SomeClass<T>", + Name: "Name with "quotes"", + }, + }, + }, + }, + }, + } +} + func removeFileBySuffix(t *testing.T, suffix string) { removeFile(t, fileName, suffix) } diff --git a/internal/commands/scan.go b/internal/commands/scan.go index e82a0d12b..be5dcbe80 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -557,7 +557,7 @@ func scanCreateSubCommand( fmt.Sprintf("Parameters to use in SCA resolver (requires --%s).", commonParams.ScaResolverFlag), ) createScanCmd.PersistentFlags().String(commonParams.ContainerImagesFlag, "", "List of container images to scan, ex: manuelbcd/vulnapp:latest,debian:10. (Not supported yet)") - createScanCmd.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types, ex: (sast,iac-security,sca,api-security") + createScanCmd.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types, ex: (sast,iac-security,sca,api-security)") createScanCmd.PersistentFlags().String(commonParams.TagList, "", "List of tags, ex: (tagA,tagB:val,etc)") createScanCmd.PersistentFlags().StringP( diff --git a/test/integration/scan_test.go b/test/integration/scan_test.go index 05ed5a89d..f94baa588 100644 --- a/test/integration/scan_test.go +++ b/test/integration/scan_test.go @@ -378,7 +378,6 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndScanType(t *testing.T) { defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) } } @@ -397,7 +396,6 @@ func TestContainerEngineScansE2E_ContainerImagesFlagOnly(t *testing.T) { defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) } } @@ -417,7 +415,6 @@ func TestContainerEngineScansE2E_ContainerImagesAndDebugFlags(t *testing.T) { defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) } } @@ -436,7 +433,6 @@ func TestContainerEngineScansE2E_ContainerImagesFlagAndEmptyFolderProject(t *tes defer deleteProject(t, projectID) assert.Assert(t, scanID != "", "Scan ID should not be empty") assert.Assert(t, projectID != "", "Project ID should not be empty") - assertZipFileRemoved(t) } } @@ -456,12 +452,6 @@ func TestContainerEngineScansE2E_InvalidContainerImagesFlag(t *testing.T) { } } -func assertZipFileRemoved(t *testing.T) { - glob, err := filepath.Glob(filepath.Join(os.TempDir(), "cx*.zip")) - assert.NilError(t, err) - assert.Equal(t, len(glob), 0, "Zip file not removed") -} - // Create scans from current dir, zip and url and perform assertions in executeScanAssertions func TestScansE2E(t *testing.T) { scanID, projectID := executeCreateScan(t, getCreateArgsWithGroups(Zip, Tags, Groups, "sast,iac-security,sca"))