Skip to content

Profile resolution with catalog with ungrouped controls throws exception #200

@aj-stein-nist

Description

@aj-stein-nist

Describe the bug

While writing tests for usnistgov/oscal-cli#178, I have been unable to resolve a profile with a catalog with a "flat" catalog that has only two controls. This is using a development version using liboscal-java v3.0.2 as a dependency.

Catalog that throws stack trace:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://github.com/usnistgov/OSCAL/releases/download/v1.1.1/oscal_complete_schema.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
<catalog xmlns="http://csrc.nist.gov/ns/oscal/1.0" uuid="1296032c-f0a7-4e00-84f0-c09b9b1c81b5">
    <metadata>
        <title>Valid OSCAL Document</title>
        <last-modified>2023-10-24T00:00:00.000000-00:00</last-modified>
        <version>1.0</version>
        <oscal-version>1.1.1</oscal-version>
        <role id="maintainer">
            <title>Maintainer of oscal-cli</title>
        </role>
        <party uuid="4ba3f2b7-e894-48d7-b940-91c68661df55" type="person">
            <name>NIST ITL CSD Developer</name>
        </party>
        <responsible-party role-id="maintainer">
            <party-uuid>4ba3f2b7-e894-48d7-b940-91c68661df55</party-uuid>
        </responsible-party>
    </metadata>
    <group id="eg1">
        <title>Example Group 1</title>
        <control id="control-1">
            <title>Control 1</title>
            <part name="statement">
                <p>This statement is a requirement for Control 1.</p>
            </part>
        </control>
        <control id="control-2">
            <title>Control 2</title>
            <part name="statement">
                <p>This statement is a requirement for Control 2.</p>
            </part>
        </control>
    </group>
</catalog>

Catalog that does not throw stack trace:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://github.com/usnistgov/OSCAL/releases/download/v1.1.1/oscal_complete_schema.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
<catalog xmlns="http://csrc.nist.gov/ns/oscal/1.0" uuid="1296032c-f0a7-4e00-84f0-c09b9b1c81b5">
    <metadata>
        <title>Valid OSCAL Document</title>
        <last-modified>2023-10-24T00:00:00.000000-00:00</last-modified>
        <version>1.0</version>
        <oscal-version>1.1.1</oscal-version>
        <role id="maintainer">
            <title>Maintainer of oscal-cli</title>
        </role>
        <party uuid="4ba3f2b7-e894-48d7-b940-91c68661df55" type="person">
            <name>NIST ITL CSD Developer</name>
        </party>
        <responsible-party role-id="maintainer">
            <party-uuid>4ba3f2b7-e894-48d7-b940-91c68661df55</party-uuid>
        </responsible-party>
    </metadata>
    <group id="eg1">
        <title>Example Group 1</title>
        <control id="control-1">
            <title>Control 1</title>
            <part name="statement">
                <p>This statement is a requirement for Control 1.</p>
            </part>
        </control>
        <control id="control-2">
            <title>Control 2</title>
            <part name="statement">
                <p>This statement is a requirement for Control 2.</p>
            </part>
        </control>
    </group>
</catalog>

Profile:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://github.com/usnistgov/OSCAL/releases/download/v1.1.1/oscal_complete_schema.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
<profile xmlns="http://csrc.nist.gov/ns/oscal/1.0" uuid="46a67f43-6dd0-4231-b7d0-28e900fcbbe0">
    <metadata>
        <title>Valid OSCAL Document</title>
        <last-modified>2023-10-24T00:00:00.000000-00:00</last-modified>
        <version>1.0</version>
        <oscal-version>1.1.1</oscal-version>
        <role id="maintainer">
            <title>Maintainer of oscal-cli</title>
        </role>
        <party uuid="4ba3f2b7-e894-48d7-b940-91c68661df55" type="person">
            <name>NIST ITL CSD Developer</name>
        </party>
        <responsible-party role-id="maintainer">
            <party-uuid>4ba3f2b7-e894-48d7-b940-91c68661df55</party-uuid>
        </responsible-party>
    </metadata>
    <import href="example_catalog_valid.xml">
        <include-controls>
            <with-id>control-1</with-id>
        </include-controls>
    </import>
    <back-matter>
        <resource uuid="1ac08f59-cafa-4a71-a63b-5f4a0f3cf1f2">
            <rlink href="example_catalog_valid.xml"/>
        </resource>
    </back-matter>
</profile>

Stack trace:

java.lang.AssertionError
 at gov.nist.secauto.oscal.lib.profile.resolver.merge.FlatteningStructuringVisitor.visitControl(FlatteningStructuringVisitor.java:121)
 at gov.nist.secauto.oscal.lib.profile.resolver.merge.FlatteningStructuringVisitor.visitControl(FlatteningStructuringVisitor.java:55)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogEntityVisitor.visitControlInternal(AbstractCatalogEntityVisitor.java:168)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogVisitor.visitControlItem(AbstractCatalogVisitor.java:145)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogVisitor.lambda$visitControlContainer$2(AbstractCatalogVisitor.java:127)
 at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
 at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:720)
 at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
 at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
 at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
 at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
 at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:553)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogVisitor.visitControlContainer(AbstractCatalogVisitor.java:129)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogEntityVisitor.visitControlContainer(AbstractCatalogEntityVisitor.java:122)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogVisitor.visitGroupContainer(AbstractCatalogVisitor.java:73)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogEntityVisitor.visitGroupContainer(AbstractCatalogEntityVisitor.java:110)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogVisitor.visitCatalog(AbstractCatalogVisitor.java:50)
 at gov.nist.secauto.oscal.lib.profile.resolver.support.AbstractCatalogEntityVisitor.visitCatalog(AbstractCatalogEntityVisitor.java:96)
 at gov.nist.secauto.oscal.lib.profile.resolver.merge.FlatteningStructuringVisitor.visitCatalog(FlatteningStructuringVisitor.java:84)
 at gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolver.structureFlat(ProfileResolver.java:489)
 at gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolver.handleMerge(ProfileResolver.java:453)
 at gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolver.resolveProfile(ProfileResolver.java:205)
 at gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolver.resolve(ProfileResolver.java:234)
 at gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolver.resolve(ProfileResolver.java:219)
 at gov.nist.secauto.oscal.tools.cli.core.commands.profile.ResolveSubcommand.executeCommand(ResolveSubcommand.java:287)
 at gov.nist.secauto.metaschema.cli.processor.command.ICommandExecutor$1.execute(ICommandExecutor.java:48)
 at gov.nist.secauto.metaschema.cli.processor.CLIProcessor$CallingContext.invokeCommand(CLIProcessor.java:403)
 at gov.nist.secauto.metaschema.cli.processor.CLIProcessor$CallingContext.processCommand(CLIProcessor.java:374)
 at gov.nist.secauto.metaschema.cli.processor.CLIProcessor.parseCommand(CLIProcessor.java:192)
 at gov.nist.secauto.metaschema.cli.processor.CLIProcessor.process(CLIProcessor.java:176)
 at gov.nist.secauto.oscal.tools.cli.core.CLI.runCli(CLI.java:78)
 at gov.nist.secauto.oscal.tools.cli.core.CLITest.testResolveSubCommandValidFile(CLITest.java:127)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
 at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)

Who is the bug affecting?

  1. Developers writing software with liboscal-java or engineers using software based on liboscal-java, such as oscal-cli.

What is affected by this bug?

Profile resolution with catalogs that do not have groups.

When does this occur?

Consistently.

How do we replicate the issue?

Review the examples or use the integration tests in in the 178-add-integration-tests branch.

See the above stack trace for further details.

Expected behavior (i.e. solution)

The catalog resolves correctly if it does not have groups.

Other Comments

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions