Skip to content

Commit

Permalink
Fix #104
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 23, 2020
1 parent e5433fb commit 09f310b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 5 deletions.
3 changes: 3 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Project: woodstox

5.3.1 (not yet released)

#104: `NullPointerException` in `DTDValidator.validateElementEnd()`
for element undefined in DTD
(reported by ChrisTrenkamp@github)
#105: W3CSchemaFactory constructor incorrectly references relaxng

5.3.0 (15-Jul-2019)
Expand Down
16 changes: 11 additions & 5 deletions src/main/java/com/ctc/wstx/dtd/DTDValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -331,10 +331,10 @@ public int validateElementEnd(String localName, String uri, String prefix)
throws XMLStreamException
{
// First, let's remove the top:
int ix = mElemCount-1;
/* [WSTX-200]: need to avoid problems when doing sub-tree
* validation...
*/
final int ix = mElemCount-1;

// [WSTX-200]: need to avoid problems when doing sub-tree
// validation...
if (ix < 0) {
return XMLValidator.CONTENT_ALLOW_WS;
}
Expand All @@ -359,7 +359,13 @@ public int validateElementEnd(String localName, String uri, String prefix)
// doesn't really matter; epilog/prolog differently handled:
return XMLValidator.CONTENT_ALLOW_WS;
}
return mElems[ix-1].getAllowedContent();

final DTDElement element = mElems[ix-1];

// 22-Apr-2020, tatu: `null` validator added for unknown elements
return (element == null)
? XMLValidator.CONTENT_ALLOW_ANY_TEXT
: element.getAllowedContent();
}

//public void validateText(String text, boolean lastTextSegment) ;
Expand Down
103 changes: 103 additions & 0 deletions src/test/java/wstxtest/vstream/TestDTDErrorCollection104Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package wstxtest.vstream;

import stax2.BaseStax2Test;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.*;

import org.codehaus.stax2.XMLStreamReader2;
import org.codehaus.stax2.validation.ValidationProblemHandler;
import org.codehaus.stax2.validation.XMLValidationException;
import org.codehaus.stax2.validation.XMLValidationProblem;
import org.codehaus.stax2.validation.XMLValidationSchema;
import org.codehaus.stax2.validation.XMLValidationSchemaFactory;

public class TestDTDErrorCollection104Test
extends BaseStax2Test
{
// [woodstox-core#103]
public void testValidationBeyondUnknownElement() throws Exception
{
final String DOC =
"<map>\n" +
" <val>\n" +
" <prop att=\"product\" val=\"win\" action=\"flag\" color=\"black\"/>\n" +
" </val>\n" +
"</map>\n";

final String INPUT_DTD =
"<!ELEMENT map (notval+)>\n"
+"<!ELEMENT notval EMPTY>\n"
;

XMLInputFactory f = getInputFactory();
setCoalescing(f, true);

XMLValidationSchemaFactory schemaFactory =
XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_DTD);
XMLValidationSchema schema = schemaFactory.createSchema(new StringReader(INPUT_DTD));
XMLStreamReader2 sr = (XMLStreamReader2)f.createXMLStreamReader(
new StringReader(DOC));

final List<XMLValidationProblem> probs = new ArrayList<XMLValidationProblem>();

sr.validateAgainst(schema);
sr.setValidationProblemHandler(new ValidationProblemHandler() {
@Override
public void reportProblem(XMLValidationProblem problem)
throws XMLValidationException {
probs.add(problem);
}
});

assertTokenType(START_ELEMENT, sr.next());
assertEquals("map", sr.getLocalName());

sr.next(); // SPACE or CHARACTERS
assertTokenType(START_ELEMENT, sr.next());
assertEquals("val", sr.getLocalName());
assertEquals(1, probs.size());
assertEquals("Undefined element <val> encountered",
probs.get(0).getMessage());

sr.next(); // SPACE or CHARACTERS
assertEquals(1, probs.size());

// From this point on, however, behavior bit unclear except
// that for DTD I guess we can at least check for undefined
// cases....

assertTokenType(START_ELEMENT, sr.next());
assertEquals("prop", sr.getLocalName());
// <prop> not defined either so:
assertEquals(2, probs.size());
assertEquals("Undefined element <prop> encountered",
probs.get(1).getMessage());

assertTokenType(END_ELEMENT, sr.next());
assertEquals("prop", sr.getLocalName());
assertEquals(2, probs.size());

sr.next(); // SPACE or CHARACTERS
assertEquals(2, probs.size());
assertTokenType(END_ELEMENT, sr.next());
assertEquals("val", sr.getLocalName());
assertEquals(2, probs.size());

sr.next(); // SPACE or CHARACTERS
assertTokenType(END_ELEMENT, sr.next());
assertEquals("map", sr.getLocalName());
assertEquals(3, probs.size());
assertEquals("Validation error, element </map>: Expected at least one element <notval>",
probs.get(2).getMessage());

// Plus content model now missing <notval>(s)
assertTokenType(END_DOCUMENT, sr.next());
assertEquals(3, probs.size());

sr.close();
}
}

0 comments on commit 09f310b

Please sign in to comment.