Coverage Report - org.owasp.dependencycheck.jaxb.pom.PomUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
PomUtils
15%
16/104
0%
0/80
15.25
 
 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) 2015 Jeremy Long. All Rights Reserved.
 17  
  */
 18  
 package org.owasp.dependencycheck.jaxb.pom;
 19  
 
 20  
 import java.io.File;
 21  
 import java.io.FileInputStream;
 22  
 import java.io.IOException;
 23  
 import java.io.InputStreamReader;
 24  
 import java.util.logging.Level;
 25  
 import java.util.logging.Logger;
 26  
 import javax.xml.bind.JAXBContext;
 27  
 import javax.xml.bind.JAXBElement;
 28  
 import javax.xml.bind.JAXBException;
 29  
 import javax.xml.bind.Unmarshaller;
 30  
 import javax.xml.parsers.ParserConfigurationException;
 31  
 import javax.xml.parsers.SAXParser;
 32  
 import javax.xml.parsers.SAXParserFactory;
 33  
 import javax.xml.transform.sax.SAXSource;
 34  
 
 35  
 import org.owasp.dependencycheck.analyzer.JarAnalyzer;
 36  
 import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
 37  
 import org.owasp.dependencycheck.dependency.Confidence;
 38  
 import org.owasp.dependencycheck.dependency.Dependency;
 39  
 import org.owasp.dependencycheck.jaxb.pom.generated.Model;
 40  
 import org.owasp.dependencycheck.jaxb.pom.generated.Organization;
 41  
 import org.xml.sax.InputSource;
 42  
 import org.xml.sax.SAXException;
 43  
 import org.xml.sax.XMLFilter;
 44  
 import org.xml.sax.XMLReader;
 45  
 
 46  
 /**
 47  
  *
 48  
  * @author jeremy
 49  
  */
 50  
 public class PomUtils {
 51  
 
 52  
     /**
 53  
      * The logger.
 54  
      */
 55  1
     private static final Logger LOGGER = Logger.getLogger(PomUtils.class.getName());
 56  
 
 57  
     /**
 58  
      * The unmarshaller used to parse the pom.xml from a JAR file.
 59  
      */
 60  
     private Unmarshaller pomUnmarshaller;
 61  
 
 62  
     /**
 63  
      * Constructs a new POM Utility.
 64  
      */
 65  11
     public PomUtils() {
 66  
         try {
 67  
             //final JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.jaxb.pom.generated");
 68  11
             final JAXBContext jaxbContext = JAXBContext.newInstance(Model.class);
 69  11
             pomUnmarshaller = jaxbContext.createUnmarshaller();
 70  0
         } catch (JAXBException ex) { //guess we will just have a null pointer exception later...
 71  0
             LOGGER.log(Level.SEVERE, "Unable to load parser. See the log for more details.");
 72  0
             LOGGER.log(Level.FINE, null, ex);
 73  11
         }
 74  11
     }
 75  
 
 76  
     /**
 77  
      * Reads in the specified POM and converts it to a Model.
 78  
      *
 79  
      * @param file the pom.xml file
 80  
      * @return returns a
 81  
      * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
 82  
      * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
 83  
      */
 84  
     public Model readPom(File file) throws AnalysisException {
 85  0
         Model model = null;
 86  
         try {
 87  0
             final FileInputStream stream = new FileInputStream(file);
 88  0
             final InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
 89  0
             final InputSource xml = new InputSource(reader);
 90  0
             final SAXSource source = new SAXSource(xml);
 91  0
             model = readPom(source);
 92  0
         } catch (SecurityException ex) {
 93  0
             final String msg = String.format("Unable to parse pom '%s'; invalid signature", file.getPath());
 94  0
             LOGGER.log(Level.WARNING, msg);
 95  0
             LOGGER.log(Level.FINE, "", ex);
 96  0
             throw new AnalysisException(ex);
 97  0
         } catch (IOException ex) {
 98  0
             final String msg = String.format("Unable to parse pom '%s'(IO Exception)", file.getPath());
 99  0
             LOGGER.log(Level.WARNING, msg);
 100  0
             LOGGER.log(Level.FINE, "", ex);
 101  0
             throw new AnalysisException(ex);
 102  0
         } catch (Throwable ex) {
 103  0
             final String msg = String.format("Unexpected error during parsing of the pom '%s'", file.getPath());
 104  0
             LOGGER.log(Level.WARNING, msg);
 105  0
             LOGGER.log(Level.FINE, "", ex);
 106  0
             throw new AnalysisException(ex);
 107  0
         }
 108  0
         return model;
 109  
     }
 110  
 
 111  
     /**
 112  
      * Retrieves the specified POM from a jar file and converts it to a Model.
 113  
      *
 114  
      * @param source the SAXSource input stream to read the POM from
 115  
      * @return returns the POM object
 116  
      * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM
 117  
      * {@link org.owasp.dependencycheck.jaxb.pom.generated.Model} object
 118  
      */
 119  
     public Model readPom(SAXSource source) throws AnalysisException {
 120  1
         Model model = null;
 121  
         try {
 122  1
             final XMLFilter filter = new MavenNamespaceFilter();
 123  1
             final SAXParserFactory spf = SAXParserFactory.newInstance();
 124  1
             final SAXParser sp = spf.newSAXParser();
 125  1
             final XMLReader xr = sp.getXMLReader();
 126  1
             filter.setParent(xr);
 127  1
             final JAXBElement<Model> el = pomUnmarshaller.unmarshal(source, Model.class);
 128  1
             model = el.getValue();
 129  0
         } catch (SecurityException ex) {
 130  0
             throw new AnalysisException(ex);
 131  0
         } catch (ParserConfigurationException ex) {
 132  0
             throw new AnalysisException(ex);
 133  0
         } catch (SAXException ex) {
 134  0
             throw new AnalysisException(ex);
 135  0
         } catch (JAXBException ex) {
 136  0
             throw new AnalysisException(ex);
 137  0
         } catch (Throwable ex) {
 138  0
             throw new AnalysisException(ex);
 139  1
         }
 140  1
         return model;
 141  
     }
 142  
 
 143  
   /**
 144  
    * Reads in the pom file and adds elements as evidence to the given dependency.
 145  
    *
 146  
    * @param dependency the dependency being analyzed
 147  
    * @param pomFile the pom file to read
 148  
    * @throws AnalysisException is thrown if there is an exception parsing the pom
 149  
    */
 150  
   public void analyzePOM(Dependency dependency, File pomFile) throws AnalysisException {
 151  0
     final Model pom = this.readPom(pomFile);
 152  
 
 153  0
     String groupid = pom.getGroupId();
 154  0
     String parentGroupId = null;
 155  
 
 156  0
     if (pom.getParent() != null) {
 157  0
       parentGroupId = pom.getParent().getGroupId();
 158  0
       if ((groupid == null || groupid.isEmpty()) && parentGroupId != null && !parentGroupId.isEmpty()) {
 159  0
         groupid = parentGroupId;
 160  
       }
 161  
     }
 162  0
     if (groupid != null && !groupid.isEmpty()) {
 163  0
       dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Confidence.HIGHEST);
 164  0
       dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Confidence.LOW);
 165  0
       if (parentGroupId != null && !parentGroupId.isEmpty() && !parentGroupId.equals(groupid)) {
 166  0
         dependency.getVendorEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.MEDIUM);
 167  0
         dependency.getProductEvidence().addEvidence("pom", "parent-groupid", parentGroupId, Confidence.LOW);
 168  
       }
 169  
     }
 170  0
     String artifactid = pom.getArtifactId();
 171  0
     String parentArtifactId = null;
 172  0
     if (pom.getParent() != null) {
 173  0
       parentArtifactId = pom.getParent().getArtifactId();
 174  0
       if ((artifactid == null || artifactid.isEmpty()) && parentArtifactId != null && !parentArtifactId.isEmpty()) {
 175  0
         artifactid = parentArtifactId;
 176  
       }
 177  
     }
 178  0
     if (artifactid != null && !artifactid.isEmpty()) {
 179  0
       if (artifactid.startsWith("org.") || artifactid.startsWith("com.")) {
 180  0
         artifactid = artifactid.substring(4);
 181  
       }
 182  0
       dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.HIGHEST);
 183  0
       dependency.getVendorEvidence().addEvidence("pom", "artifactid", artifactid, Confidence.LOW);
 184  0
       if (parentArtifactId != null && !parentArtifactId.isEmpty() && !parentArtifactId.equals(artifactid)) {
 185  0
         dependency.getProductEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.MEDIUM);
 186  0
         dependency.getVendorEvidence().addEvidence("pom", "parent-artifactid", parentArtifactId, Confidence.LOW);
 187  
       }
 188  
     }
 189  
     //version
 190  0
     String version = pom.getVersion();
 191  0
     String parentVersion = null;
 192  0
     if (pom.getParent() != null) {
 193  0
       parentVersion = pom.getParent().getVersion();
 194  0
       if ((version == null || version.isEmpty()) && parentVersion != null && !parentVersion.isEmpty()) {
 195  0
         version = parentVersion;
 196  
       }
 197  
     }
 198  0
     if (version != null && !version.isEmpty()) {
 199  0
       dependency.getVersionEvidence().addEvidence("pom", "version", version, Confidence.HIGHEST);
 200  0
       if (parentVersion != null && !parentVersion.isEmpty() && !parentVersion.equals(version)) {
 201  0
         dependency.getVersionEvidence().addEvidence("pom", "parent-version", version, Confidence.LOW);
 202  
       }
 203  
     }
 204  
 
 205  0
     final Organization org = pom.getOrganization();
 206  0
     if (org != null) {
 207  0
       final String orgName = org.getName();
 208  0
       if (orgName != null && !orgName.isEmpty()) {
 209  0
         dependency.getVendorEvidence().addEvidence("pom", "organization name", orgName, Confidence.HIGH);
 210  
       }
 211  
     }
 212  0
     final String pomName = pom.getName();
 213  0
     if (pomName != null && !pomName.isEmpty()) {
 214  0
       dependency.getProductEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
 215  0
       dependency.getVendorEvidence().addEvidence("pom", "name", pomName, Confidence.HIGH);
 216  
     }
 217  
 
 218  0
     if (pom.getDescription() != null) {
 219  0
       final String description = pom.getDescription();
 220  0
       if (description != null && !description.isEmpty()) {
 221  0
         JarAnalyzer.addDescription(dependency, description, "pom", "description");
 222  
       }
 223  
     }
 224  0
     JarAnalyzer.extractLicense(pom, null, dependency);
 225  0
   }
 226  
 }