From 8ad420970cd6bd72ee0c18e6c25a4578e9db4432 Mon Sep 17 00:00:00 2001 From: Brandt Keller <43887158+brandtkeller@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:38:58 -0700 Subject: [PATCH] fix(composition): nil pointer in composition (#733) * fix(composition): nil pointer in composition * fix(validate): testing for required error with no control implementations --- src/pkg/common/composition/composition.go | 54 +++++++++---------- src/test/e2e/cmd/validate_test.go | 5 ++ .../valid-component-no-implementations.yaml | 14 +++++ 3 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 src/test/unit/common/oscal/valid-component-no-implementations.yaml diff --git a/src/pkg/common/composition/composition.go b/src/pkg/common/composition/composition.go index 9615ee5c..57dd86a6 100644 --- a/src/pkg/common/composition/composition.go +++ b/src/pkg/common/composition/composition.go @@ -152,41 +152,41 @@ func (c *Composer) ComposeComponentValidations(ctx context.Context, compDef *osc for componentIndex, component := range *compDef.Components { // If there are no control-implementations, skip to the next component - controlImplementations := *component.ControlImplementations - if controlImplementations == nil { - continue - } - for controlImplementationIndex, controlImplementation := range controlImplementations { - for implementedRequirementIndex, implementedRequirement := range controlImplementation.ImplementedRequirements { - if implementedRequirement.Links != nil { - compiledLinks := []oscalTypes_1_1_2.Link{} - - for _, link := range *implementedRequirement.Links { - if common.IsLulaLink(link) { - ids, err := resourceMap.AddFromLink(&link, baseDir) - if err != nil { - // return err - newId := uuid.NewUUID() - message.Debugf("Error adding validation %s from link %s: %v", newId, link.Href, err) - ids = []string{newId} - } - for _, id := range ids { - link := oscalTypes_1_1_2.Link{ - Rel: link.Rel, - Href: common.AddIdPrefix(id), - Text: link.Text, + if component.ControlImplementations != nil { + controlImplementations := *component.ControlImplementations + for controlImplementationIndex, controlImplementation := range controlImplementations { + for implementedRequirementIndex, implementedRequirement := range controlImplementation.ImplementedRequirements { + if implementedRequirement.Links != nil { + compiledLinks := []oscalTypes_1_1_2.Link{} + + for _, link := range *implementedRequirement.Links { + if common.IsLulaLink(link) { + ids, err := resourceMap.AddFromLink(&link, baseDir) + if err != nil { + // return err + newId := uuid.NewUUID() + message.Debugf("Error adding validation %s from link %s: %v", newId, link.Href, err) + ids = []string{newId} } + for _, id := range ids { + link := oscalTypes_1_1_2.Link{ + Rel: link.Rel, + Href: common.AddIdPrefix(id), + Text: link.Text, + } + compiledLinks = append(compiledLinks, link) + } + } else { compiledLinks = append(compiledLinks, link) } - } else { - compiledLinks = append(compiledLinks, link) } + (*component.ControlImplementations)[controlImplementationIndex].ImplementedRequirements[implementedRequirementIndex].Links = &compiledLinks + (*compDef.Components)[componentIndex] = component } - (*component.ControlImplementations)[controlImplementationIndex].ImplementedRequirements[implementedRequirementIndex].Links = &compiledLinks - (*compDef.Components)[componentIndex] = component } } } + } allFetched := resourceMap.AllFetched() if compDef.BackMatter != nil && compDef.BackMatter.Resources != nil { diff --git a/src/test/e2e/cmd/validate_test.go b/src/test/e2e/cmd/validate_test.go index 0c34681d..1e03be12 100644 --- a/src/test/e2e/cmd/validate_test.go +++ b/src/test/e2e/cmd/validate_test.go @@ -68,6 +68,11 @@ func TestValidateCommand(t *testing.T) { require.ErrorContains(t, err, "error validating on path") }) + t.Run("Validate with valid oscal containing no control implementations - error", func(t *testing.T) { + err := test(t, "-f", "../../unit/common/oscal/valid-component-no-implementations.yaml") + require.ErrorContains(t, err, "no control implementations found in component definition") + }) + t.Run("Test help", func(t *testing.T) { err := testAgainstGolden(t, "help", "--help") require.NoError(t, err) diff --git a/src/test/unit/common/oscal/valid-component-no-implementations.yaml b/src/test/unit/common/oscal/valid-component-no-implementations.yaml new file mode 100644 index 00000000..aa7cdbc2 --- /dev/null +++ b/src/test/unit/common/oscal/valid-component-no-implementations.yaml @@ -0,0 +1,14 @@ +component-definition: + uuid: ea3e8daf-a055-4593-95f4-fa1b10eab448 + metadata: + title: example no implementations + last-modified: "2023-11-29T17:48:16Z" + version: "20231129" + oscal-version: 1.1.2 + components: + - uuid: b87ba90e-86db-4980-9600-fbfc8bf3c4f1 + type: software + title: Test + description: | + this represents a component without any control implementations + purpose: Provides a testing \ No newline at end of file