From dcccb90ac8152d7d45b10a33ae0402440871199c Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 19 Jan 2024 16:16:03 -0600 Subject: [PATCH] Add support for remove operation using index into arrays (slices) Signed-off-by: Matt Rutkowski --- .vscode/settings.json | 1 + README.md | 8 ++++++-- cmd/patch.go | 12 +++++++++++- cmd/patch_test.go | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7fdc3cc4..6d6b8b25 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -74,6 +74,7 @@ "losslessly", "LSTM", "marshallers", + "MBOM", "MLBOM", "multimap", "myservices", diff --git a/README.md b/README.md index f43da443..bf775210 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,13 @@ # sbom-utility -This utility was designed to be an API platform used initially to **validate CycloneDX** or **SPDX Software Bills-of-Materials (BOMs)** against versioned JSON schemas, as published by their respective communities, as well as customized schema variants provided by companies or organizations that have stricter BOM compliance requirements. +This utility was designed to be an API platform used initially to validate **CycloneDX** or **SPDX-formatted Bills-of-Materials (BOMs)** against versioned JSON schemas as published by their respective standards communities as well as customized variants designed by companies or organizations that may have stricter BOM compliance requirements. -The utility has now grown to include a rich set of commands, listed below, that can be used for creating filtered BOM-data reports in many formats (e.g., txt, csv, md) using the utility's powerful, SQL-like **query** capability. These commands can extract data from BOMs that enables verification of information supporting [BOM use cases](#cyclonedx-use-cases) or any custom security and compliance requirements. +The utility has now grown to include a rich set of commands, listed below, such as **trim**, **patch** (IETF RFC 6902) and **diff** as well as commands used to create filtered reports using the utility's powerful, SQL-like **query** command capability. + +In addition, commands exist to easily extract **license**, **vulnerability**, **component**, **service** and other BOM information enabling verification for [BOM use cases](#cyclonedx-use-cases) or custom security and compliance requirements. + +*Please note that the utility supports all BOM variants such as **Software** (SBOM), **Hardware** (HBOM), **Manufacturing** (MBOM), **AI/ML** (MLBOM), etc. that adhere to their respective schemas.* ## Command Overview diff --git a/cmd/patch.go b/cmd/patch.go index 931ce9d3..01a08402 100644 --- a/cmd/patch.go +++ b/cmd/patch.go @@ -352,7 +352,8 @@ func removeValue(parentMap map[string]interface{}, keys []string, value interfac if err != nil { return } - newSlice := insertValueIntoSlice(nextNode.([]interface{}), arrayIndex, value) + var newSlice []interface{} + newSlice, err = removeValueFromSlice(typedNode, arrayIndex) parentMap[nextNodeKey] = newSlice case float64: // NOTE: It is a conscious decision of tbe encoding/json package to @@ -451,3 +452,12 @@ func insertValueIntoSlice(slice []interface{}, index int, value interface{}) []i slice[index] = value return slice } + +func removeValueFromSlice(slice []interface{}, index int) (newSlice []interface{}, err error) { + if index < 0 || index >= len(slice) { + err = fmt.Errorf("remove array element failed. Index (%v) out of range for array (length: %v). ", index, len(slice)) + return + } + // unpack elements from the slice subsets (i.e. using ... notation) + return append(slice[:index], slice[index+1:]...), nil +} diff --git a/cmd/patch_test.go b/cmd/patch_test.go index d4a2e9de..3c0a27d0 100644 --- a/cmd/patch_test.go +++ b/cmd/patch_test.go @@ -748,3 +748,20 @@ func TestPatchRFC6902AppendixA3Patch1Remove(t *testing.T) { t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) } } + +func TestPatchRFC6902AppendixA4Patch1Remove(t *testing.T) { + ti := NewPatchTestInfo( + TEST_PATCH_RFC_6902_APPX_A_4_BASE, + TEST_PATCH_RFC_6902_APPX_A_4_PATCH_REMOVE_ARRAY_1, nil) + ti.IsInputJSON = true + ti.OutputIndent = 0 + buffer, _, err := innerTestPatch(t, ti) + if err != nil { + t.Error(err) + } + getLogger().Tracef("%s\n", buffer.String()) + TEST_RESULT := "{\"foo\":[\"bar\",\"baz\"]}\n" + if buffer.String() != TEST_RESULT { + t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + } +}