Skip to content

Commit

Permalink
Support parsing Dpkg OVAL with StAX
Browse files Browse the repository at this point in the history
  • Loading branch information
HoussemNasri committed Sep 7, 2023
1 parent 4dd210e commit 8dc2d93
Showing 1 changed file with 86 additions and 37 deletions.
123 changes: 86 additions & 37 deletions java/code/src/com/suse/oval/OvalParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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<String> TEST_TYPES = List.of("rpminfo_test", "dpkginfo_test");
private static final List<String> OBJECT_TYPES = List.of("rpminfo_object", "dpkginfo_object");
private static final List<String> STATE_TYPES = List.of("rpminfo_state", "dpkginfo_state");

public OvalRootType parse(File ovalFile) throws OvalParserException {
try {
Expand Down Expand Up @@ -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
}
}
}
Expand Down Expand Up @@ -395,9 +409,12 @@ private List<TestType> 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));
}
}

Expand All @@ -411,8 +428,17 @@ private List<TestType> parseTests(XMLEventReader reader) throws XMLStreamExcepti
throw new OvalParserException("Unable to find the closing tag for </tests>");
}

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();
Expand All @@ -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) {
Expand All @@ -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 </rpminfo_test>");
throw new OvalParserException("Unable to find the closing tag for test type");
}

private List<StateType> parseStates(XMLEventReader reader) throws XMLStreamException {
Expand All @@ -468,9 +497,12 @@ private List<StateType> 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));
}
}

Expand All @@ -484,12 +516,19 @@ private List<StateType> parseStates(XMLEventReader reader) throws XMLStreamExcep
throw new OvalParserException("Unable to find the closing tag for </states>");
}

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());
Expand Down Expand Up @@ -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 </rpminfo_state>");
throw new OvalParserException("Unable to find the closing tag for state type");
}

private ArchType parseArchStateEntity(StartElement archElement, XMLEventReader reader) throws XMLStreamException {
Expand All @@ -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()));
}
Expand Down Expand Up @@ -583,9 +622,12 @@ private List<ObjectType> 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));
}
}

Expand All @@ -599,8 +641,15 @@ private List<ObjectType> parseObjects(XMLEventReader reader) throws XMLStreamExc
throw new OvalParserException("Unable to find the closing tag for </objects>");
}

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();
Expand All @@ -617,7 +666,6 @@ private ObjectType parseObjectType(StartElement rpmObjectElement, XMLEventReader
}
});


while (reader.hasNext()) {
XMLEvent nextEvent = reader.nextEvent();
if (nextEvent.isStartElement()) {
Expand All @@ -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 </rpminfo_object>");
throw new OvalParserException("Unable to find the closing tag for object type");
}

}

0 comments on commit 8dc2d93

Please sign in to comment.