-
Bug
-
Resolution: Fixed
-
P4
-
8, 9
-
b06
FULL PRODUCT VERSION :
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 4.4.0-62-generic #83-Ubuntu x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The javax.xml.validation.Validator validates an illegal xml as correct even though it is not adhering to its .xsd schema. xmllint --noout --schema minimal.xsd minimal.xml outputs the following for the same setup as in the test case below:
minimal.xml:4: element innerInnerObject: Schemas validity error : Element '{http://www.test.de/config.xml}innerInnerObject', attribute 'test-unique-attribute': The XPath 'sn:innerInnerObject/@test-unique-attribute' of a field of unique identity-constraint '{http://www.test.de/config.xml}testunique' evaluates to a node-set with more than one member.
minimal.xml fails to validate
while javax.xml.validation.Validator.validate(xmlSource) returns without the expected ParsingException (org.xml.sax.SAXException).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
* define a unique-contraint on an element's attribute contained inside another inner object in the xsd
* try to validate the xml against its schema
* Will validate even though the xml is not valid.
OR:
* Run the source code below as a junit4 test class.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
* SAXException thrown
ACTUAL -
No Exception is thrown.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.StringReader;
/**
* Created by ddraper on 02.03.17. Minimal example of broken xml parsing.
*/
public class XmlTest {
private StreamSource schemaSource;
private StreamSource xmlSource;
@Before
public void setup() throws Exception {
schemaSource = new StreamSource(new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:h=\"http://www.w3.org/1999/xhtml\"\n" +
" xmlns:sn=\"http://www.test.de/config.xml\"\n" +
" targetNamespace=\"http://www.test.de/config.xml\" elementFormDefault=\"qualified\">\n" +
" <xsd:element name=\"test\" type=\"sn:object\">\n" +
" <xsd:unique name=\"testunique\">\n" +
" <xsd:selector xpath=\"sn:innerObject\"/>\n" +
" <xsd:field xpath=\"sn:innerInnerObject/@test-unique-attribute\"/>\n" +
" </xsd:unique>\n" +
" </xsd:element>\n" +
"\n" +
" <xsd:complexType name=\"object\">\n" +
" <xsd:sequence>\n" +
" <xsd:element name=\"innerObject\" maxOccurs=\"unbounded\" type=\"sn:testType\" />\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
"\n" +
" <xsd:complexType name=\"testType\">\n" +
" <xsd:sequence>\n" +
" <xsd:element name=\"innerInnerObject\" maxOccurs=\"unbounded\" type=\"sn:testObjectType\"/>\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
"\n" +
" <xsd:complexType name=\"testObjectType\">\n" +
" <xsd:attribute use=\"optional\" name=\"test-unique-attribute\" type=\"xsd:int\" />\n" +
" </xsd:complexType>\n" +
"\n" +
"</xsd:schema>\n"));
xmlSource = new StreamSource(new StringReader("<test xmlns=\"http://www.test.de/config.xml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.test.de/config.xml\">\n" +
" <innerObject>\n" +
" <innerInnerObject test-unique-attribute=\"1\" />\n" +
" <innerInnerObject test-unique-attribute=\"1\" />\n" +
" </innerObject>\n" +
"</test>"));
}
@Test(expected = SAXException.class)
public void testUniqueness() throws Exception {
final Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(schemaSource);
final Validator val = schema.newValidator();
val.validate(xmlSource);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Using compile group:'xerces', name:'xercesImpl', version:'2.11.0+' as the xml parser returns the expected exception.
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux 4.4.0-62-generic #83-Ubuntu x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The javax.xml.validation.Validator validates an illegal xml as correct even though it is not adhering to its .xsd schema. xmllint --noout --schema minimal.xsd minimal.xml outputs the following for the same setup as in the test case below:
minimal.xml:4: element innerInnerObject: Schemas validity error : Element '{http://www.test.de/config.xml}innerInnerObject', attribute 'test-unique-attribute': The XPath 'sn:innerInnerObject/@test-unique-attribute' of a field of unique identity-constraint '{http://www.test.de/config.xml}testunique' evaluates to a node-set with more than one member.
minimal.xml fails to validate
while javax.xml.validation.Validator.validate(xmlSource) returns without the expected ParsingException (org.xml.sax.SAXException).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
* define a unique-contraint on an element's attribute contained inside another inner object in the xsd
* try to validate the xml against its schema
* Will validate even though the xml is not valid.
OR:
* Run the source code below as a junit4 test class.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
* SAXException thrown
ACTUAL -
No Exception is thrown.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.StringReader;
/**
* Created by ddraper on 02.03.17. Minimal example of broken xml parsing.
*/
public class XmlTest {
private StreamSource schemaSource;
private StreamSource xmlSource;
@Before
public void setup() throws Exception {
schemaSource = new StreamSource(new StringReader("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:h=\"http://www.w3.org/1999/xhtml\"\n" +
" xmlns:sn=\"http://www.test.de/config.xml\"\n" +
" targetNamespace=\"http://www.test.de/config.xml\" elementFormDefault=\"qualified\">\n" +
" <xsd:element name=\"test\" type=\"sn:object\">\n" +
" <xsd:unique name=\"testunique\">\n" +
" <xsd:selector xpath=\"sn:innerObject\"/>\n" +
" <xsd:field xpath=\"sn:innerInnerObject/@test-unique-attribute\"/>\n" +
" </xsd:unique>\n" +
" </xsd:element>\n" +
"\n" +
" <xsd:complexType name=\"object\">\n" +
" <xsd:sequence>\n" +
" <xsd:element name=\"innerObject\" maxOccurs=\"unbounded\" type=\"sn:testType\" />\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
"\n" +
" <xsd:complexType name=\"testType\">\n" +
" <xsd:sequence>\n" +
" <xsd:element name=\"innerInnerObject\" maxOccurs=\"unbounded\" type=\"sn:testObjectType\"/>\n" +
" </xsd:sequence>\n" +
" </xsd:complexType>\n" +
"\n" +
" <xsd:complexType name=\"testObjectType\">\n" +
" <xsd:attribute use=\"optional\" name=\"test-unique-attribute\" type=\"xsd:int\" />\n" +
" </xsd:complexType>\n" +
"\n" +
"</xsd:schema>\n"));
xmlSource = new StreamSource(new StringReader("<test xmlns=\"http://www.test.de/config.xml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.test.de/config.xml\">\n" +
" <innerObject>\n" +
" <innerInnerObject test-unique-attribute=\"1\" />\n" +
" <innerInnerObject test-unique-attribute=\"1\" />\n" +
" </innerObject>\n" +
"</test>"));
}
@Test(expected = SAXException.class)
public void testUniqueness() throws Exception {
final Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(schemaSource);
final Validator val = schema.newValidator();
val.validate(xmlSource);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Using compile group:'xerces', name:'xercesImpl', version:'2.11.0+' as the xml parser returns the expected exception.