usnistgov/oscal-cli

Exception in thread "main" java.lang.UnsupportedOperationException: Node 'LinkRef' not handled

volpet2014 opened this issue · 7 comments

Describe the bug

When running a conversion on a json SSP to XML, the OSCAL-CLI dumps out with the above error.

Who is the bug affecting?

Unable to successfully convert the file.

What is affected by this bug?

Unable to succesfully conver the source JSON file.

When does this occur?

When running a conversion on a json SSP to XML, the OSCAL-CLI dumps out with the above error.

How do we replicate the issue?

./oscal-cli ssp convert --to xml sample-ssp.json sample-ssp.xml

If applicable, add screenshots to help explain your problem.}

Expected behavior (i.e. solution)

Successful conversion of source file.

Other Comments

{Add any other context about the problem here.}
sample_ssp_conv.txt

@volpet2014, thanks for your report. I can talk with Dave, but I will point out based on the sample you had sent and testing it confirmed that there is potentially a bug, but I have figured in short order how to work around it.

I found a number of examples of descriptions with NIST SP 800-53/53A control identifiers in brackets (i.e. [AC-1] but for many controls, always in the form [AB-NN] for the family and control number) for a number of statements:

            {
              "statement-id": "ca-7.a_smt.2",
              "uuid": "d3096acf-87c3-47db-91a3-78d41c6ecd09",
              "by-components": [
                {
                  "component-uuid": "29b91da3-7583-496a-8347-56a5c1a0e8f5",
                  "uuid": "db6db715-478e-427c-b947-d9b849f17b97",
                  "description": "[IR-3] AwesomeCloud does something awesome.",
                  "implementation-status": {
                    "state": "implemented"
                  },
                  "responsible-roles": [
                    {
                      "role-id": "a-fun-org-role",
                      "party-uuids": [
                        "f048b11b-7e43-47ca-bfcb-560973b47cbe"
                      ]
                    }
                  ]
                }
              ]
            },

There seems to be, just like I expected from the stack trace, something odd going on with the interpretation of brackets even though it is part of the description string value re this cryptic bit from the relevant Java library:

$ oscal-cli ssp convert --to=xml path/to/sample_ssp.json
# .... truncated with content from sample ....
Exception in thread "main" java.lang.UnsupportedOperationException: Node 'LinkRef' not handled. AST: LinkRef[0, 6] referenceOpen:[0, 1, "["] reference:[1, 5, "IR-3"] referenceClose:[5, 6, "]"]
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupVisitor.visit(AbstractMarkupVisitor.java:102)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupVisitor.visitChildren(AbstractMarkupVisitor.java:85)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupXmlWriter.handleBasicElement(AbstractMarkupXmlWriter.java:52)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupXmlVisitor.visitParagraph(AbstractMarkupXmlVisitor.java:212)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupVisitor.processBlockElements(AbstractMarkupVisitor.java:184)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupVisitor.visit(AbstractMarkupVisitor.java:93)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.AbstractMarkupVisitor.visitChildren(AbstractMarkupVisitor.java:85)
        at gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter.writeXmlCharacters(MarkupMultilineAdapter.java:111)
        at gov.nist.secauto.metaschema.binding.model.JavaTypeAdapterDataTypeHandler.accept(JavaTypeAdapterDataTypeHandler.java:97)
        at gov.nist.secauto.metaschema.binding.model.AbstractFieldProperty.writeItem(AbstractFieldProperty.java:205)
        at gov.nist.secauto.metaschema.binding.model.SingletonPropertyInfo.writeValue(SingletonPropertyInfo.java:107)
        at gov.nist.secauto.metaschema.binding.model.AbstractNamedModelProperty.write(AbstractNamedModelProperty.java:304)
        at gov.nist.secauto.metaschema.binding.model.AbstractFieldProperty.write(AbstractFieldProperty.java:53)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeBody(DefaultAssemblyClassBinding.java:550)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeInternal(AbstractClassBinding.java:370)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeItem(AbstractClassBinding.java:361)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeItem(DefaultAssemblyClassBinding.java:80)
        at gov.nist.secauto.metaschema.binding.model.ClassDataTypeHandler.accept(ClassDataTypeHandler.java:110)
        at gov.nist.secauto.metaschema.binding.model.AbstractAssemblyProperty.writeItem(AbstractAssemblyProperty.java:103)
        at gov.nist.secauto.metaschema.binding.model.ListPropertyInfo.writeValue(ListPropertyInfo.java:173)
        at gov.nist.secauto.metaschema.binding.model.AbstractNamedModelProperty.write(AbstractNamedModelProperty.java:304)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeBody(DefaultAssemblyClassBinding.java:550)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeInternal(AbstractClassBinding.java:370)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeItem(AbstractClassBinding.java:361)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeItem(DefaultAssemblyClassBinding.java:80)
        at gov.nist.secauto.metaschema.binding.model.ClassDataTypeHandler.accept(ClassDataTypeHandler.java:110)
        at gov.nist.secauto.metaschema.binding.model.AbstractAssemblyProperty.writeItem(AbstractAssemblyProperty.java:103)
        at gov.nist.secauto.metaschema.binding.model.ListPropertyInfo.writeValue(ListPropertyInfo.java:173)
        at gov.nist.secauto.metaschema.binding.model.AbstractNamedModelProperty.write(AbstractNamedModelProperty.java:304)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeBody(DefaultAssemblyClassBinding.java:550)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeInternal(AbstractClassBinding.java:370)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeItem(AbstractClassBinding.java:361)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeItem(DefaultAssemblyClassBinding.java:80)
        at gov.nist.secauto.metaschema.binding.model.ClassDataTypeHandler.accept(ClassDataTypeHandler.java:110)
        at gov.nist.secauto.metaschema.binding.model.AbstractAssemblyProperty.writeItem(AbstractAssemblyProperty.java:103)
        at gov.nist.secauto.metaschema.binding.model.ListPropertyInfo.writeValue(ListPropertyInfo.java:173)
        at gov.nist.secauto.metaschema.binding.model.AbstractNamedModelProperty.write(AbstractNamedModelProperty.java:304)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeBody(DefaultAssemblyClassBinding.java:550)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeInternal(AbstractClassBinding.java:370)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeItem(AbstractClassBinding.java:361)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeItem(DefaultAssemblyClassBinding.java:80)
        at gov.nist.secauto.metaschema.binding.model.ClassDataTypeHandler.accept(ClassDataTypeHandler.java:110)
        at gov.nist.secauto.metaschema.binding.model.AbstractAssemblyProperty.writeItem(AbstractAssemblyProperty.java:103)
        at gov.nist.secauto.metaschema.binding.model.SingletonPropertyInfo.writeValue(SingletonPropertyInfo.java:107)
        at gov.nist.secauto.metaschema.binding.model.AbstractNamedModelProperty.write(AbstractNamedModelProperty.java:304)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeBody(DefaultAssemblyClassBinding.java:550)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeInternal(AbstractClassBinding.java:370)
        at gov.nist.secauto.metaschema.binding.model.AbstractClassBinding.writeItem(AbstractClassBinding.java:361)
        at gov.nist.secauto.metaschema.binding.model.DefaultAssemblyClassBinding.writeItem(DefaultAssemblyClassBinding.java:80)
        at gov.nist.secauto.metaschema.binding.model.RootAssemblyDefinition.writeItem(RootAssemblyDefinition.java:116)
        at gov.nist.secauto.metaschema.binding.model.RootAssemblyDefinition.writeRoot(RootAssemblyDefinition.java:285)
        at gov.nist.secauto.metaschema.binding.io.xml.DefaultXmlSerializer.serialize(DefaultXmlSerializer.java:98)
        at gov.nist.secauto.metaschema.binding.io.ISerializer.serialize(ISerializer.java:67)
        at gov.nist.secauto.oscal.tools.cli.core.commands.AbstractConvertSubcommand.convert(AbstractConvertSubcommand.java:203)
        at gov.nist.secauto.oscal.tools.cli.core.commands.AbstractConvertSubcommand.performConvert(AbstractConvertSubcommand.java:187)
        at gov.nist.secauto.oscal.tools.cli.core.commands.AbstractConvertSubcommand.executeCommand(AbstractConvertSubcommand.java:168)
        at gov.nist.secauto.oscal.tools.cli.framework.CLIProcessor.invokeCommand(CLIProcessor.java:260)
        at gov.nist.secauto.oscal.tools.cli.framework.CLIProcessor.parseCommand(CLIProcessor.java:236)
        at gov.nist.secauto.oscal.tools.cli.framework.CLIProcessor.processCommand(CLIProcessor.java:196)
        at gov.nist.secauto.oscal.tools.cli.framework.CLIProcessor.parseCommand(CLIProcessor.java:143)
        at gov.nist.secauto.oscal.tools.cli.framework.CLIProcessor.process(CLIProcessor.java:127)
        at gov.nist.secauto.oscal.tools.cli.core.CLI.parse(CLI.java:64)
        at gov.nist.secauto.oscal.tools.cli.core.CLI.main(CLI.java:46)

Removing the brackets altogether, so I will show with an amended example, from above with out the [ and ], resolves the issue.

            {
              "statement-id": "ca-7.a_smt.2",
              "uuid": "d3096acf-87c3-47db-91a3-78d41c6ecd09",
              "by-components": [
                {
                  "component-uuid": "29b91da3-7583-496a-8347-56a5c1a0e8f5",
                  "uuid": "db6db715-478e-427c-b947-d9b849f17b97",
                  "description": "IR-3 AwesomeCloud does something awesome.",
                  "implementation-status": {
                    "state": "implemented"
                  },
                  "responsible-roles": [
                    {
                      "role-id": "a-fun-org-role",
                      "party-uuids": [
                        "f048b11b-7e43-47ca-bfcb-560973b47cbe"
                      ]
                    }
                  ]
                }
              ]
            },

To do this in your sample, you can use the Search and Replace feature on the file in regex mode of a current version of VS Code and replace all these references at once by replacing the pattern \[([A-Z]{2}-[0-9])\] with $1 to quickly replace and re-run conversion. Replace all by selecting the button highlight in blue.

image

As for the why of this, I am less sure. This appears to have changed many that are of this format, but some from your collaborating stakeholder have escaped the inline brackets in text. I can confirm for you (and @david-waltermire-nist if those are ignored), since that is another interesting data point.

Can you please try and confirm this workaround on your workstation please?

Weirdly enough, also escaping the leading one will mitigate this. This will not throw an exception.

            {
              "statement-id": "ca-7.a_smt.2",
              "uuid": "d3096acf-87c3-47db-91a3-78d41c6ecd09",
              "by-components": [
                {
                  "component-uuid": "29b91da3-7583-496a-8347-56a5c1a0e8f5",
                  "uuid": "db6db715-478e-427c-b947-d9b849f17b97",
                  "description": "\"[IR-3] AwesomeCloud does something awesome.",
                  "implementation-status": {
                    "state": "implemented"
                  },
                  "responsible-roles": [
                    {
                      "role-id": "a-fun-org-role",
                      "party-uuids": [
                        "f048b11b-7e43-47ca-bfcb-560973b47cbe"
                      ]
                    }
                  ]
                }
              ]
            },

During conversion, a single left-bracket, unescaped, will also throw an exception. This similarly exhibits the bug. Descriptions cannot have unbalanced brackets when converting with this tool and this version, very odd.

            {
              "statement-id": "ca-7.a_smt.2",
              "uuid": "d3096acf-87c3-47db-91a3-78d41c6ecd09",
              "by-components": [
                {
                  "component-uuid": "29b91da3-7583-496a-8347-56a5c1a0e8f5",
                  "uuid": "db6db715-478e-427c-b947-d9b849f17b97",
                  "description": "[IR-3 AwesomeCloud does something awesome.",
                  "implementation-status": {
                    "state": "implemented"
                  },
                  "responsible-roles": [
                    {
                      "role-id": "a-fun-org-role",
                      "party-uuids": [
                        "f048b11b-7e43-47ca-bfcb-560973b47cbe"
                      ]
                    }
                  ]
                }
              ]
            },

The issue here is that the following markup is an link reference:

{
  "description": "[IR-3] AwesomeCloud does something awesome."
}

It is expecting a link definition like the following:

{
  "description": "[IR-3]: https://example.org/somelink 'somelink title'\n\n[IR-3] AwesomeCloud does something awesome."
}

That being said, the parser should fail more gracefully. I'll fix the error handling for this as part of this issue.

Link references, such as [IR-3]: https://example.org/somelink 'somelink title'\n\n[IR-3] AwesomeCloud are not supported by metaschema Java. As @aj-stein-nist indicated, you can escape the brackets, which will fix the content.

Thus:

{
  "description": "[IR-3] AwesomeCloud does something awesome."
}

Should be:

{
  "description": "\[IR-3\] AwesomeCloud does something awesome."
}

Suggest closing this issue.

This is fixed in #155. A more meaningful error message is now produced.