W3CSchemaMaxOccursStackOverflow87Test.java
package failing;
import org.codehaus.stax2.validation.XMLValidationSchema;
import wstxtest.vstream.BaseValidationTest;
import org.junit.jupiter.api.Test;
/**
* Reproducer for Woodstox issue #87: parsing a W3C Schema that declares a
* particle with a large numeric {@code maxOccurs} (e.g. {@code "25000"})
* throws {@link StackOverflowError} during schema compilation, before any
* document is validated. {@code maxOccurs="unbounded"} is unaffected.
*<p>
* MSV expands a numeric {@code maxOccurs="N"} into a binary tree of
* {@code SequenceExp}/{@code ChoiceExp} nodes of depth ~N representing the
* 0..N optional occurrences. Any of MSV's recursive grammar walkers can
* overflow the stack while traversing that tree ��� the original issue
* reported {@code AttributeWildcardComputer.onRef}; on this minimal
* reproducer it surfaces in {@code RunAwayExpressionChecker.onChoice},
* which runs earlier during schema compilation. The root cause is the
* same in both cases (recursive descent via {@code ExpressionWalker} /
* {@code ChoiceExp.visit} / {@code binaryVisit}).
*<p>
* {@code maxOccurs="unbounded"} is modelled with a single {@code OneOrMore}
* node and so does not trigger the deep recursion.
*<p>
* Lives under {@code failing/} because the fix has to be made in MSV
* (upstream fork at {@code github.com/xmlark/msv}) ��� either by rewriting
* {@code ExpressionWalker} iteratively or by representing bounded-but-large
* {@code maxOccurs} without a deep expansion. There is no clean Woodstox-side
* workaround.
*/
public class W3CSchemaMaxOccursStackOverflow87Test
extends BaseValidationTest
{
// Large maxOccurs matches the value reported in the issue.
final static String SCHEMA_LARGE_MAX_OCCURS =
"<?xml version='1.0' encoding='UTF-8'?>\n"
+"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>\n"
+" <xs:element name='root'>\n"
+" <xs:complexType>\n"
+" <xs:sequence>\n"
+" <xs:element name='item' type='xs:string'"
+" minOccurs='0' maxOccurs='25000'/>\n"
+" </xs:sequence>\n"
+" </xs:complexType>\n"
+" </xs:element>\n"
+"</xs:schema>\n";
// Sanity check: maxOccurs="unbounded" compiles fine ��� MSV models it as a
// single OneOrMore node, so the AttributeWildcardComputer walk stays shallow.
@Test
public void testUnboundedCompiles() throws Exception
{
final String schema = SCHEMA_LARGE_MAX_OCCURS.replace("'25000'", "'unbounded'");
XMLValidationSchema vs = parseW3CSchema(schema);
ValidationMode.reader.validate(vs,
"<root><item>a</item><item>b</item></root>");
}
// The failing case from issue #87: large numeric maxOccurs overflows the
// stack inside MSV's AttributeWildcardComputer during schema compilation.
@Test
public void testLargeMaxOccursCompiles() throws Exception
{
XMLValidationSchema vs = parseW3CSchema(SCHEMA_LARGE_MAX_OCCURS);
ValidationMode.reader.validate(vs,
"<root><item>a</item><item>b</item></root>");
}
}