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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.io.Reader;
27 import java.nio.charset.StandardCharsets;
28 import java.util.List;
29 import javax.annotation.concurrent.ThreadSafe;
30 import javax.xml.parsers.ParserConfigurationException;
31
32 import org.apache.commons.io.ByteOrderMark;
33 import org.apache.commons.io.input.BOMInputStream;
34
35 import org.owasp.dependencycheck.utils.AutoCloseableInputSource;
36 import org.owasp.dependencycheck.utils.XmlUtils;
37
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.xml.sax.InputSource;
41 import org.xml.sax.SAXException;
42 import org.xml.sax.XMLReader;
43
44 import static org.owasp.dependencycheck.utils.AutoCloseableInputSource.fromResource;
45
46
47
48
49
50
51 @ThreadSafe
52 public class SuppressionParser {
53
54
55
56
57 private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionParser.class);
58
59
60
61
62 public static final String SUPPRESSION_SCHEMA_1_4 = "schema/dependency-suppression.1.4.xsd";
63
64
65
66 public static final String SUPPRESSION_SCHEMA_1_3 = "schema/dependency-suppression.1.3.xsd";
67
68
69
70 public static final String SUPPRESSION_SCHEMA_1_2 = "schema/dependency-suppression.1.2.xsd";
71
72
73
74 public static final String SUPPRESSION_SCHEMA_1_1 = "schema/dependency-suppression.1.1.xsd";
75
76
77
78 private static final String SUPPRESSION_SCHEMA_1_0 = "schema/suppression.xsd";
79
80
81
82
83
84
85
86
87
88 @SuppressFBWarnings(justification = "try with resource will clenaup the resources", value = {"OBL_UNSATISFIED_OBLIGATION"})
89 public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
90 try (FileInputStream fis = new FileInputStream(file)) {
91 return parseSuppressionRules(fis);
92 } catch (SAXException | IOException ex) {
93 LOGGER.debug("", ex);
94 throw new SuppressionParseException(ex);
95 }
96 }
97
98
99
100
101
102
103
104
105
106
107 public List<SuppressionRule> parseSuppressionRules(InputStream inputStream)
108 throws SuppressionParseException, SAXException {
109 try (AutoCloseableInputSource schemaStream14 = fromResource(SUPPRESSION_SCHEMA_1_4);
110 AutoCloseableInputSource schemaStream13 = fromResource(SUPPRESSION_SCHEMA_1_3);
111 AutoCloseableInputSource schemaStream12 = fromResource(SUPPRESSION_SCHEMA_1_2);
112 AutoCloseableInputSource schemaStream11 = fromResource(SUPPRESSION_SCHEMA_1_1);
113 AutoCloseableInputSource schemaStream10 = fromResource(SUPPRESSION_SCHEMA_1_0)) {
114
115 final BOMInputStream bomStream = BOMInputStream.builder().setInputStream(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
120 final SuppressionHandler handler = new SuppressionHandler();
121 final XMLReader xmlReader = XmlUtils.buildSecureValidatingXmlReader(schemaStream14, schemaStream13, schemaStream12, schemaStream11, schemaStream10);
122 xmlReader.setErrorHandler(new SuppressionErrorHandler());
123 xmlReader.setContentHandler(handler);
124 try (Reader reader = new InputStreamReader(bomStream, charsetName)) {
125 final InputSource in = new InputSource(reader);
126 xmlReader.parse(in);
127 return handler.getSuppressionRules();
128 }
129 } catch (ParserConfigurationException | IOException ex) {
130 LOGGER.debug("", ex);
131 throw new SuppressionParseException(ex);
132 } catch (SAXException ex) {
133 if (ex.getMessage().contains("Cannot find the declaration of element 'suppressions'.")) {
134 throw ex;
135 } else {
136 LOGGER.debug("", ex);
137 throw new SuppressionParseException(ex);
138 }
139 }
140 }
141
142 }