Author: fanningpj
Date: Sun Jun 21 00:13:45 2026
New Revision: 1935533
Log:
validate NCName parts of xsd:QName in lexQName. Thanks to aizu-m. This closes
#62
Modified:
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java
xmlbeans/trunk/src/test/java/misc/checkin/RichParserTests.java
Modified:
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java
==============================================================================
---
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java
Sun Jun 21 00:10:15 2026 (r1935532)
+++
xmlbeans/trunk/src/main/java/org/apache/xmlbeans/impl/util/XsTypeConverter.java
Sun Jun 21 00:13:45 2026 (r1935533)
@@ -17,6 +17,7 @@ package org.apache.xmlbeans.impl.util;
import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.common.InvalidLexicalValueException;
+import org.apache.xmlbeans.impl.common.XMLChar;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
@@ -505,6 +506,13 @@ public final class XsTypeConverter {
localname = charSeq.toString();
}
+ if (!prefix.isEmpty() && !XMLChar.isValidNCName(prefix)) {
+ throw new InvalidLexicalValueException("invalid xsd:QName '" +
charSeq + "'");
+ }
+ if (!XMLChar.isValidNCName(localname)) {
+ throw new InvalidLexicalValueException("invalid xsd:QName '" +
charSeq + "'");
+ }
+
String uri = nscontext.getNamespaceURI(prefix);
if (uri == null) {
Modified: xmlbeans/trunk/src/test/java/misc/checkin/RichParserTests.java
==============================================================================
--- xmlbeans/trunk/src/test/java/misc/checkin/RichParserTests.java Sun Jun
21 00:10:15 2026 (r1935532)
+++ xmlbeans/trunk/src/test/java/misc/checkin/RichParserTests.java Sun Jun
21 00:13:45 2026 (r1935533)
@@ -83,6 +83,30 @@ public class RichParserTests {
assertThrows(InvalidLexicalValueException.class, () ->
attByName.getAttributeBase64Value("", "b"));
}
+ @Test
+ void testInvalidQNameThrowsInvalidLexicalValue() throws Exception {
+ // The localname of an xsd:QName must be an NCName, so a value whose
+ // local part still contains a ':' (or any other non-NCName char) is
+ // outside the lexical space. lexQName resolved the prefix but never
+ // checked the parts, so "p:b:c" came back as QName{uri}b:c instead of
+ // being rejected like the holder validate path does.
+ XMLStreamReaderExt colonInLocal = atFirstStartElement("<a
xmlns:p='urn:x'>p:b:c</a>");
+ assertThrows(InvalidLexicalValueException.class,
colonInLocal::getQNameValue);
+
+ XMLStreamReaderExt spaceInLocal = atFirstStartElement("<a>b c</a>");
+ assertThrows(InvalidLexicalValueException.class,
spaceInLocal::getQNameValue);
+
+ XMLStreamReaderExt emptyLocal = atFirstStartElement("<a
xmlns:p='urn:x'>p:</a>");
+ assertThrows(InvalidLexicalValueException.class,
emptyLocal::getQNameValue);
+
+ XMLStreamReaderExt attColon = atFirstStartElement("<a xmlns:p='urn:x'
b='p:b:c'/>");
+ assertThrows(InvalidLexicalValueException.class, () ->
attColon.getAttributeQNameValue(0));
+
+ // a well-formed prefixed QName still resolves
+ XMLStreamReaderExt good = atFirstStartElement("<a
xmlns:p='urn:x'>p:good</a>");
+ assertEquals(new QName("urn:x", "good"), good.getQNameValue());
+ }
+
private static XMLStreamReaderExt atFirstStartElement(String xml) throws
Exception {
XMLStreamReader xsr =
XmlObject.Factory.parse(xml).newXMLStreamReader();
XMLStreamReaderExt ext = new XMLStreamReaderExtImpl(xsr);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]