diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index 34685d6bf..cb74b6c07 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -251,20 +251,20 @@ public class CPEAnalyzer extends AbstractAnalyzer { * @param evidence an iterable set of evidence to concatenate * @return the new evidence text */ - private String addEvidenceWithoutDuplicateTerms(final String text, final Iterable evidence) { + @SuppressWarnings("null") + protected String addEvidenceWithoutDuplicateTerms(final String text, final Iterable evidence) { final String txt = (text == null) ? "" : text; - final StringBuilder sb = new StringBuilder(); + final StringBuilder sb = new StringBuilder(txt.length() * 2); sb.append(' ').append(txt).append(' '); for (Evidence e : evidence) { - final String value = e.getValue(); - //removed as the URLTokenizingFilter was created - //hack to get around the fact that lucene does a really good job of recognizing domains and not splitting them. -// if (value.startsWith("http://")) { -// value = value.substring(7).replaceAll("\\.", " "); -// } -// if (value.startsWith("https://")) { -// value = value.substring(8).replaceAll("\\.", " "); -// } + String value = e.getValue(); + if (value.length() > 1000) { + value = value.substring(0, 1000); + final int pos = value.lastIndexOf(" "); + if (pos > 0) { + value = value.substring(0, pos); + } + } if (sb.indexOf(" " + value + " ") < 0) { sb.append(value).append(' '); } @@ -373,7 +373,7 @@ public class CPEAnalyzer extends AbstractAnalyzer { * @return if the append was successful. */ private boolean appendWeightedSearch(StringBuilder sb, String field, String searchText, Set weightedText) { - sb.append(' ').append(field).append(":( "); + sb.append(field).append(":("); final String cleanText = cleanseText(searchText); @@ -384,6 +384,7 @@ public class CPEAnalyzer extends AbstractAnalyzer { if (weightedText == null || weightedText.isEmpty()) { LuceneUtils.appendEscapedLuceneQuery(sb, cleanText); } else { + boolean addSpace = false; final StringTokenizer tokens = new StringTokenizer(cleanText); while (tokens.hasMoreElements()) { final String word = tokens.nextToken(); @@ -395,14 +396,20 @@ public class CPEAnalyzer extends AbstractAnalyzer { LuceneUtils.appendEscapedLuceneQuery(temp, word); temp.append(WEIGHTING_BOOST); if (!word.equalsIgnoreCase(weightedStr)) { - temp.append(' '); + if (temp.length() > 0) { + temp.append(' '); + } LuceneUtils.appendEscapedLuceneQuery(temp, weightedStr); temp.append(WEIGHTING_BOOST); } break; } } - sb.append(' '); + if (addSpace) { + sb.append(' '); + } else { + addSpace = true; + } if (temp == null) { LuceneUtils.appendEscapedLuceneQuery(sb, word); } else { @@ -410,7 +417,7 @@ public class CPEAnalyzer extends AbstractAnalyzer { } } } - sb.append(" ) "); + sb.append(")"); return true; } diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml index 0b05d7645..2d45461b4 100644 --- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml +++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml @@ -64,6 +64,7 @@ 8. Context project is drupal plugin 9. mail_project is ruby library 10. ldap_project is part of type3 written in php + 11. user import project is used in drupal (i.e. php) ]]> .*(\.(dll|jar|ear|war|pom|nupkg|nuspec)|pom\.xml|package.json)$ cpe:/a:sandbox:sandbox @@ -79,6 +80,7 @@ cpe:/a:context_project:context cpe:/a:mail_project:mail cpe:/a:ldap_project:ldap + cpe:/a:user_import_project:user_import evidence = new ArrayList<>(); + evidence.add(new Evidence("test case", "value", "test", Confidence.HIGHEST)); + CPEAnalyzer instance = new CPEAnalyzer(); + String expResult = "test"; + String result = instance.addEvidenceWithoutDuplicateTerms(text, evidence); + assertEquals(expResult, result); + + text = "some"; + expResult = "some test"; + result = instance.addEvidenceWithoutDuplicateTerms(text, evidence); + assertEquals(expResult, result); + + text = "test"; + expResult = "test"; + result = instance.addEvidenceWithoutDuplicateTerms(text, evidence); + assertEquals(expResult, result); + + + StringBuilder sb = new StringBuilder(); + StringBuilder expect = new StringBuilder(); + for (int x=0;x<500;x++) { + sb.append("items "); + if (expect.length()+5<1000) { + expect.append("items "); + } + } + evidence.clear(); + evidence.add(new Evidence("test case", "value", sb.toString(), Confidence.HIGHEST)); + text = ""; + expResult = expect.toString().trim(); + result = instance.addEvidenceWithoutDuplicateTerms(text, evidence); + assertEquals(expResult, result); + } + + /** + * Test of buildSearch method, of class CPEAnalyzer. + */ + @Test + public void testBuildSearch() { + String vendor = "apache software foundation"; + String product = "lucene index"; + Set vendorWeighting = null; + Set productWeightings = null; + + CPEAnalyzer instance = new CPEAnalyzer(); + String expResult = "product:(lucene index) AND vendor:(apache software foundation)"; + String result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + + vendorWeighting = new HashSet<>(); + productWeightings = new HashSet<>(); + expResult = "product:(lucene index) AND vendor:(apache software foundation)"; + result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + + vendorWeighting.add("apache"); + expResult = "product:(lucene index) AND vendor:(apache^5 software foundation)"; + result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + + productWeightings.add("lucene"); + expResult = "product:(lucene^5 index) AND vendor:(apache^5 software foundation)"; + result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + + productWeightings.add("ignored"); + expResult = "product:(lucene^5 index) AND vendor:(apache^5 software foundation)"; + result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + + vendorWeighting.clear(); + expResult = "product:(lucene^5 index) AND vendor:(apache software foundation)"; + result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + + vendorWeighting.add("ignored"); + productWeightings.clear(); + expResult = "product:(lucene index) AND vendor:(apache software foundation)"; + result = instance.buildSearch(vendor, product, vendorWeighting, productWeightings); + assertEquals(expResult, result); + } +}