blob: f77fdf3ada33eb5f491a74e8028cfc8696738a0c [file]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package tests;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaException;
import org.junit.Assert;
import org.junit.Test;
import org.xml.sax.InputSource;
/**
* The total work of a single read must be bounded: an include chain
* deeper than the configured maximum depth is rejected with the documented
* XmlSchemaException rather than recursing until the thread stack overflows.
*/
public class ImportDepthLimitTest extends Assert {
private File createIncludeChain(File dir, int depth) throws Exception {
for (int i = 0; i < depth; i++) {
File f = new File(dir, "chain" + i + ".xsd");
Writer out = new FileWriter(f);
try {
out.write("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"");
out.write(" targetNamespace=\"urn:deep\">");
if (i + 1 < depth) {
out.write("<xs:include schemaLocation=\"chain" + (i + 1) + ".xsd\"/>");
}
out.write("</xs:schema>");
} finally {
out.close();
}
}
return new File(dir, "chain0.xsd");
}
private File newTempDir() {
File dir = new File(System.getProperty("java.io.tmpdir"),
"xmlschema-depth-" + System.nanoTime());
assertTrue(dir.mkdir());
return dir;
}
@Test
public void testShallowIncludeChainStillParses() throws Exception {
File dir = newTempDir();
File root = createIncludeChain(dir, 5);
XmlSchemaCollection collection = new XmlSchemaCollection();
XmlSchema schema = collection.read(new InputSource(root.toURI().toString()));
assertNotNull(schema);
}
@Test
public void testIncludeChainDeeperThanLimitIsRejected() throws Exception {
File dir = newTempDir();
File root = createIncludeChain(dir, 5000);
XmlSchemaCollection collection = new XmlSchemaCollection();
try {
collection.read(new InputSource(root.toURI().toString()));
fail("An include chain deeper than the maximum depth should be rejected.");
} catch (XmlSchemaException expected) {
assertTrue(expected.getMessage().contains("depth"));
}
}
}