From 8dc2d93aaa35c8e4e7f30d43f48ba18eda07c0d6 Mon Sep 17 00:00:00 2001 From: HoussemNasri Date: Mon, 4 Sep 2023 20:42:15 +0100 Subject: [PATCH] Support parsing Dpkg OVAL with StAX --- java/code/src/com/suse/oval/OvalParser.java | 123 ++++++++++++++------ 1 file changed, 86 insertions(+), 37 deletions(-) diff --git a/java/code/src/com/suse/oval/OvalParser.java b/java/code/src/com/suse/oval/OvalParser.java index 8f0e288949da..7ddfac59e1ec 100755 --- a/java/code/src/com/suse/oval/OvalParser.java +++ b/java/code/src/com/suse/oval/OvalParser.java @@ -15,6 +15,7 @@ package com.suse.oval; +import com.redhat.rhn.domain.rhnpackage.PackageType; import com.suse.oval.exceptions.OvalParserException; import com.suse.oval.ovaltypes.Advisory; import com.suse.oval.ovaltypes.AdvisoryAffectedType; @@ -35,6 +36,12 @@ import com.suse.oval.ovaltypes.StateType; import com.suse.oval.ovaltypes.TestType; import com.suse.oval.ovaltypes.VersionType; +import com.suse.oval.ovaltypes.linux.DpkginfoObject; +import com.suse.oval.ovaltypes.linux.DpkginfoState; +import com.suse.oval.ovaltypes.linux.DpkginfoTest; +import com.suse.oval.ovaltypes.linux.RpminfoObject; +import com.suse.oval.ovaltypes.linux.RpminfoState; +import com.suse.oval.ovaltypes.linux.RpminfoTest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -57,12 +64,16 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * The Oval Parser is responsible for parsing OVAL(Open Vulnerability and Assessment Language) documents */ public class OvalParser { private static final Logger LOG = LogManager.getLogger(OvalParser.class); + private static final List TEST_TYPES = List.of("rpminfo_test", "dpkginfo_test"); + private static final List OBJECT_TYPES = List.of("rpminfo_object", "dpkginfo_object"); + private static final List STATE_TYPES = List.of("rpminfo_state", "dpkginfo_state"); public OvalRootType parse(File ovalFile) throws OvalParserException { try { @@ -96,17 +107,20 @@ public OvalRootType parseStax(File ovalFile) { if (nextEvent.isStartElement()) { String elementName = nextEvent.asStartElement().getName().getLocalPart(); - if (elementName.equals("objects")) { - ovalRoot.setObjects(parseObjects(reader)); - } - else if (elementName.equals("states")) { - ovalRoot.setStates(parseStates(reader)); - } - else if (elementName.equals("tests")) { - ovalRoot.setTests(parseTests(reader)); - } - else if (elementName.equals("definitions")) { - ovalRoot.setDefinitions(parseDefinitions(reader)); + switch (elementName) { + case "objects": + ovalRoot.setObjects(parseObjects(reader)); + break; + case "states": + ovalRoot.setStates(parseStates(reader)); + break; + case "tests": + ovalRoot.setTests(parseTests(reader)); + break; + case "definitions": + ovalRoot.setDefinitions(parseDefinitions(reader)); + break; + default: // Do nothing } } } @@ -395,9 +409,12 @@ private List parseTests(XMLEventReader reader) throws XMLStreamExcepti XMLEvent nextEvent = reader.nextEvent(); if (nextEvent.isStartElement()) { - if (nextEvent.asStartElement().getName().getLocalPart().equals("rpminfo_test")) { - TestType testType = parseTestType(nextEvent.asStartElement(), reader); - tests.add(testType); + String element = nextEvent.asStartElement().getName().getLocalPart(); + if (element.equals("rpminfo_test")) { + tests.add(parseTestType(nextEvent.asStartElement(), reader, PackageType.RPM)); + } + else if(element.equals("dpkginfo_test_test")) { + tests.add(parseTestType(nextEvent.asStartElement(), reader, PackageType.DEB)); } } @@ -411,8 +428,17 @@ private List parseTests(XMLEventReader reader) throws XMLStreamExcepti throw new OvalParserException("Unable to find the closing tag for "); } - private TestType parseTestType(StartElement testElement, XMLEventReader reader) throws XMLStreamException { - TestType testType = new TestType(); + private TestType parseTestType(StartElement testElement, XMLEventReader reader, PackageType packageType) + throws XMLStreamException { + + Objects.requireNonNull(packageType); + TestType testType; + if (packageType == PackageType.DEB) { + testType = new DpkginfoTest(); + } + else { + testType = new RpminfoTest(); + } testElement.getAttributes().forEachRemaining(attribute -> { String attributeName = attribute.getName().getLocalPart(); @@ -436,10 +462,12 @@ private TestType parseTestType(StartElement testElement, XMLEventReader reader) new QName("object_ref")); if (objectRefAttribute != null) { testType.setObjectRef(objectRefAttribute.getValue()); - } else { + } + else { LOG.warn("objectRef property was not found"); } - } else if (nextEvent.asStartElement().getName().getLocalPart().equals("state")) { + } + else if (nextEvent.asStartElement().getName().getLocalPart().equals("state")) { Attribute stateRefAttribute = nextEvent.asStartElement().getAttributeByName( new QName("state_ref")); if (stateRefAttribute != null) { @@ -452,13 +480,14 @@ private TestType parseTestType(StartElement testElement, XMLEventReader reader) } if (nextEvent.isEndElement()) { - if (nextEvent.asEndElement().getName().getLocalPart().equals("rpminfo_test")) { + String element = nextEvent.asEndElement().getName().getLocalPart(); + if (TEST_TYPES.contains(element)) { return testType; } } } - throw new OvalParserException("Unable to find the closing tag for "); + throw new OvalParserException("Unable to find the closing tag for test type"); } private List parseStates(XMLEventReader reader) throws XMLStreamException { @@ -468,9 +497,12 @@ private List parseStates(XMLEventReader reader) throws XMLStreamExcep XMLEvent nextEvent = reader.nextEvent(); if (nextEvent.isStartElement()) { - if (nextEvent.asStartElement().getName().getLocalPart().equals("rpminfo_state")) { - StateType stateType = parseStateType(nextEvent.asStartElement(), reader); - states.add(stateType); + String element = nextEvent.asStartElement().getName().getLocalPart(); + if (element.equals("rpminfo_state")) { + states.add(parseStateType(nextEvent.asStartElement(), reader, PackageType.RPM)); + } + else if (element.equals("dpkginfo_state")) { + states.add(parseStateType(nextEvent.asStartElement(), reader, PackageType.DEB)); } } @@ -484,12 +516,19 @@ private List parseStates(XMLEventReader reader) throws XMLStreamExcep throw new OvalParserException("Unable to find the closing tag for "); } - private StateType parseStateType(StartElement rpmStateElement, XMLEventReader reader) throws XMLStreamException { - StateType stateType = new StateType(); + private StateType parseStateType(StartElement rpmStateElement, XMLEventReader reader, PackageType packageType) + throws XMLStreamException { + Objects.requireNonNull(packageType); + StateType stateType; + if (packageType == PackageType.DEB) { + stateType = new DpkginfoState(); + } + else { + stateType = new RpminfoState(); + } rpmStateElement.getAttributes().forEachRemaining(attribute -> { String attributeName = attribute.getName().getLocalPart(); - switch (attributeName) { case "id": stateType.setId(attribute.getValue()); @@ -518,13 +557,14 @@ else if (elementName.equals("version")) { } if (nextEvent.isEndElement()) { - if (nextEvent.asEndElement().getName().getLocalPart().equals("rpminfo_state")) { + String element = nextEvent.asEndElement().getName().getLocalPart(); + if (STATE_TYPES.contains(element)) { return stateType; } } } - throw new OvalParserException("Unable to find the closing tag for "); + throw new OvalParserException("Unable to find the closing tag for state type"); } private ArchType parseArchStateEntity(StartElement archElement, XMLEventReader reader) throws XMLStreamException { @@ -548,7 +588,6 @@ private EVRType parseEVRStateEntity(StartElement evrElement, XMLEventReader read evrElement.getAttributes().forEachRemaining(attribute -> { String attributeName = attribute.getName().getLocalPart(); - if (attributeName.equals("operation")) { evrType.setOperation(OperationEnumeration.fromValue(attribute.getValue())); } @@ -583,9 +622,12 @@ private List parseObjects(XMLEventReader reader) throws XMLStreamExc XMLEvent nextEvent = reader.nextEvent(); if (nextEvent.isStartElement()) { - if (nextEvent.asStartElement().getName().getLocalPart().equals("rpminfo_object")) { - ObjectType objectType = parseObjectType(nextEvent.asStartElement(), reader); - objects.add(objectType); + String element = nextEvent.asStartElement().getName().getLocalPart(); + if (element.equals("rpminfo_object")) { + objects.add(parseObjectType(nextEvent.asStartElement(), reader, PackageType.RPM)); + } + else if (element.equals("dpkginfo_object")) { + objects.add(parseObjectType(nextEvent.asStartElement(), reader, PackageType.DEB)); } } @@ -599,8 +641,15 @@ private List parseObjects(XMLEventReader reader) throws XMLStreamExc throw new OvalParserException("Unable to find the closing tag for "); } - private ObjectType parseObjectType(StartElement rpmObjectElement, XMLEventReader reader) throws XMLStreamException { - ObjectType objectType = new ObjectType(); + private ObjectType parseObjectType(StartElement rpmObjectElement, XMLEventReader reader, PackageType packageType) + throws XMLStreamException { + Objects.requireNonNull(packageType); + ObjectType objectType; + if (packageType == PackageType.DEB) { + objectType = new DpkginfoObject(); + } else { + objectType = new RpminfoObject(); + } rpmObjectElement.getAttributes().forEachRemaining(attribute -> { String attributeName = attribute.getName().getLocalPart(); @@ -617,7 +666,6 @@ private ObjectType parseObjectType(StartElement rpmObjectElement, XMLEventReader } }); - while (reader.hasNext()) { XMLEvent nextEvent = reader.nextEvent(); if (nextEvent.isStartElement()) { @@ -627,13 +675,14 @@ private ObjectType parseObjectType(StartElement rpmObjectElement, XMLEventReader } if (nextEvent.isEndElement()) { - if (nextEvent.asEndElement().getName().getLocalPart().equals("rpminfo_object")) { + String element = nextEvent.asEndElement().getName().getLocalPart(); + if (OBJECT_TYPES.contains(element)) { return objectType; } } } - throw new OvalParserException("Unable to find the closing tag for "); + throw new OvalParserException("Unable to find the closing tag for object type"); } }