1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.xml.secure;
19
20 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertSame;
24
25 import java.util.Locale;
26
27 import javax.xml.parsers.SAXParser;
28 import javax.xml.parsers.SAXParserFactory;
29 import javax.xml.validation.Schema;
30
31 import org.junit.jupiter.api.Tag;
32 import org.junit.jupiter.api.Test;
33 import org.xml.sax.DocumentHandler;
34 import org.xml.sax.Parser;
35 import org.xml.sax.SAXNotRecognizedException;
36 import org.xml.sax.SAXNotSupportedException;
37 import org.xml.sax.XMLReader;
38
39 @Tag("sax")
40 class SecureSAXParserTest {
41
42 private static final class ParserSecureReader extends SecureXMLReader implements Parser {
43
44 ParserSecureReader(final XMLReader reader) {
45 super(reader);
46 }
47
48 @Override
49 public void setDocumentHandler(final DocumentHandler handler) {
50 }
51
52 @Override
53 public void setLocale(final Locale locale) {
54 }
55 }
56
57 private static final class ReaderSAXParser extends SAXParser {
58
59 private final XMLReader reader;
60
61 ReaderSAXParser(final XMLReader reader) {
62 this.reader = reader;
63 }
64
65 @Override
66 public Parser getParser() {
67 return (Parser) reader;
68 }
69
70 @Override
71 public Object getProperty(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
72 return reader.getProperty(name);
73 }
74
75 @Override
76 public Schema getSchema() {
77 return null;
78 }
79
80 @Override
81 public XMLReader getXMLReader() {
82 return reader;
83 }
84
85 @Override
86 public boolean isNamespaceAware() {
87 return false;
88 }
89
90 @Override
91 public boolean isValidating() {
92 return false;
93 }
94
95 @Override
96 public boolean isXIncludeAware() {
97 return false;
98 }
99
100 @Override
101 public void reset() {
102 }
103
104 @Override
105 public void setProperty(final String name, final Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
106 reader.setProperty(name, value);
107 }
108 }
109
110 @Test
111 void cachesSecureViewsAndKeepsThemSecuredAfterReset() throws Exception {
112 final SecureSAXParser parser = new SecureSAXParser(SAXParserFactory.newInstance().newSAXParser());
113 final XMLReader firstReader = parser.getXMLReader();
114 final Parser firstParser = parser.getParser();
115 assertSame(firstReader, parser.getXMLReader());
116 assertSame(firstParser, parser.getParser());
117 parser.setProperty("http://xml.org/sax/properties/lexical-handler", null);
118 assertNull(parser.getProperty("http://xml.org/sax/properties/lexical-handler"));
119 parser.reset();
120
121 assertSame(firstReader, parser.getXMLReader());
122 assertSame(firstParser, parser.getParser());
123 assertInstanceOf(FallbackIgnoreEntityResolver2.class, ((SecureXMLReader) firstReader).getDelegate().getEntityResolver(),
124 "the reset must put the floor back on the underlying reader");
125 }
126
127 @Test
128 void exposesSecureParserViewsAndState() throws Exception {
129 final SecureSAXParser parser = new SecureSAXParser(SAXParserFactory.newInstance().newSAXParser());
130 assertNotNull(parser.getXMLReader());
131 assertNotNull(parser.getParser());
132 parser.isNamespaceAware();
133 parser.isValidating();
134 if (AttackTestSupport.SAX_SUPPORTS_SCHEMA) {
135 parser.getSchema();
136 }
137 if (AttackTestSupport.SAX_SUPPORTS_XINCLUDE) {
138 parser.isXIncludeAware();
139 }
140 if (AttackTestSupport.SAX_SUPPORTS_RESET) {
141 parser.reset();
142 }
143 }
144
145 @Test
146 void reusesAReaderThatAlreadyImplementsSax1Parser() throws Exception {
147 final ParserSecureReader reader = new ParserSecureReader(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
148 final SecureSAXParser parser = new SecureSAXParser(new ReaderSAXParser(reader));
149 assertSame(reader, parser.getParser());
150 }
151 }