1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.xml.suppression;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.io.Reader;
27 import java.util.List;
28 import javax.xml.parsers.ParserConfigurationException;
29 import javax.xml.parsers.SAXParser;
30 import javax.xml.parsers.SAXParserFactory;
31
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.xml.sax.InputSource;
35 import org.xml.sax.SAXException;
36 import org.xml.sax.XMLReader;
37
38
39
40
41
42
43 public class SuppressionParser {
44
45
46
47
48 private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
49
50
51
52
53 public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
54
55
56
57
58 public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
59
60
61
62
63 public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
64
65
66
67 private static final String SUPPRESSION_SCHEMA = "schema/dependency-suppression.1.1.xsd";
68
69
70
71 private static final String OLD_SUPPRESSION_SCHEMA = "schema/suppression.xsd";
72
73
74
75
76
77
78
79
80
81 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
82 FileInputStream fis = null;
83 try {
84 fis = new FileInputStream(file);
85 return parseSuppressionRules(fis);
86 } catch (IOException ex) {
87 LOGGER.debug("", ex);
88 throw new SuppressionParseException(ex);
89 } catch (SAXException ex) {
90 try {
91 if (fis != null) {
92 try {
93 fis.close();
94 } catch (IOException ex1) {
95 LOGGER.debug("Unable to close stream", ex1);
96 }
97 }
98 fis = new FileInputStream(file);
99 } catch (FileNotFoundException ex1) {
100 throw new SuppressionParseException(ex);
101 }
102 return parseOldSuppressionRules(fis);
103 } finally {
104 if (fis != null) {
105 try {
106 fis.close();
107 } catch (IOException ex) {
108 LOGGER.debug("Unable to close stream", ex);
109 }
110 }
111 }
112 }
113
114
115
116
117
118
119
120
121
122
123 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException {
124 InputStream schemaStream = null;
125 try {
126 schemaStream = this.getClass().getClassLoader().getResourceAsStream(SUPPRESSION_SCHEMA);
127 final SuppressionHandler handler = new SuppressionHandler();
128 final SAXParserFactory factory = SAXParserFactory.newInstance();
129 factory.setNamespaceAware(true);
130 factory.setValidating(true);
131 final SAXParser saxParser = factory.newSAXParser();
132 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
133 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
134 final XMLReader xmlReader = saxParser.getXMLReader();
135 xmlReader.setErrorHandler(new SuppressionErrorHandler());
136 xmlReader.setContentHandler(handler);
137
138 final Reader reader = new InputStreamReader(inputStream, "UTF-8");
139 final InputSource in = new InputSource(reader);
140
141
142 xmlReader.parse(in);
143
144 return handler.getSuppressionRules();
145 } catch (ParserConfigurationException ex) {
146 LOGGER.debug("", ex);
147 throw new SuppressionParseException(ex);
148 } catch (SAXException ex) {
149 if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) {
150 throw ex;
151 } else {
152 LOGGER.debug("", ex);
153 throw new SuppressionParseException(ex);
154 }
155 } catch (FileNotFoundException ex) {
156 LOGGER.debug("", ex);
157 throw new SuppressionParseException(ex);
158 } catch (IOException ex) {
159 LOGGER.debug("", ex);
160 throw new SuppressionParseException(ex);
161 } finally {
162 if (schemaStream != null) {
163 try {
164 schemaStream.close();
165 } catch (IOException ex) {
166 LOGGER.debug("Error closing suppression file stream", ex);
167 }
168 }
169 }
170 }
171
172
173
174
175
176
177
178
179
180 private List<SuppressionRule> parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException {
181 InputStream schemaStream = null;
182 try {
183 schemaStream = this.getClass().getClassLoader().getResourceAsStream(OLD_SUPPRESSION_SCHEMA);
184 final SuppressionHandler handler = new SuppressionHandler();
185 final SAXParserFactory factory = SAXParserFactory.newInstance();
186 factory.setNamespaceAware(true);
187 factory.setValidating(true);
188 final SAXParser saxParser = factory.newSAXParser();
189 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_LANGUAGE, SuppressionParser.W3C_XML_SCHEMA);
190 saxParser.setProperty(SuppressionParser.JAXP_SCHEMA_SOURCE, new InputSource(schemaStream));
191 final XMLReader xmlReader = saxParser.getXMLReader();
192 xmlReader.setErrorHandler(new SuppressionErrorHandler());
193 xmlReader.setContentHandler(handler);
194
195 final Reader reader = new InputStreamReader(inputStream, "UTF-8");
196 final InputSource in = new InputSource(reader);
197
198 xmlReader.parse(in);
199
200 return handler.getSuppressionRules();
201 } catch (ParserConfigurationException ex) {
202 LOGGER.debug("", ex);
203 throw new SuppressionParseException(ex);
204 } catch (SAXException ex) {
205 LOGGER.debug("", ex);
206 throw new SuppressionParseException(ex);
207 } catch (FileNotFoundException ex) {
208 LOGGER.debug("", ex);
209 throw new SuppressionParseException(ex);
210 } catch (IOException ex) {
211 LOGGER.debug("", ex);
212 throw new SuppressionParseException(ex);
213 } finally {
214 if (schemaStream != null) {
215 try {
216 schemaStream.close();
217 } catch (IOException ex) {
218 LOGGER.debug("Error closing old suppression file stream", ex);
219 }
220 }
221 }
222 }
223 }