View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.xml.secure;
19  
20  import static org.junit.jupiter.api.Assertions.assertEquals;
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.assertThrows;
24  
25  import java.io.StringReader;
26  import java.util.Collections;
27  import java.util.Iterator;
28  
29  import javax.xml.XMLConstants;
30  import javax.xml.namespace.NamespaceContext;
31  import javax.xml.namespace.QName;
32  import javax.xml.xpath.XPath;
33  import javax.xml.xpath.XPathConstants;
34  import javax.xml.xpath.XPathExpression;
35  import javax.xml.xpath.XPathExpressionException;
36  import javax.xml.xpath.XPathFactory;
37  import javax.xml.xpath.XPathFunctionResolver;
38  import javax.xml.xpath.XPathVariableResolver;
39  
40  import org.junit.jupiter.api.Tag;
41  import org.junit.jupiter.api.Test;
42  import org.xml.sax.InputSource;
43  
44  @Tag("xpath")
45  class SecureXPathTest {
46  
47      @Test
48      void delegatesEveryXPathMethod() throws Exception {
49          final SecureXPath xpath = new SecureXPath(XPathFactory.newInstance().newXPath(), false);
50          final NamespaceContext context = new NamespaceContext() {
51  
52              @Override
53              public String getNamespaceURI(final String prefix) {
54                  return XMLConstants.NULL_NS_URI;
55              }
56  
57              @Override
58              public String getPrefix(final String namespaceUri) {
59                  return null;
60              }
61  
62              @Override
63              public Iterator<String> getPrefixes(final String namespaceUri) {
64                  return Collections.emptyIterator();
65              }
66          };
67          xpath.setNamespaceContext(context);
68          xpath.setXPathFunctionResolver((name, arity) -> null);
69          xpath.setXPathVariableResolver(name -> null);
70          assertNotNull(xpath.getNamespaceContext());
71          assertNotNull(xpath.getXPathFunctionResolver());
72          assertNotNull(xpath.getXPathVariableResolver());
73          assertNotNull(xpath.compile("/root"));
74          assertEquals("value", xpath.evaluate("/root/text()", new InputSource(new StringReader("<root>value</root>"))));
75          assertEquals("value", xpath.evaluate("/root/text()", new InputSource(new StringReader("<root>value</root>")), XPathConstants.STRING));
76          assertEquals("value", xpath.evaluate("/root/text()", SecureXPath.parse(new InputSource(new StringReader("<root>value</root>")), false)));
77          assertEquals("value", xpath.evaluate("/root/text()", SecureXPath.parse(new InputSource(new StringReader("<root>value</root>")), false),
78                  XPathConstants.STRING));
79          xpath.reset();
80      }
81  
82      @Test
83      void preservesANullCompiledExpressionFromTheDelegate() throws Exception {
84          final XPath delegate = new XPath() {
85  
86              @Override
87              public XPathExpression compile(final String expression) {
88                  return null;
89              }
90  
91              @Override
92              public String evaluate(final String expression, final InputSource source) {
93                  return null;
94              }
95  
96              @Override
97              public Object evaluate(final String expression, final InputSource source, final QName returnType) {
98                  return null;
99              }
100 
101             @Override
102             public String evaluate(final String expression, final Object item) {
103                 return null;
104             }
105 
106             @Override
107             public Object evaluate(final String expression, final Object item, final QName returnType) {
108                 return null;
109             }
110 
111             @Override
112             public NamespaceContext getNamespaceContext() {
113                 return null;
114             }
115 
116             @Override
117             public XPathFunctionResolver getXPathFunctionResolver() {
118                 return null;
119             }
120 
121             @Override
122             public XPathVariableResolver getXPathVariableResolver() {
123                 return null;
124             }
125 
126             @Override
127             public void reset() {
128             }
129 
130             @Override
131             public void setNamespaceContext(final NamespaceContext context) {
132             }
133 
134             @Override
135             public void setXPathFunctionResolver(final XPathFunctionResolver resolver) {
136             }
137 
138             @Override
139             public void setXPathVariableResolver(final XPathVariableResolver resolver) {
140             }
141         };
142         assertNull(new SecureXPath(delegate, false).compile("/root"));
143     }
144 
145     @Test
146     void wrapsParseFailuresAsXPathExpressionExceptions() {
147         final XPathExpressionException exception = assertThrows(XPathExpressionException.class,
148                 () -> SecureXPath.parse(new InputSource(new StringReader("<root>")), false));
149         assertNotNull(exception.getCause());
150     }
151 }