View Javadoc
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.xml.pom;
19  
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  import java.io.Reader;
26  import java.nio.charset.StandardCharsets;
27  import javax.annotation.concurrent.ThreadSafe;
28  import javax.xml.parsers.ParserConfigurationException;
29  import javax.xml.parsers.SAXParser;
30  import org.apache.commons.io.ByteOrderMark;
31  import org.apache.commons.io.input.BOMInputStream;
32  import org.owasp.dependencycheck.utils.XmlUtils;
33  import org.owasp.dependencycheck.xml.XmlInputStream;
34  
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  import org.xml.sax.InputSource;
38  import org.xml.sax.SAXException;
39  import org.xml.sax.XMLReader;
40  
41  /**
42   * A parser for pom.xml files.
43   *
44   * @author Jeremy Long
45   */
46  @ThreadSafe
47  public class PomParser {
48  
49      /**
50       * The logger.
51       */
52      private static final Logger LOGGER = LoggerFactory.getLogger(PomParser.class);
53  
54      /**
55       * Parses the given xml file and returns a Model object containing only the
56       * fields dependency-check requires. An attempt is made to remove any
57       * doctype definitions.
58       *
59       * @param file a pom.xml
60       * @return a Model object containing only the fields dependency-check
61       * requires
62       * @throws PomParseException thrown if the xml file cannot be parsed
63       */
64      public Model parse(File file) throws PomParseException {
65          try (FileInputStream fis = new FileInputStream(file)) {
66              return parse(fis);
67          } catch (IOException ex) {
68              if (ex instanceof PomParseException) {
69                  throw (PomParseException) ex;
70              }
71              LOGGER.debug("", ex);
72              throw new PomParseException(String.format("Unable to parse pom '%s'", file), ex);
73          }
74      }
75  
76      /**
77       * Parses the given xml file and returns a Model object containing only the
78       * fields dependency-check requires. No attempt is made to remove doctype
79       * definitions.
80       *
81       * @param file a pom.xml
82       * @return a Model object containing only the fields dependency-check
83       * requires
84       * @throws PomParseException thrown if the xml file cannot be parsed
85       */
86      public Model parseWithoutDocTypeCleanup(File file) throws PomParseException {
87          try (FileInputStream fis = new FileInputStream(file)) {
88              return parseWithoutDocTypeCleanup(fis);
89          } catch (IOException ex) {
90              if (ex instanceof PomParseException) {
91                  throw (PomParseException) ex;
92              }
93              LOGGER.debug("", ex);
94              throw new PomParseException(String.format("Unable to parse pom '%s'", file), ex);
95          }
96      }
97  
98      /**
99       * Parses the given XML file and returns a Model object containing only the
100      * fields dependency-check requires. An attempt is made to remove any
101      * doctype definitions.
102      *
103      * @param inputStream an InputStream containing suppression rues
104      * @return a list of suppression rules
105      * @throws PomParseException if the XML cannot be parsed
106      */
107     public Model parse(InputStream inputStream) throws PomParseException {
108         try {
109             final PomHandler handler = new PomHandler();
110             final SAXParser saxParser = XmlUtils.buildSecureSaxParser();
111             final XMLReader xmlReader = saxParser.getXMLReader();
112             xmlReader.setContentHandler(handler);
113 
114             final BOMInputStream bomStream = BOMInputStream.builder()
115                     .setInputStream(new XmlInputStream(new PomProjectInputStream(inputStream))).get();
116             final ByteOrderMark bom = bomStream.getBOM();
117             final String defaultEncoding = StandardCharsets.UTF_8.name();
118             final String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
119             final Reader reader = new InputStreamReader(bomStream, charsetName);
120             final InputSource in = new InputSource(reader);
121             xmlReader.parse(in);
122             return handler.getModel();
123         } catch (ParserConfigurationException | SAXException | IOException ex) {
124             LOGGER.debug("", ex);
125             throw new PomParseException(ex);
126         }
127     }
128 
129     /**
130      * Parses the given XML file and returns a Model object containing only the
131      * fields dependency-check requires. No attempt is made to remove doctype
132      * definitions.
133      *
134      * @param inputStream an InputStream containing suppression rues
135      * @return a list of suppression rules
136      * @throws PomParseException if the XML cannot be parsed
137      */
138     public Model parseWithoutDocTypeCleanup(InputStream inputStream) throws PomParseException {
139         try {
140             final PomHandler handler = new PomHandler();
141             final SAXParser saxParser = XmlUtils.buildSecureSaxParser();
142             final XMLReader xmlReader = saxParser.getXMLReader();
143             xmlReader.setContentHandler(handler);
144 
145             final BOMInputStream bomStream = BOMInputStream.builder().setInputStream(new XmlInputStream(inputStream)).get();
146             final ByteOrderMark bom = bomStream.getBOM();
147             final String defaultEncoding = StandardCharsets.UTF_8.name();
148             final String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
149             final Reader reader = new InputStreamReader(bomStream, charsetName);
150             final InputSource in = new InputSource(reader);
151             xmlReader.parse(in);
152             return handler.getModel();
153         } catch (ParserConfigurationException | SAXException | IOException ex) {
154             LOGGER.debug("", ex);
155             throw new PomParseException(ex);
156         }
157     }
158 }