1 /* 2 * This file is part of dependency-check-core. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * Copyright (c) 2017 Hans Aikema. All Rights Reserved. 17 */ 18 package org.owasp.dependencycheck.xml.hints; 19 20 import java.util.regex.Pattern; 21 import org.owasp.dependencycheck.dependency.Confidence; 22 import org.owasp.dependencycheck.dependency.Evidence; 23 24 /** 25 * EvidenceMatcher can match one or more {@link Evidence}s. By using regular 26 * expressions for some fields and allowing omission of Evidence fields it can 27 * be used to match more than one occurrence of evidence to enable hints that 28 * work for a range of similar false positives/false negatives. 29 * 30 * The EvidenceMatcher is used for processing Evidences of a project's 31 * dependencies in conjunction with the {@code <given>} and {@code <remove>} 32 * clauses of the hints file. 33 * 34 * @author Hans Aikema 35 */ 36 public class EvidenceMatcher { 37 38 /** 39 * The name that the {@link Evidence} should have for a match. 40 */ 41 private final String name; 42 43 /** 44 * The source that the {@link Evidence} should have for a match. A 45 * {@code null}-value is allowed and functions as a wildcard. 46 */ 47 private final String source; 48 49 /** 50 * The value that the {@link Evidence} should have for a match. 51 */ 52 private final String value; 53 54 /** 55 * Whether the {@link EvidenceMatcher#value} should be interpreted as a 56 * regular expression. 57 */ 58 private final boolean regex; 59 60 /** 61 * The confidence that the {@link Evidence} should have for a match. A 62 * {@code null}-value is allowed and functions as a wildcard. 63 */ 64 private final Confidence confidence; 65 66 /** 67 * Creates a new EvidenceMatcher objects. 68 * 69 * @param source the source of the evidence, a source that is {@code null} 70 * indicates any source should match. 71 * @param name the non-{@code null} name of the evidence. 72 * @param value the non-{@code null} value of the evidence. 73 * @param regex whether value is a regex. 74 * @param confidence the confidence of the evidence, a confidence that is 75 * {@code null} indicates any confidence should match. 76 */ 77 public EvidenceMatcher(String source, String name, String value, boolean regex, Confidence confidence) { 78 this.source = source; 79 this.name = name; 80 this.value = value; 81 this.confidence = confidence; 82 this.regex = regex; 83 } 84 85 /** 86 * Tests whether the given Evidence matches this EvidenceMatcher. 87 * 88 * @param evidence the evidence to match 89 * @return whether the evidence matches this matcher 90 */ 91 public boolean matches(Evidence evidence) { 92 return sourceMatches(evidence) 93 && confidenceMatches(evidence) 94 && name.equalsIgnoreCase(evidence.getName()) 95 && valueMatches(evidence); 96 } 97 98 /** 99 * Standard toString() implementation. 100 * 101 * @return the string representation of the object 102 */ 103 @Override 104 public String toString() { 105 return "HintEvidenceMatcher{" + "name=" + name + ", source=" + source + ", value=" + value 106 + ", confidence=" + confidence + ", regex=" + regex + '}'; 107 } 108 109 /** 110 * package-private getter to allow testability of the parser without mocking. 111 * 112 * @return The name property 113 */ 114 String getName() { 115 return name; 116 } 117 118 /** 119 * package-private getter to allow testability of the parser without mocking. 120 * 121 * @return The source property 122 */ 123 String getSource() { 124 return source; 125 } 126 127 /** 128 * package-private getter to allow testability of the parser without mocking. 129 * 130 * @return The value property 131 */ 132 String getValue() { 133 return value; 134 } 135 136 /** 137 * package-private getter to allow testability of the parser without mocking. 138 * 139 * @return The regex property 140 */ 141 boolean isRegex() { 142 return regex; 143 } 144 145 /** 146 * package-private getter to allow testability of the parser without mocking. 147 * 148 * @return The confidence property 149 */ 150 Confidence getConfidence() { 151 return confidence; 152 } 153 154 /** 155 * Checks whether the value of the evidence matches this matcher. When 156 * {@link #isRegex()} is {@code true} value is used as a 157 * {@link java.util.regex.Pattern} that it should match. Otherwise the value 158 * must be case-insensitive equal to the evidence's value. 159 * 160 * @param evidence the evidence to match 161 * @return <code>true</code> if the evidence matches; otherwise 162 * <code>false</code> 163 */ 164 private boolean valueMatches(Evidence evidence) { 165 final boolean result; 166 if (regex) { 167 result = Pattern.matches(value, evidence.getValue()); 168 } else { 169 result = value.equalsIgnoreCase(evidence.getValue()); 170 } 171 return result; 172 } 173 174 /** 175 * Checks whether the source of the evidence matches this matcher. If our 176 * source is {@code null} any source in the evidence matches. Otherwise the 177 * source in the evidence must be case-insensitive equal to our source. 178 * 179 * @param evidence The evidence to inspect 180 * @return {@code true} is the source of the evidence matches, false 181 * otherwise. 182 */ 183 private boolean sourceMatches(Evidence evidence) { 184 return this.source == null || source.equalsIgnoreCase(evidence.getSource()); 185 } 186 187 /** 188 * Checks whether the confidence of the evidence matches this matcher. If 189 * our confidence is {@code null} any confidence in the evidence matches. 190 * Otherwise the confidence in the evidence must be exactly equal to our 191 * confidence. 192 * 193 * @param evidence The evidence to inspect 194 * @return {@code true} is the confidence of the evidence matches, false 195 * otherwise. 196 */ 197 private boolean confidenceMatches(Evidence evidence) { 198 return this.confidence == null || confidence.equals(evidence.getConfidence()); 199 } 200 201 }