You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2026/10/16 12:05:29 UTC
(poi-xmlbeans) branch trunk updated: terminate the xsi:type block walk in Validator.beginEvent (#134)
This is an automated email from the ASF dual-hosted git repository.
pjfanning pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi-xmlbeans.git
The following commit(s) were added to refs/heads/trunk by this push:
new f815da5a terminate the xsi:type block walk in Validator.beginEvent (#134)
f815da5a is described below
commit f815da5a90b582a6a92608634270e55471a9ae58
Author: aizu-m <ai...@gmail.com>
AuthorDate: Fri Oct 16 17:35:24 2026 +0530
terminate the xsi:type block walk in Validator.beginEvent (#134)
* terminate the xsi:type block walk in Validator.beginEvent
* reject simple xsi:type substitution for union-content complex types
isAssignableFrom took the union-member branch for any type whose simple
variety is UNION, which includes complex types with union simple content.
A simple type was then accepted as an xsi:type for such a complex type.
Restrict the branch to simple types so cvc-elt.4.3a is reported.
Co-Authored-By: Claude Opus 5.5 <no...@anthropic.com>
---------
Co-authored-by: PJ Fanning <pj...@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <no...@anthropic.com>
---
.../xmlbeans/impl/schema/SchemaTypeImpl.java | 4 +-
.../apache/xmlbeans/impl/validator/Validator.java | 6 +-
.../misc/checkin/XsiTypeBlockValidateTest.java | 100 +++++++++++++++++++++
3 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
index 39256e79..b3689eb3 100644
--- a/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
+++ b/src/main/java/org/apache/xmlbeans/impl/schema/SchemaTypeImpl.java
@@ -2177,7 +2177,9 @@ public final class SchemaTypeImpl implements SchemaType, TypeStoreUserFactory {
return false;
}
- if (getSimpleVariety() == UNION) {
+ // a union admits types derived from its members (Type Derivation OK (Simple) 2.2.4), but a
+ // complex type with union simple content is not a union and admits no simple type
+ if (isSimpleType() && getSimpleVariety() == UNION) {
SchemaType[] members = getUnionMemberTypes();
for (SchemaType member : members) {
if (member.isAssignableFrom(type)) {
diff --git a/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java b/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java
index da7b8bfe..5ffeada1 100644
--- a/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java
+++ b/src/main/java/org/apache/xmlbeans/impl/validator/Validator.java
@@ -373,7 +373,7 @@ public final class Validator
}
if (elementType.blockExtension()) {
- for (SchemaType t = xsiType; !t.equals(elementType);
+ for (SchemaType t = xsiType; t != null && !t.equals(elementType);
t = t.getBaseType()) {
if (t.getDerivationType() == SchemaType.DT_EXTENSION) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_EXTENSION,
@@ -388,7 +388,7 @@ public final class Validator
}
if (elementType.blockRestriction()) {
- for (SchemaType t = xsiType; !t.equals(elementType);
+ for (SchemaType t = xsiType; t != null && !t.equals(elementType);
t = t.getBaseType()) {
if (t.getDerivationType() == SchemaType.DT_RESTRICTION) {
emitFieldError(event, XmlErrorCodes.ELEM_LOCALLY_VALID$XSI_TYPE_BLOCK_RESTRICTION,
@@ -406,7 +406,7 @@ public final class Validator
_localElement = sle;
if (sle.blockExtension() || sle.blockRestriction()) {
- for (SchemaType t = xsiType; !t.equals(elementType);
+ for (SchemaType t = xsiType; t != null && !t.equals(elementType);
t = t.getBaseType()) {
if ((t.getDerivationType() == SchemaType.DT_RESTRICTION && sle.blockRestriction()) ||
(t.getDerivationType() == SchemaType.DT_EXTENSION && sle.blockExtension())) {
diff --git a/src/test/java/misc/checkin/XsiTypeBlockValidateTest.java b/src/test/java/misc/checkin/XsiTypeBlockValidateTest.java
new file mode 100644
index 00000000..29b661d8
--- /dev/null
+++ b/src/test/java/misc/checkin/XsiTypeBlockValidateTest.java
@@ -0,0 +1,100 @@
+/* Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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 misc.checkin;
+
+import org.apache.xmlbeans.SchemaTypeLoader;
+import org.apache.xmlbeans.XmlBeans;
+import org.apache.xmlbeans.XmlError;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class XsiTypeBlockValidateTest {
+
+ private static final String UNION_MEMBER_INSTANCE =
+ "<t:root xmlns:t='urn:t' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xmlns:xs='http://www.w3.org/2001/XMLSchema' xsi:type='xs:int'>5</t:root>";
+
+ private static XmlObject parse(String xsd, String instance) throws Exception {
+ SchemaTypeLoader loader = XmlBeans.loadXsd(new XmlObject[]{SchemaDocument.Factory.parse(xsd)});
+ return loader.parse(instance, null, null);
+ }
+
+ @Test
+ void unionMemberSubstitutionUnderElementBlock() throws Exception {
+ // xs:int is validly derived from the union, and block only excludes extension
+ String xsd =
+ "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' " +
+ "xmlns:t='urn:t' targetNamespace='urn:t'>" +
+ " <xs:simpleType name='u'><xs:union memberTypes='xs:int xs:string'/></xs:simpleType>" +
+ " <xs:element name='root' type='t:u' block='extension'/>" +
+ "</xs:schema>";
+
+ XmlObject doc = parse(xsd, UNION_MEMBER_INSTANCE);
+ List<XmlError> errors = new ArrayList<>();
+ assertTrue(doc.validate(new XmlOptions().setErrorListener(errors)), errors.toString());
+ }
+
+ @Test
+ void simpleTypeSubstitutionForUnionContentComplexType() throws Exception {
+ // ct only has union simple content; xs:int is a simple type and not derived from ct
+ String xsd =
+ "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' " +
+ "xmlns:t='urn:t' targetNamespace='urn:t'>" +
+ " <xs:simpleType name='u'><xs:union memberTypes='xs:int xs:string'/></xs:simpleType>" +
+ " <xs:complexType name='ct' block='extension'>" +
+ " <xs:simpleContent><xs:extension base='t:u'/></xs:simpleContent>" +
+ " </xs:complexType>" +
+ " <xs:element name='root' type='t:ct'/>" +
+ "</xs:schema>";
+
+ XmlObject doc = parse(xsd, UNION_MEMBER_INSTANCE);
+ List<XmlError> errors = new ArrayList<>();
+ assertFalse(doc.validate(new XmlOptions().setErrorListener(errors)));
+ assertEquals(1, errors.size(), errors.toString());
+ assertEquals("cvc-elt.4.3a", errors.get(0).getErrorCode());
+ }
+
+ @Test
+ void blockedExtensionIsStillReported() throws Exception {
+ String xsd =
+ "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' " +
+ "xmlns:t='urn:t' targetNamespace='urn:t'>" +
+ " <xs:complexType name='base'><xs:sequence/></xs:complexType>" +
+ " <xs:complexType name='ext'>" +
+ " <xs:complexContent><xs:extension base='t:base'><xs:sequence/></xs:extension></xs:complexContent>" +
+ " </xs:complexType>" +
+ " <xs:element name='root' type='t:base' block='extension'/>" +
+ "</xs:schema>";
+
+ XmlObject doc = parse(xsd,
+ "<t:root xmlns:t='urn:t' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
+ "xsi:type='t:ext'/>");
+
+ List<XmlError> errors = new ArrayList<>();
+ assertFalse(doc.validate(new XmlOptions().setErrorListener(errors)));
+ assertEquals(1, errors.size(), errors.toString());
+ assertEquals("cvc-elt.4.3d", errors.get(0).getErrorCode());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org