mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 15:53:36 +01:00
Implement issue #704 and enable multi-schema validation
This commit is contained in:
@@ -25,6 +25,7 @@ import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import org.owasp.dependencycheck.Engine;
|
||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||
@@ -36,6 +37,7 @@ import org.owasp.dependencycheck.utils.DownloadFailedException;
|
||||
import org.owasp.dependencycheck.utils.Downloader;
|
||||
import org.owasp.dependencycheck.utils.FileUtils;
|
||||
import org.owasp.dependencycheck.utils.Settings;
|
||||
import org.owasp.dependencycheck.xml.hints.EvidenceMatcher;
|
||||
import org.owasp.dependencycheck.xml.hints.VendorDuplicatingHintRule;
|
||||
import org.owasp.dependencycheck.xml.hints.HintParseException;
|
||||
import org.owasp.dependencycheck.xml.hints.HintParser;
|
||||
@@ -136,23 +138,23 @@ public class HintAnalyzer extends AbstractAnalyzer {
|
||||
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||
for (HintRule hint : hints.getHintRules()) {
|
||||
boolean matchFound = false;
|
||||
for (Evidence given : hint.getGivenVendor()) {
|
||||
if (dependency.getVendorEvidence().getEvidence().contains(given)) {
|
||||
for (EvidenceMatcher given : hint.getGivenVendor()) {
|
||||
if (hasMatchingEvidence(dependency.getVendorEvidence().getEvidence(),given)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matchFound) {
|
||||
for (Evidence given : hint.getGivenProduct()) {
|
||||
if (dependency.getProductEvidence().getEvidence().contains(given)) {
|
||||
for (EvidenceMatcher given : hint.getGivenProduct()) {
|
||||
if (hasMatchingEvidence(dependency.getProductEvidence().getEvidence(),given)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matchFound) {
|
||||
for (Evidence given : hint.getGivenVersion()) {
|
||||
if (dependency.getVersionEvidence().getEvidence().contains(given)) {
|
||||
for (EvidenceMatcher given : hint.getGivenVersion()) {
|
||||
if (hasMatchingEvidence(dependency.getVersionEvidence().getEvidence(),given)) {
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
@@ -176,20 +178,14 @@ public class HintAnalyzer extends AbstractAnalyzer {
|
||||
for (Evidence e : hint.getAddVersion()) {
|
||||
dependency.getVersionEvidence().addEvidence(e);
|
||||
}
|
||||
for (Evidence e : hint.getRemoveVendor()) {
|
||||
if (dependency.getVendorEvidence().getEvidence().contains(e)) {
|
||||
dependency.getVendorEvidence().getEvidence().remove(e);
|
||||
}
|
||||
for (EvidenceMatcher e : hint.getRemoveVendor()) {
|
||||
removeMatchingEvidences(dependency.getVendorEvidence().getEvidence(),e);
|
||||
}
|
||||
for (Evidence e : hint.getRemoveProduct()) {
|
||||
if (dependency.getProductEvidence().getEvidence().contains(e)) {
|
||||
dependency.getProductEvidence().getEvidence().remove(e);
|
||||
}
|
||||
for (EvidenceMatcher e : hint.getRemoveProduct()) {
|
||||
removeMatchingEvidences(dependency.getProductEvidence().getEvidence(),e);
|
||||
}
|
||||
for (Evidence e : hint.getRemoveVersion()) {
|
||||
if (dependency.getVersionEvidence().getEvidence().contains(e)) {
|
||||
dependency.getVersionEvidence().getEvidence().remove(e);
|
||||
}
|
||||
for (EvidenceMatcher e : hint.getRemoveVersion()) {
|
||||
removeMatchingEvidences(dependency.getVersionEvidence().getEvidence(),e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,6 +206,24 @@ public class HintAnalyzer extends AbstractAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMatchingEvidence(Set<Evidence> evidences, EvidenceMatcher criterion) {
|
||||
for (Evidence evidence : evidences) {
|
||||
if (criterion.matches(evidence)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void removeMatchingEvidences(Set<Evidence> evidences, EvidenceMatcher e) {
|
||||
for (Iterator<Evidence> it = evidences.iterator();it.hasNext();) {
|
||||
Evidence evidence = it.next();
|
||||
if (e.matches(evidence)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the hint rules file.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* This file is part of dependency-check-core.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright (c) 2017 Hans Aikema. All Rights Reserved.
|
||||
*/
|
||||
package org.owasp.dependencycheck.xml.hints;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Evidence;
|
||||
|
||||
/**
|
||||
* EvidenceMatcher can match one or more {@link Evidence}s.
|
||||
* By using regular expressions for some fields and allowing omission of
|
||||
* Evidence fields it can be used to match more than one occurrence of evidence
|
||||
* to enable hints that work for a range of similar false positives/false negatives.
|
||||
*
|
||||
* The EvidenceMatcher is used for processing Evidences of a project's
|
||||
* dependencies in conjuction with the {@code <given>} and {@code <remove>}
|
||||
* clauses of the hints file.
|
||||
*
|
||||
* @author Hans Aikema
|
||||
*/
|
||||
public class EvidenceMatcher {
|
||||
|
||||
/**
|
||||
* Creates a new EvidenceMatcher objects.
|
||||
*
|
||||
* @param source the source of the evidence, a source that is {@code null} indicates any source should match.
|
||||
* @param name the non-{@code null} name of the evidence.
|
||||
* @param value the non-{@code null} value of the evidence.
|
||||
* @param regex whether value is a regex.
|
||||
* @param confidence the confidence of the evidence, a confidence that is {@code null} indicates any confidence should match.
|
||||
*/
|
||||
public EvidenceMatcher(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
this.source = source;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.confidence = confidence;
|
||||
this.regex = regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name that the {@link Evidence} should have for a match.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* The source that the {@link Evidence} should have for a match.
|
||||
* A {@code null}-value is allowed and functions as a wildcard.
|
||||
*/
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* The value that the {@link Evidence} should have for a match.
|
||||
*/
|
||||
private String value;
|
||||
|
||||
/**
|
||||
* Whether the {@link EvidenceMatcher#value} should be interpreted as a
|
||||
* regular expression.
|
||||
*/
|
||||
private boolean regex=false;
|
||||
|
||||
|
||||
/**
|
||||
* The confidence that the {@link Evidence} should have for a match.
|
||||
* A {@code null}-value is allowed and functions as a wildcard.
|
||||
*/
|
||||
private Confidence confidence;
|
||||
|
||||
/**
|
||||
* Tests whether the given Evidence matches this EvidenceMatcher.
|
||||
* @param evidence
|
||||
* @return whehter the evidence matches this matcher.
|
||||
*/
|
||||
public boolean matches(Evidence evidence) {
|
||||
return sourceMatches(evidence)
|
||||
&& confidenceMatches(evidence)
|
||||
&& name.equalsIgnoreCase(evidence.getName())
|
||||
&& valueMatches(evidence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard toString() implementation.
|
||||
*
|
||||
* @return the string representation of the object
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HintEvidenceMatcher{" + "name=" + name + ", source=" + source + ", value=" + value + ", confidence=" + confidence + ", regex=" + regex +'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* package-private getter to allow testability of the parser without mocking
|
||||
* @return The name property
|
||||
*/
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* package-private getter to allow testability of the parser without mocking
|
||||
* @return The source property
|
||||
*/
|
||||
String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* package-private getter to allow testability of the parser without mocking
|
||||
* @return The value property
|
||||
*/
|
||||
String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* package-private getter to allow testability of the parser without mocking
|
||||
* @return The regex property
|
||||
*/
|
||||
boolean isRegex() {
|
||||
return regex;
|
||||
}
|
||||
|
||||
/**
|
||||
* package-private getter to allow testability of the parser without mocking
|
||||
* @return The confidence property
|
||||
*/
|
||||
Confidence getConfidence() {
|
||||
return confidence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the value of the evidence matches this matcher.
|
||||
* When {@link #isRegEx()} is {@code true} value is used as a
|
||||
* {@link java.util.regex.Pattern} that it should match. Otherwise the
|
||||
* value must be case-insensitive equal to the evidence's value.
|
||||
*
|
||||
* Uses {@link Evidence#getValue(java.lang.Boolean) to avoid setting
|
||||
* evidences to used while just checking for a match.
|
||||
*/
|
||||
private boolean valueMatches(Evidence evidence) {
|
||||
boolean result;
|
||||
if (regex) {
|
||||
result = Pattern.matches(value, evidence.getValue(Boolean.FALSE));
|
||||
} else {
|
||||
result = value.equalsIgnoreCase(evidence.getValue(Boolean.FALSE));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the source of the evidence matches this matcher.
|
||||
* If our source is {@code null} any source in the evidence matches.
|
||||
* Otherwise the source in the evidence must be case-insensitive equal to
|
||||
* our source.
|
||||
*
|
||||
* @param evidence The evidence to inspect
|
||||
* @return {@code true} is the source of the evidence matches, false otherwise.
|
||||
*/
|
||||
private boolean sourceMatches(Evidence evidence) {
|
||||
return this.source == null || source.equalsIgnoreCase(evidence.getSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the confidence of the evidence matches this matcher.
|
||||
* If our confidence is {@code null} any confidence in the evidence matches.
|
||||
* Otherwise the confidence in the evidence must be exactly equal to our
|
||||
* confidence.
|
||||
*
|
||||
* @param evidence The evidence to inspect
|
||||
* @return {@code true} is the confidence of the evidence matches, false otherwise.
|
||||
*/
|
||||
private boolean confidenceMatches(Evidence evidence) {
|
||||
return this.confidence == null || confidence.equals(evidence.getConfidence());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ package org.owasp.dependencycheck.xml.hints;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.utils.XmlUtils;
|
||||
import org.owasp.dependencycheck.xml.suppression.PropertyType;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
@@ -199,7 +200,20 @@ public class HintHandler extends DefaultHandler {
|
||||
final String source = attr.getValue(SOURCE);
|
||||
final String name = attr.getValue(NAME);
|
||||
final String value = attr.getValue(VALUE);
|
||||
final Confidence confidence = Confidence.valueOf(attr.getValue(CONFIDENCE));
|
||||
final Confidence confidence;
|
||||
final String confidenceAttribute = attr.getValue(CONFIDENCE);
|
||||
if (confidenceAttribute == null) {
|
||||
confidence = null;
|
||||
} else {
|
||||
confidence = Confidence.valueOf(confidenceAttribute);
|
||||
}
|
||||
final boolean regex;
|
||||
final String regexAttribute = attr.getValue(REGEX);
|
||||
if (regexAttribute == null) {
|
||||
regex = false;
|
||||
} else {
|
||||
regex = XmlUtils.parseBoolean(regexAttribute);
|
||||
}
|
||||
switch (hintType) {
|
||||
case VENDOR:
|
||||
switch (nodeType) {
|
||||
@@ -207,10 +221,10 @@ public class HintHandler extends DefaultHandler {
|
||||
rule.addAddVendor(source, name, value, confidence);
|
||||
break;
|
||||
case REMOVE:
|
||||
rule.addRemoveVendor(source, name, value, confidence);
|
||||
rule.addRemoveVendor(source, name, value, regex, confidence);
|
||||
break;
|
||||
case GIVEN:
|
||||
rule.addGivenVendor(source, name, value, confidence);
|
||||
rule.addGivenVendor(source, name, value, regex, confidence);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -222,10 +236,10 @@ public class HintHandler extends DefaultHandler {
|
||||
rule.addAddProduct(source, name, value, confidence);
|
||||
break;
|
||||
case REMOVE:
|
||||
rule.addRemoveProduct(source, name, value, confidence);
|
||||
rule.addRemoveProduct(source, name, value, regex, confidence);
|
||||
break;
|
||||
case GIVEN:
|
||||
rule.addGivenProduct(source, name, value, confidence);
|
||||
rule.addGivenProduct(source, name, value, regex, confidence);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -237,10 +251,10 @@ public class HintHandler extends DefaultHandler {
|
||||
rule.addAddVersion(source, name, value, confidence);
|
||||
break;
|
||||
case REMOVE:
|
||||
rule.addRemoveVersion(source, name, value, confidence);
|
||||
rule.addRemoveVersion(source, name, value, regex, confidence);
|
||||
break;
|
||||
case GIVEN:
|
||||
rule.addGivenVersion(source, name, value, confidence);
|
||||
rule.addGivenVersion(source, name, value, regex, confidence);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -66,12 +66,17 @@ public class HintParser {
|
||||
/**
|
||||
* The schema for the hint XML files.
|
||||
*/
|
||||
private static final String HINT_SCHEMA = "schema/dependency-hint.1.2.xsd";
|
||||
private static final String HINT_SCHEMA_1_2 = "schema/dependency-hint.1.2.xsd";
|
||||
|
||||
/**
|
||||
* The schema for the hint XML files.
|
||||
*/
|
||||
private static final String HINT_SCHEMA_OLD = "schema/dependency-hint.1.1.xsd";
|
||||
private static final String HINT_SCHEMA_1_1 = "schema/dependency-hint.1.1.xsd";
|
||||
|
||||
/**
|
||||
* The schema for the hint XML files.
|
||||
*/
|
||||
private static final String HINT_SCHEMA_1_3 = "schema/dependency-hint.1.3.xsd";
|
||||
|
||||
/**
|
||||
* Parses the given XML file and returns a list of the hints contained.
|
||||
@@ -82,19 +87,11 @@ public class HintParser {
|
||||
*/
|
||||
public Hints parseHints(File file) throws HintParseException {
|
||||
//TODO there must be a better way to determine which schema to use for validation.
|
||||
try {
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
return parseHints(fis);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.debug("", ex);
|
||||
throw new HintParseException(ex);
|
||||
}
|
||||
} catch (SAXException ex) {
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
return parseHints(fis, HINT_SCHEMA_OLD);
|
||||
} catch (SAXException | IOException ex1) {
|
||||
throw new HintParseException(ex);
|
||||
}
|
||||
} catch (SAXException | IOException ex) {
|
||||
LOGGER.debug("", ex);
|
||||
throw new HintParseException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,23 +105,13 @@ public class HintParser {
|
||||
* @throws SAXException thrown if the XML cannot be parsed
|
||||
*/
|
||||
public Hints parseHints(InputStream inputStream) throws HintParseException, SAXException {
|
||||
return parseHints(inputStream, HINT_SCHEMA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given XML stream and returns a list of the hint rules
|
||||
* contained.
|
||||
*
|
||||
* @param inputStream an InputStream containing hint rules
|
||||
* @param schema the XSD to use to validate the XML against
|
||||
* @return a list of hint rules
|
||||
* @throws HintParseException thrown if the XML cannot be parsed
|
||||
* @throws SAXException thrown if the XML cannot be parsed
|
||||
*/
|
||||
private Hints parseHints(InputStream inputStream, String schema) throws HintParseException, SAXException {
|
||||
try (InputStream schemaStream = FileUtils.getResourceAsStream(schema)) {
|
||||
try (
|
||||
InputStream schemaStream13 = FileUtils.getResourceAsStream(HINT_SCHEMA_1_3);
|
||||
InputStream schemaStream12 = FileUtils.getResourceAsStream(HINT_SCHEMA_1_2);
|
||||
InputStream schemaStream11 = FileUtils.getResourceAsStream(HINT_SCHEMA_1_1);
|
||||
) {
|
||||
final HintHandler handler = new HintHandler();
|
||||
final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream);
|
||||
final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream13, schemaStream12, schemaStream11);
|
||||
final XMLReader xmlReader = saxParser.getXMLReader();
|
||||
xmlReader.setErrorHandler(new HintErrorHandler());
|
||||
xmlReader.setContentHandler(handler);
|
||||
|
||||
@@ -39,15 +39,15 @@ public class HintRule {
|
||||
/**
|
||||
* The list of vendor evidence that is being matched.
|
||||
*/
|
||||
private final List<Evidence> givenVendor = new ArrayList<>();
|
||||
private final List<EvidenceMatcher> givenVendor = new ArrayList<>();
|
||||
/**
|
||||
* The list of product evidence that is being matched.
|
||||
*/
|
||||
private final List<Evidence> givenProduct = new ArrayList<>();
|
||||
private final List<EvidenceMatcher> givenProduct = new ArrayList<>();
|
||||
/**
|
||||
* The list of product evidence that is being matched.
|
||||
*/
|
||||
private final List<Evidence> givenVersion = new ArrayList<>();
|
||||
private final List<EvidenceMatcher> givenVersion = new ArrayList<>();
|
||||
/**
|
||||
* The list of vendor hints to add.
|
||||
*/
|
||||
@@ -62,17 +62,17 @@ public class HintRule {
|
||||
private final List<Evidence> addVersion = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The list of vendor hints to add.
|
||||
* The list of vendor hints to remove.
|
||||
*/
|
||||
private final List<Evidence> removeVendor = new ArrayList<>();
|
||||
private final List<EvidenceMatcher> removeVendor = new ArrayList<>();
|
||||
/**
|
||||
* The list of product evidence to add.
|
||||
* The list of product evidence to remove.
|
||||
*/
|
||||
private final List<Evidence> removeProduct = new ArrayList<>();
|
||||
private final List<EvidenceMatcher> removeProduct = new ArrayList<>();
|
||||
/**
|
||||
* The list of version evidence to add.
|
||||
* The list of version evidence to remove.
|
||||
*/
|
||||
private final List<Evidence> removeVersion = new ArrayList<>();
|
||||
private final List<EvidenceMatcher> removeVersion = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Adds the filename evidence to the collection.
|
||||
@@ -98,10 +98,11 @@ public class HintRule {
|
||||
* @param source the source of the evidence
|
||||
* @param name the name of the evidence
|
||||
* @param value the value of the evidence
|
||||
* @param regex whether value is a regex
|
||||
* @param confidence the confidence of the evidence
|
||||
*/
|
||||
public void addGivenProduct(String source, String name, String value, Confidence confidence) {
|
||||
givenProduct.add(new Evidence(source, name, value, confidence));
|
||||
public void addGivenProduct(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
givenProduct.add(new EvidenceMatcher(source, name, value, regex, confidence));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +110,7 @@ public class HintRule {
|
||||
*
|
||||
* @return the value of givenProduct
|
||||
*/
|
||||
public List<Evidence> getGivenProduct() {
|
||||
public List<EvidenceMatcher> getGivenProduct() {
|
||||
return givenProduct;
|
||||
}
|
||||
|
||||
@@ -119,10 +120,11 @@ public class HintRule {
|
||||
* @param source the source of the evidence
|
||||
* @param name the name of the evidence
|
||||
* @param value the value of the evidence
|
||||
* @param regex whether value is a regex
|
||||
* @param confidence the confidence of the evidence
|
||||
*/
|
||||
public void addGivenVendor(String source, String name, String value, Confidence confidence) {
|
||||
givenVendor.add(new Evidence(source, name, value, confidence));
|
||||
public void addGivenVendor(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
givenVendor.add(new EvidenceMatcher(source, name, value, regex, confidence));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +132,7 @@ public class HintRule {
|
||||
*
|
||||
* @return the value of givenVendor
|
||||
*/
|
||||
public List<Evidence> getGivenVendor() {
|
||||
public List<EvidenceMatcher> getGivenVendor() {
|
||||
return givenVendor;
|
||||
}
|
||||
|
||||
@@ -203,17 +205,18 @@ public class HintRule {
|
||||
* @param source the source of the evidence
|
||||
* @param name the name of the evidence
|
||||
* @param value the value of the evidence
|
||||
* @param regex whether value is a regex
|
||||
* @param confidence the confidence of the evidence
|
||||
*/
|
||||
public void addRemoveVendor(String source, String name, String value, Confidence confidence) {
|
||||
removeVendor.add(new Evidence(source, name, value, confidence));
|
||||
public void addRemoveVendor(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
removeVendor.add(new EvidenceMatcher(source, name, value, regex, confidence));
|
||||
}
|
||||
/**
|
||||
* Get the value of removeVendor.
|
||||
*
|
||||
* @return the value of removeVendor
|
||||
*/
|
||||
public List<Evidence> getRemoveVendor() {
|
||||
public List<EvidenceMatcher> getRemoveVendor() {
|
||||
return removeVendor;
|
||||
}
|
||||
/**
|
||||
@@ -222,17 +225,18 @@ public class HintRule {
|
||||
* @param source the source of the evidence
|
||||
* @param name the name of the evidence
|
||||
* @param value the value of the evidence
|
||||
* @param regex whether value is a regex
|
||||
* @param confidence the confidence of the evidence
|
||||
*/
|
||||
public void addRemoveProduct(String source, String name, String value, Confidence confidence) {
|
||||
removeProduct.add(new Evidence(source, name, value, confidence));
|
||||
public void addRemoveProduct(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
removeProduct.add(new EvidenceMatcher(source, name, value, regex, confidence));
|
||||
}
|
||||
/**
|
||||
* Get the value of removeProduct.
|
||||
*
|
||||
* @return the value of removeProduct
|
||||
*/
|
||||
public List<Evidence> getRemoveProduct() {
|
||||
public List<EvidenceMatcher> getRemoveProduct() {
|
||||
return removeProduct;
|
||||
}
|
||||
/**
|
||||
@@ -241,17 +245,18 @@ public class HintRule {
|
||||
* @param source the source of the evidence
|
||||
* @param name the name of the evidence
|
||||
* @param value the value of the evidence
|
||||
* @param regex whether value is a regex
|
||||
* @param confidence the confidence of the evidence
|
||||
*/
|
||||
public void addRemoveVersion(String source, String name, String value, Confidence confidence) {
|
||||
removeVersion.add(new Evidence(source, name, value, confidence));
|
||||
public void addRemoveVersion(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
removeVersion.add(new EvidenceMatcher(source, name, value, regex, confidence));
|
||||
}
|
||||
/**
|
||||
* Get the value of removeVersion.
|
||||
*
|
||||
* @return the value of removeVersion
|
||||
*/
|
||||
public List<Evidence> getRemoveVersion() {
|
||||
public List<EvidenceMatcher> getRemoveVersion() {
|
||||
return removeVersion;
|
||||
}
|
||||
/**
|
||||
@@ -260,17 +265,18 @@ public class HintRule {
|
||||
* @param source the source of the evidence
|
||||
* @param name the name of the evidence
|
||||
* @param value the value of the evidence
|
||||
* @param regex whether value is a regex
|
||||
* @param confidence the confidence of the evidence
|
||||
*/
|
||||
public void addGivenVersion(String source, String name, String value, Confidence confidence) {
|
||||
givenVersion.add(new Evidence(source, name, value, confidence));
|
||||
public void addGivenVersion(String source, String name, String value, boolean regex, Confidence confidence) {
|
||||
givenVersion.add(new EvidenceMatcher(source, name, value, regex, confidence));
|
||||
}
|
||||
/**
|
||||
* Get the value of givenVersion.
|
||||
*
|
||||
* @return the value of givenVersion
|
||||
*/
|
||||
public List<Evidence> getGivenVersion() {
|
||||
public List<EvidenceMatcher> getGivenVersion() {
|
||||
return givenVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema id="hints"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="https://jeremylong.github.io/DependencyCheck/dependency-hint.1.3.xsd"
|
||||
xmlns:dc="https://jeremylong.github.io/DependencyCheck/dependency-hint.1.3.xsd">
|
||||
|
||||
<xs:simpleType name="type">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="vendor"/>
|
||||
<xs:enumeration value="product"/>
|
||||
<xs:enumeration value="version"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="confidence">
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="HIGHEST"/>
|
||||
<xs:enumeration value="HIGH"/>
|
||||
<xs:enumeration value="MEDIUM"/>
|
||||
<xs:enumeration value="LOW"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:complexType name="evidenceMatcher">
|
||||
<xs:attribute name="type" use="required" type="dc:type"/>
|
||||
<xs:attribute name="source" use="optional" type="xs:string"/>
|
||||
<xs:attribute name="name" use="required" type="xs:string"/>
|
||||
<xs:attribute name="value" use="required" type="xs:string"/>
|
||||
<xs:attribute name="regex" use="optional" type="xs:boolean" default="false"/>
|
||||
<xs:attribute name="confidence" use="optional" type="dc:confidence"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="evidence">
|
||||
<xs:attribute name="type" use="required" type="dc:type"/>
|
||||
<xs:attribute name="source" use="required" type="xs:string"/>
|
||||
<xs:attribute name="name" use="required" type="xs:string"/>
|
||||
<xs:attribute name="value" use="required" type="xs:string"/>
|
||||
<xs:attribute name="confidence" use="required" type="dc:confidence"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="fileName">
|
||||
<xs:attribute name="contains" use="required" type="xs:string"/>
|
||||
<xs:attribute name="regex" use="optional" type="xs:boolean" default="false"/>
|
||||
<xs:attribute name="caseSensitive" use="optional" type="xs:boolean" default="false"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="given">
|
||||
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:element name="evidence" type="dc:evidenceMatcher"/>
|
||||
<xs:element name="fileName" type="dc:fileName"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="add">
|
||||
<xs:sequence minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:element name="evidence" type="dc:evidence"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="remove">
|
||||
<xs:sequence minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:element name="evidence" type="dc:evidenceMatcher"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="hint">
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="given" type="dc:given"/>
|
||||
<xs:choice minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="add" type="dc:add"/>
|
||||
<xs:element name="remove" type="dc:remove"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="duplicatingHint">
|
||||
<xs:attribute name="value" use="required" type="xs:string"/>
|
||||
<xs:attribute name="duplicate" use="required" type="xs:string"/>
|
||||
</xs:complexType>
|
||||
<xs:element name="hints">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="hint" type="dc:hint"/>
|
||||
</xs:sequence>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="vendorDuplicatingHint" type="dc:duplicatingHint"/>
|
||||
</xs:sequence>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2017 OWASP.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.owasp.dependencycheck.xml.hints;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import org.junit.Test;
|
||||
import org.owasp.dependencycheck.dependency.Confidence;
|
||||
import org.owasp.dependencycheck.dependency.Evidence;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link EvidenceMatcher}.
|
||||
*
|
||||
* @author Hans Aikema
|
||||
*/
|
||||
public class EvidenceMatcherTest {
|
||||
|
||||
private static final Evidence EVIDENCE_HIGHEST = new Evidence("source", "name", "value", Confidence.HIGHEST);
|
||||
private static final Evidence EVIDENCE_HIGH = new Evidence("source", "name", "value", Confidence.HIGH);
|
||||
private static final Evidence EVIDENCE_MEDIUM = new Evidence("source", "name", "value", Confidence.MEDIUM);
|
||||
private static final Evidence EVIDENCE_MEDIUM_SECOND_SOURCE = new Evidence("source 2", "name", "value", Confidence.MEDIUM);
|
||||
private static final Evidence EVIDENCE_LOW = new Evidence("source", "name", "value", Confidence.LOW);
|
||||
|
||||
@Test
|
||||
public void testExactMatching() throws Exception {
|
||||
final EvidenceMatcher exactMatcherHighest = new EvidenceMatcher("source", "name", "value", false, Confidence.HIGHEST);
|
||||
assertTrue("exact matcher should match EVIDENCE_HIGHEST", exactMatcherHighest.matches(EVIDENCE_HIGHEST));
|
||||
assertFalse("exact matcher should not match EVIDENCE_HIGH", exactMatcherHighest.matches(EVIDENCE_HIGH));
|
||||
assertFalse("exact matcher should not match EVIDENCE_MEDIUM", exactMatcherHighest.matches(EVIDENCE_MEDIUM));
|
||||
assertFalse("exact matcher should not match EVIDENCE_MEDIUM_SECOND_SOURCE", exactMatcherHighest.matches(EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertFalse("exact matcher should not match EVIDENCE_LOW", exactMatcherHighest.matches(EVIDENCE_LOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcardConfidenceMatching() throws Exception {
|
||||
final EvidenceMatcher wildcardCofidenceMatcher = new EvidenceMatcher("source", "name", "value", false, null);
|
||||
assertTrue("wildcard confidence matcher should match EVIDENCE_HIGHEST", wildcardCofidenceMatcher.matches(EVIDENCE_HIGHEST));
|
||||
assertTrue("wildcard confidence matcher should match EVIDENCE_HIGH", wildcardCofidenceMatcher.matches(EVIDENCE_HIGH));
|
||||
assertTrue("wildcard confidence matcher should match EVIDENCE_MEDIUM", wildcardCofidenceMatcher.matches(EVIDENCE_MEDIUM));
|
||||
assertFalse("wildcard confidence matcher should not match EVIDENCE_MEDIUM_SECOND_SOURCE", wildcardCofidenceMatcher.matches(EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertTrue("wildcard confidence matcher should match EVIDENCE_LOW", wildcardCofidenceMatcher.matches(EVIDENCE_LOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildcardSourceMatching() throws Exception {
|
||||
final EvidenceMatcher wildcardSourceMatcher = new EvidenceMatcher(null, "name", "value", false, Confidence.MEDIUM);
|
||||
assertFalse("wildcard source matcher should not match EVIDENCE_HIGHEST", wildcardSourceMatcher.matches(EVIDENCE_HIGHEST));
|
||||
assertFalse("wildcard source matcher should not match EVIDENCE_HIGH", wildcardSourceMatcher.matches(EVIDENCE_HIGH));
|
||||
assertTrue("wildcard source matcher should match EVIDENCE_MEDIUM", wildcardSourceMatcher.matches(EVIDENCE_MEDIUM));
|
||||
assertTrue("wildcard source matcher should match EVIDENCE_MEDIUM_SECOND_SOURCE", wildcardSourceMatcher.matches(EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertFalse("wildcard source matcher should not match EVIDENCE_LOW", wildcardSourceMatcher.matches(EVIDENCE_LOW));
|
||||
}
|
||||
|
||||
private static final Evidence REGEX_EVIDENCE_HIGHEST = new Evidence("source", "name", "value 1", Confidence.HIGHEST);
|
||||
private static final Evidence REGEX_EVIDENCE_HIGH = new Evidence("source", "name", "value 2", Confidence.HIGH);
|
||||
private static final Evidence REGEX_EVIDENCE_MEDIUM = new Evidence("source", "name", "Value will not match because of case", Confidence.MEDIUM);
|
||||
private static final Evidence REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE = new Evidence("source 2", "name", "yet another value that will match", Confidence.MEDIUM);
|
||||
private static final Evidence REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE = new Evidence("source 3", "name", "and even more values to match", Confidence.MEDIUM);
|
||||
private static final Evidence REGEX_EVIDENCE_LOW = new Evidence("source", "name", "val that should not match", Confidence.LOW);
|
||||
|
||||
@Test
|
||||
public void testRegExMatching() throws Exception {
|
||||
final EvidenceMatcher regexMediumMatcher = new EvidenceMatcher("source 2", "name", ".*value.*", true, Confidence.MEDIUM);
|
||||
assertFalse("regex medium matcher should not match REGEX_EVIDENCE_HIGHEST", regexMediumMatcher.matches(REGEX_EVIDENCE_HIGHEST));
|
||||
assertFalse("regex medium matcher should not match REGEX_EVIDENCE_HIGH", regexMediumMatcher.matches(REGEX_EVIDENCE_HIGH));
|
||||
assertFalse("regex medium matcher should not match REGEX_EVIDENCE_MEDIUM", regexMediumMatcher.matches(REGEX_EVIDENCE_MEDIUM));
|
||||
assertTrue("regex medium matcher should match REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE", regexMediumMatcher.matches(REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertFalse("regex medium matcher should not match REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE", regexMediumMatcher.matches(REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE));
|
||||
assertFalse("regex medium matcher should not match REGEX_EVIDENCE_LOW", regexMediumMatcher.matches(REGEX_EVIDENCE_LOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegExWildcardSourceMatching() throws Exception {
|
||||
final EvidenceMatcher regexMediumWildcardSourceMatcher = new EvidenceMatcher(null, "name", "^.*v[al]{2,2}ue[a-z ]+$", true, Confidence.MEDIUM);
|
||||
assertFalse("regex medium wildcard source matcher should not match REGEX_EVIDENCE_HIGHEST", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_HIGHEST));
|
||||
assertFalse("regex medium wildcard source matcher should not match REGEX_EVIDENCE_HIGH", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_HIGH));
|
||||
assertFalse("regex medium wildcard source matcher should not match REGEX_EVIDENCE_MEDIUM", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM));
|
||||
assertTrue("regex medium wildcard source matcher should match REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertTrue("regex medium wildcard source matcher should match REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE));
|
||||
assertFalse("regex medium wildcard source matcher should not match REGEX_EVIDENCE_LOW", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_LOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegExWildcardSourceWildcardConfidenceMatching() throws Exception {
|
||||
final EvidenceMatcher regexMediumWildcardSourceMatcher = new EvidenceMatcher(null, "name", ".*value.*", true, null);
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_HIGHEST", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_HIGHEST));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_HIGH", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_HIGH));
|
||||
assertFalse("regex wildcard source wildcard confidence matcher should not match REGEX_EVIDENCE_MEDIUM", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE));
|
||||
assertFalse("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_LOW", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_LOW));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegExWildcardSourceWildcardConfidenceFourMatching() throws Exception {
|
||||
final EvidenceMatcher regexMediumWildcardSourceMatcher = new EvidenceMatcher(null, "name", "^.*[Vv][al]{2,2}[a-z ]+$", true, null);
|
||||
assertFalse("regex wildcard source wildcard confidence matcher should not match REGEX_EVIDENCE_HIGHEST", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_HIGHEST));
|
||||
assertFalse("regex wildcard source wildcard confidence matcher should not match REGEX_EVIDENCE_HIGH", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_HIGH));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_MEDIUM", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM_SECOND_SOURCE));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_MEDIUM_THIRD_SOURCE));
|
||||
assertTrue("regex wildcard source wildcard confidence matcher should match REGEX_EVIDENCE_LOW", regexMediumWildcardSourceMatcher.matches(REGEX_EVIDENCE_LOW));
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,11 @@ package org.owasp.dependencycheck.xml.hints;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.owasp.dependencycheck.BaseTest;
|
||||
|
||||
/**
|
||||
@@ -29,6 +32,9 @@ import org.owasp.dependencycheck.BaseTest;
|
||||
*/
|
||||
public class HintParserTest extends BaseTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown= ExpectedException.none();
|
||||
|
||||
/**
|
||||
* Test of parseHints method, of class HintParser.
|
||||
*/
|
||||
@@ -59,6 +65,27 @@ public class HintParserTest extends BaseTest {
|
||||
assertEquals("sun duplicates vendor oracle", "oracle", results.getVendorDuplicatingHintRules().get(0).getDuplicate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the application of the correct XSD by the parser by using a
|
||||
* hints-file with namespace
|
||||
* {@code https://jeremylong.github.io/DependencyCheck/dependency-hint.1.1.xsd}
|
||||
* that is using the version evidence for {@code<given>} that was introduced
|
||||
* with namespace
|
||||
* {@code https://jeremylong.github.io/DependencyCheck/dependency-hint.1.2.xsd}.
|
||||
* This should yield a specific SAXParseException that gets wrapped into a
|
||||
* HintParseException. We check for the correct error by searching for the
|
||||
* error-message of the SAXParser in the exception's message.
|
||||
*/
|
||||
@Test
|
||||
public void testParseHintsXSDSelection() throws Exception {
|
||||
thrown.expect(org.owasp.dependencycheck.xml.hints.HintParseException.class);
|
||||
thrown.expectMessage("Line=7, Column=133: cvc-enumeration-valid: Value 'version' is not facet-valid with respect to enumeration '[vendor, product]'. It must be a value from the enumeration.");
|
||||
File file = BaseTest.getResourceAsFile(this, "hints_invalid.xml");
|
||||
HintParser instance = new HintParser();
|
||||
instance.parseHints(file);
|
||||
Assert.fail("A parser exception for an XML-schema violation should have been thrown");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of parseHints method, of class HintParser.
|
||||
*/
|
||||
@@ -107,4 +134,60 @@ public class HintParserTest extends BaseTest {
|
||||
assertEquals("add version name not found in hint 1", "remove version name", results.getHintRules().get(1).getRemoveVersion().get(0).getName());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of parseHints method, of class HintParser.
|
||||
*/
|
||||
@Test
|
||||
public void testParseHintsWithRegex() throws Exception {
|
||||
InputStream ins = BaseTest.getResourceAsStream(this, "hints_13.xml");
|
||||
HintParser instance = new HintParser();
|
||||
Hints results = instance.parseHints(ins);
|
||||
assertEquals("Zero duplicating hints should have been read", 0, results.getVendorDuplicatingHintRules().size());
|
||||
assertEquals("Two hint rules should have been read", 2, results.getHintRules().size());
|
||||
|
||||
assertEquals("One given product should have been read in hint 0", 1, results.getHintRules().get(0).getGivenProduct().size());
|
||||
assertEquals("One given vendor should have been read in hint 0", 1, results.getHintRules().get(0).getGivenVendor().size());
|
||||
assertEquals("One given version should have been read in hint 0", 1, results.getHintRules().get(0).getGivenVersion().size());
|
||||
|
||||
assertEquals("One add product should have been read in hint 0", 1, results.getHintRules().get(0).getAddProduct().size());
|
||||
assertEquals("One add vendor should have been read in hint 0", 1, results.getHintRules().get(0).getAddVendor().size());
|
||||
assertEquals("One add version should have been read in hint 0", 1, results.getHintRules().get(0).getAddVersion().size());
|
||||
assertEquals("Zero remove product should have been read in hint 0", 0, results.getHintRules().get(0).getRemoveProduct().size());
|
||||
assertEquals("Zero remove vendor should have been read in hint 0", 0, results.getHintRules().get(0).getRemoveVendor().size());
|
||||
assertEquals("Zero remove version should have been read in hint 0", 0, results.getHintRules().get(0).getRemoveVersion().size());
|
||||
|
||||
assertEquals("Zero given product should have been read in hint 1", 0, results.getHintRules().get(1).getGivenProduct().size());
|
||||
assertEquals("Zero given vendor should have been read in hint 1", 0, results.getHintRules().get(1).getGivenVendor().size());
|
||||
assertEquals("One given version should have been read in hint 1", 1, results.getHintRules().get(1).getGivenVersion().size());
|
||||
|
||||
assertEquals("One remove product should have been read in hint 1", 1, results.getHintRules().get(1).getRemoveProduct().size());
|
||||
assertEquals("One remove vendor should have been read in hint 1", 1, results.getHintRules().get(1).getRemoveVendor().size());
|
||||
assertEquals("One remove version should have been read in hint 1", 1, results.getHintRules().get(1).getRemoveVersion().size());
|
||||
assertEquals("Zero add product should have been read in hint 1", 0, results.getHintRules().get(1).getAddProduct().size());
|
||||
assertEquals("Zero add vendor should have been read in hint 1", 0, results.getHintRules().get(1).getAddVendor().size());
|
||||
assertEquals("Zero add version should have been read in hint 1", 0, results.getHintRules().get(1).getAddVersion().size());
|
||||
|
||||
assertEquals("add product name not found in hint 0", "add product name", results.getHintRules().get(0).getAddProduct().get(0).getName());
|
||||
assertEquals("add vendor name not found in hint 0", "add vendor name", results.getHintRules().get(0).getAddVendor().get(0).getName());
|
||||
assertEquals("add version name not found in hint 0", "add version name", results.getHintRules().get(0).getAddVersion().get(0).getName());
|
||||
|
||||
assertEquals("given product name not found in hint 0", "given product name", results.getHintRules().get(0).getGivenProduct().get(0).getName());
|
||||
assertEquals("value not registered to be a regex for given product in hint 0", true, results.getHintRules().get(0).getGivenProduct().get(0).isRegex());
|
||||
assertEquals("given vendor name not found in hint 0", "given vendor name", results.getHintRules().get(0).getGivenVendor().get(0).getName());
|
||||
assertEquals("value not registered to be a regex for given vendor in hint 0", true, results.getHintRules().get(0).getGivenVendor().get(0).isRegex());
|
||||
assertEquals("given version name not found in hint 0", "given version name", results.getHintRules().get(0).getGivenVersion().get(0).getName());
|
||||
assertEquals("value not registered to not be a regex for given version in hint 0", false, results.getHintRules().get(0).getGivenVersion().get(0).isRegex());
|
||||
|
||||
assertEquals("given version name not found in hint 1", "given version name", results.getHintRules().get(1).getGivenVersion().get(0).getName());
|
||||
assertEquals("value not registered to not be a regex by default for given version in hint 1", false, results.getHintRules().get(1).getRemoveProduct().get(0).isRegex());
|
||||
|
||||
assertEquals("remove product name not found in hint 1", "remove product name", results.getHintRules().get(1).getRemoveProduct().get(0).getName());
|
||||
assertEquals("value not registered to not be a regex for product removal in hint 1", false, results.getHintRules().get(1).getRemoveProduct().get(0).isRegex());
|
||||
assertEquals("remove vendor name not found in hint 1", "remove vendor name", results.getHintRules().get(1).getRemoveVendor().get(0).getName());
|
||||
assertEquals("value not registered to not be a regex for vendor removal in hint 1", false, results.getHintRules().get(1).getRemoveVendor().get(0).isRegex());
|
||||
assertEquals("remove version name not found in hint 1", "remove version name", results.getHintRules().get(1).getRemoveVersion().get(0).getName());
|
||||
assertEquals("value not defaulted to not be a regex for vendor removal in hint 1", false, results.getHintRules().get(1).getRemoveVersion().get(0).isRegex());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
25
dependency-check-core/src/test/resources/hints_13.xml
Normal file
25
dependency-check-core/src/test/resources/hints_13.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<hints xmlns="https://jeremylong.github.io/DependencyCheck/dependency-hint.1.3.xsd">
|
||||
<hint>
|
||||
<given><!-- NOTE: These are OR conditions -->
|
||||
<evidence type="product" source="product source" name="given product name" value="value" regex="true" confidence="HIGH"/>
|
||||
<evidence type="vendor" source="vendor source" name="given vendor name" value="value" regex="1" confidence="HIGH"/>
|
||||
<evidence type="version" source="version source" name="given version name" value="value" regex="false" confidence="HIGH"/>
|
||||
</given>
|
||||
<add>
|
||||
<evidence type="product" source="hint analyzer" name="add product name" value="product" confidence="HIGH"/>
|
||||
<evidence type="vendor" source="hint analyzer" name="add vendor name" value="vendor" confidence="HIGH"/>
|
||||
<evidence type="version" source="hint analyzer" name="add version name" value="value" confidence="HIGH"/>
|
||||
</add>
|
||||
</hint>
|
||||
<hint>
|
||||
<given>
|
||||
<evidence type="version" source="version source" name="given version name" value="1.2.3" confidence="HIGH"/>
|
||||
</given>
|
||||
<remove>
|
||||
<evidence type="product" source="hint analyzer" name="remove product name" value="product" regex="false" confidence="HIGH"/>
|
||||
<evidence type="vendor" source="hint analyzer" name="remove vendor name" value="vendor" regex="0" confidence="HIGH"/>
|
||||
<evidence type="version" source="hint analyzer" name="remove version name" value="value" confidence="HIGH"/>
|
||||
</remove>
|
||||
</hint>
|
||||
</hints>
|
||||
26
dependency-check-core/src/test/resources/hints_invalid.xml
Normal file
26
dependency-check-core/src/test/resources/hints_invalid.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<hints xmlns="https://jeremylong.github.io/DependencyCheck/dependency-hint.1.1.xsd">
|
||||
<hint>
|
||||
<given>
|
||||
<evidence type="product" source="product source" name="given product name" value="value" confidence="HIGH"/>
|
||||
<evidence type="vendor" source="vendor source" name="given vendor name" value="value" confidence="HIGH"/>
|
||||
<evidence type="version" source="version source" name="given version name" value="value" confidence="HIGH"/>
|
||||
</given>
|
||||
<add>
|
||||
<evidence type="product" source="hint analyzer" name="add product name" value="product" confidence="HIGH"/>
|
||||
<evidence type="vendor" source="hint analyzer" name="add vendor name" value="vendor" confidence="HIGH"/>
|
||||
</add>
|
||||
</hint>
|
||||
<hint>
|
||||
<given>
|
||||
<fileName contains="spring"/>
|
||||
<fileName contains="struts" regex="true" caseSensitive="true"/>
|
||||
</given>
|
||||
<add>
|
||||
<evidence type="product" source="hint analyzer" name="product" value="product" confidence="HIGH"/>
|
||||
<evidence type="vendor" source="hint analyzer" name="vendor" value="vendor" confidence="HIGH"/>
|
||||
</add>
|
||||
</hint>
|
||||
<vendorDuplicatingHint value="sun" duplicate="oracle"/>
|
||||
<vendorDuplicatingHint value="oracle" duplicate="sun"/>
|
||||
</hints>
|
||||
@@ -61,7 +61,7 @@ public final class XmlUtils {
|
||||
/**
|
||||
* Constructs a validating secure SAX Parser.
|
||||
*
|
||||
* @param schemaStream the schema to validate the XML against
|
||||
* @param schemaStream One or more inputStreams with the schema(s) that the parser should be able to validate the XML against, one InputStream per schema
|
||||
* @return a SAX Parser
|
||||
* @throws ParserConfigurationException is thrown if there is a parser
|
||||
* configuration exception
|
||||
@@ -71,7 +71,7 @@ public final class XmlUtils {
|
||||
* feature
|
||||
* @throws SAXException is thrown if there is a SAXException
|
||||
*/
|
||||
public static SAXParser buildSecureSaxParser(InputStream schemaStream) throws ParserConfigurationException,
|
||||
public static SAXParser buildSecureSaxParser(InputStream... schemaStream) throws ParserConfigurationException,
|
||||
SAXNotRecognizedException, SAXNotSupportedException, SAXException {
|
||||
final SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
@@ -87,6 +87,32 @@ public final class XmlUtils {
|
||||
return saxParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an attribute value representing an xsd:boolean value to a boolean using
|
||||
* the rules as stated in the XML specification
|
||||
*
|
||||
* @param lexicalXSDBoolean The string-value of the boolean
|
||||
* @return the boolean value represented by {@code lexicalXSDBoolean}
|
||||
* @throws IllegalArgumentException When {@code lexicalXSDBoolean} does
|
||||
* fit the lexical space of the XSD boolean datatype
|
||||
*/
|
||||
public static boolean parseBoolean(String lexicalXSDBoolean) {
|
||||
final boolean result;
|
||||
switch (lexicalXSDBoolean) {
|
||||
case "true":
|
||||
case "1":
|
||||
result = true;
|
||||
break;
|
||||
case "false":
|
||||
case "0":
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("'"+lexicalXSDBoolean+"' is not a valid xs:boolean value");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a secure SAX Parser.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user