Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8176447

javax.xml.validation.Validator validates incorrectly on uniqueness constraint

    XMLWordPrintable

Details

    Description

      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.

      Attachments

        Activity

          People

            joehw Joe Wang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: