8222991: Xerces 2.12.0: Validation
Reviewed-by: lancea
This commit is contained in:
parent
5d1df35fe7
commit
94f04de7bc
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* reserved comment block
|
||||
* DO NOT REMOVE OR ALTER!
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -23,6 +22,8 @@ package com.sun.org.apache.xerces.internal.impl.dv.xs;
|
||||
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLChar;
|
||||
import jdk.xml.internal.SecuritySupport;
|
||||
|
||||
/**
|
||||
* All primitive types plus ID/IDREF/ENTITY/INTEGER are derived from this abstract
|
||||
@ -35,9 +36,14 @@ import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
|
||||
* @author Neeraj Bajaj, Sun Microsystems, inc.
|
||||
* @author Sandy Gao, IBM
|
||||
*
|
||||
* @LastModified: Apr 2019
|
||||
*/
|
||||
public abstract class TypeValidator {
|
||||
|
||||
private static final boolean USE_CODE_POINT_COUNT_FOR_STRING_LENGTH =
|
||||
Boolean.parseBoolean(SecuritySupport.getSystemProperty(
|
||||
"com.sun.org.apache.xerces.internal.impl.dv.xs.useCodePointCountForStringLength", "false"));
|
||||
|
||||
// which facets are allowed for this type
|
||||
public abstract short getAllowedFacets();
|
||||
|
||||
@ -82,7 +88,14 @@ public abstract class TypeValidator {
|
||||
// get the length of the value
|
||||
// the parameters are in compiled form (from getActualValue)
|
||||
public int getDataLength(Object value) {
|
||||
return (value instanceof String) ? ((String)value).length() : -1;
|
||||
if (value instanceof String) {
|
||||
final String str = (String)value;
|
||||
if (!USE_CODE_POINT_COUNT_FOR_STRING_LENGTH) {
|
||||
return str.length();
|
||||
}
|
||||
return getCodePointLength(str);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get the number of digits of the value
|
||||
@ -97,6 +110,25 @@ public abstract class TypeValidator {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Returns the length of the string in Unicode code points.
|
||||
private int getCodePointLength(String value) {
|
||||
// Count the number of surrogate pairs, and subtract them from
|
||||
// the total length.
|
||||
final int len = value.length();
|
||||
int surrogatePairCount = 0;
|
||||
for (int i = 0; i < len - 1; ++i) {
|
||||
if (XMLChar.isHighSurrogate(value.charAt(i))) {
|
||||
if (XMLChar.isLowSurrogate(value.charAt(++i))) {
|
||||
++surrogatePairCount;
|
||||
}
|
||||
else {
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return len - surrogatePairCount;
|
||||
}
|
||||
|
||||
// check whether the character is in the range 0x30 ~ 0x39
|
||||
public static final boolean isDigit(char ch) {
|
||||
return ch >= '0' && ch <= '9';
|
||||
|
@ -39,7 +39,6 @@
|
||||
cvc-complex-type.2.4.b = cvc-complex-type.2.4.b: The content of element ''{0}'' is not complete. One of ''{1}'' is expected.
|
||||
cvc-complex-type.2.4.c = cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ''{0}''.
|
||||
cvc-complex-type.2.4.d = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element is expected at this point.
|
||||
cvc-complex-type.2.4.d.1 = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element ''{1}'' is expected at this point.
|
||||
cvc-complex-type.2.4.e = cvc-complex-type.2.4.e: ''{0}'' can occur a maximum of ''{2}'' times in the current sequence. This limit was exceeded. At this point one of ''{1}'' is expected.
|
||||
cvc-complex-type.2.4.f = cvc-complex-type.2.4.f: ''{0}'' can occur a maximum of ''{1}'' times in the current sequence. This limit was exceeded. No child element is expected at this point.
|
||||
cvc-complex-type.2.4.g = cvc-complex-type.2.4.g: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. One more instance is required to satisfy this constraint.
|
||||
@ -103,7 +102,7 @@
|
||||
src-ct.1 = src-ct.1: Complex Type Definition Representation Error for type ''{0}''. When <complexContent> is used, the base type must be a complexType. ''{1}'' is a simpleType.
|
||||
src-ct.2.1 = src-ct.2.1: Complex Type Definition Representation Error for type ''{0}''. When <simpleContent> is used, the base type must be a complexType whose content type is simple, or, only if restriction is specified, a complex type with mixed content and emptiable particle, or, only if extension is specified, a simple type. ''{1}'' satisfies none of these conditions.
|
||||
src-ct.2.2 = src-ct.2.2: Complex Type Definition Representation Error for type ''{0}''. When a complexType with simpleContent restricts a complexType with mixed content and emptiable particle, then there must be a <simpleType> among the children of <restriction>.
|
||||
src-ct.4 = src-ct.4: Complex Type Definition Representation Error for type ''{0}''. The intersection of wildcards is not expressible.
|
||||
src-ct.4 = src-ct.4: Complex Type Definition Representation Error for type ''{0}''. The intersection of wildcards is not expressible.
|
||||
src-ct.5 = src-ct.5: Complex Type Definition Representation Error for type ''{0}''. The union of wildcards is not expressible.
|
||||
src-element.1 = src-element.1: The properties ''default'' and ''fixed'' cannot both be present in element declaration ''{0}''. Use only one of them.
|
||||
src-element.2.1 = src-element.2.1: : One of 'ref' or 'name' must be present in a local element declaration.
|
||||
@ -234,14 +233,14 @@
|
||||
rcase-MapAndSum.2 = rcase-MapAndSum.2: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}).
|
||||
rcase-NameAndTypeOK.1 = rcase-NameAndTypeOK.1: Elements have names and target namespaces which are not the same: Element ''{0}'' in namespace ''{1}'' and element ''{2}'' in namespace ''{3}''.
|
||||
rcase-NameAndTypeOK.2 = rcase-NameAndTypeOK.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. The element declaration''s '{'nillable'}' is true, but the corresponding particle in the base type has an element declaration whose '{'nillable'}' is false.
|
||||
rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}, of the corresponding particle in the base type.
|
||||
rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}), of the corresponding particle in the base type.
|
||||
rcase-NameAndTypeOK.4.a = rcase-NameAndTypeOK.4.a: Element ''{0}'' is not fixed, but the corresponding element in the base type is fixed with value ''{1}''.
|
||||
rcase-NameAndTypeOK.4.b = rcase-NameAndTypeOK.4.b: Element ''{0}'' is fixed with value ''{1}'', but the corresponding element in the base type is fixed with value ''{2}''.
|
||||
rcase-NameAndTypeOK.5 = rcase-NameAndTypeOK.5: Identity constraints for element ''{0}'' are not a subset of those in base.
|
||||
rcase-NameAndTypeOK.6 = rcase-NameAndTypeOK.6: The disallowed substitutions for element ''{0}'' are not a superset of those in the base.
|
||||
rcase-NameAndTypeOK.7 = rcase-NameAndTypeOK.7: The type of element ''{0}'', ''{1}'', is not derived from the type of the base element, ''{2}''.
|
||||
rcase-NSCompat.1 = rcase-NSCompat.1: Element ''{0}'' has a namespace ''{1}'' which is not allowed by the wildcard in the base.
|
||||
rcase-NSCompat.2 = rcase-NSCompat.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}, of the corresponding particle in the base type.
|
||||
rcase-NSCompat.2 = rcase-NSCompat.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}), of the corresponding particle in the base type.
|
||||
rcase-NSRecurseCheckCardinality.1 = rcase-NSRecurseCheckCardinality.1: There is not a complete functional mapping between the particles.
|
||||
rcase-NSRecurseCheckCardinality.2 = rcase-NSRecurseCheckCardinality.2: Group''s occurrence range, ({0},{1}), is not a valid restriction of base wildcard''s range, ({2},{3}).
|
||||
rcase-NSSubset.1 = rcase-NSSubset.1: Wildcard is not a subset of corresponding wildcard in base.
|
||||
@ -286,15 +285,15 @@
|
||||
EmptyTargetNamespace = EmptyTargetNamespace: In schema document ''{0}'', the value of the ''targetNamespace'' attribute cannot be an empty string.
|
||||
FacetValueFromBase = FacetValueFromBase: In the declaration of type ''{0}'', value ''{1}'' of facet ''{2}'' must be from the value space of the base type, ''{3}''.
|
||||
FixedFacetValue = FixedFacetValue: In the definition of {3}, the value ''{1}'' for the facet ''{0}'' is invalid, because the value for ''{0}'' has been set to ''{2}'' in one of the ancestor types, and '{'fixed'}' = true.
|
||||
InvalidRegex = InvalidRegex: Pattern value ''{0}'' is not a valid regular expression. The reported error was: ''{1}'' at column ''{2}''.
|
||||
MaxOccurLimit = Current configuration of the parser doesn''t allow a maxOccurs attribute value to be set greater than the value {0}.
|
||||
InvalidRegex = InvalidRegex: Pattern value ''{0}'' is not a valid regular expression. The reported error was: ''{1}''.
|
||||
MaxOccurLimit = Current configuration of the parser doesn''t allow the expansion of a content model for a complex type to contain more than {0} nodes.
|
||||
PublicSystemOnNotation = PublicSystemOnNotation: At least one of ''public'' and ''system'' must appear in element ''notation''.
|
||||
SchemaLocation = SchemaLocation: schemaLocation value = ''{0}'' must have even number of URI''s.
|
||||
TargetNamespace.1 = TargetNamespace.1: Expecting namespace ''{0}'', but the target namespace of the schema document is ''{1}''.
|
||||
TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''.
|
||||
UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared.
|
||||
UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared.
|
||||
|
||||
FacetsContradict = FacetsContradict: For simpleType definition ''{2}'', the enumeration value ''{0}'' contradicts with value of ''{1}'' facet.
|
||||
|
||||
# JAXP 1.2 schema source property errors
|
||||
|
||||
|
@ -23,6 +23,8 @@ package com.sun.org.apache.xerces.internal.impl.xs.traversers;
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.XSFacets;
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
|
||||
import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
|
||||
import com.sun.org.apache.xerces.internal.impl.validation.ValidationState;
|
||||
import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
|
||||
import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
|
||||
@ -42,6 +44,7 @@ import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
|
||||
import com.sun.org.apache.xerces.internal.xni.QName;
|
||||
import com.sun.org.apache.xerces.internal.xs.XSAttributeUse;
|
||||
import com.sun.org.apache.xerces.internal.xs.XSObjectList;
|
||||
import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
|
||||
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -280,6 +283,7 @@ abstract class XSDAbstractTraverser {
|
||||
}
|
||||
|
||||
FacetInfo traverseFacets(Element content,
|
||||
XSTypeDefinition typeDef,
|
||||
XSSimpleType baseValidator,
|
||||
XSDocumentInfo schemaDoc) {
|
||||
|
||||
@ -293,6 +297,9 @@ abstract class XSDAbstractTraverser {
|
||||
List<NamespaceContext> enumNSDecls = hasQName ? new ArrayList<>() : null;
|
||||
int currentFacet = 0;
|
||||
xsFacets.reset();
|
||||
boolean seenPattern = false;
|
||||
Element contextNode = (Element)content.getParentNode();
|
||||
boolean hasLengthFacet = false, hasMinLengthFacet = false, hasMaxLengthFacet = false;
|
||||
while (content != null) {
|
||||
// General Attribute Checking
|
||||
Object[] attrs = null;
|
||||
@ -364,7 +371,6 @@ abstract class XSDAbstractTraverser {
|
||||
}
|
||||
}
|
||||
else if (facet.equals(SchemaSymbols.ELT_PATTERN)) {
|
||||
facetsPresent |= XSSimpleType.FACET_PATTERN;
|
||||
attrs = fAttrChecker.checkAttributes(content, false, schemaDoc);
|
||||
String patternVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
|
||||
// The facet can't be used if the value is missing. Ignore
|
||||
@ -376,6 +382,7 @@ abstract class XSDAbstractTraverser {
|
||||
continue;
|
||||
}
|
||||
|
||||
seenPattern = true;
|
||||
if (fPattern.length() == 0) {
|
||||
fPattern.append(patternVal);
|
||||
} else {
|
||||
@ -477,9 +484,11 @@ abstract class XSDAbstractTraverser {
|
||||
switch (currentFacet) {
|
||||
case XSSimpleType.FACET_MINLENGTH:
|
||||
xsFacets.minLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
|
||||
hasMinLengthFacet = true;
|
||||
break;
|
||||
case XSSimpleType.FACET_MAXLENGTH:
|
||||
xsFacets.maxLength = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
|
||||
hasMaxLengthFacet = true;
|
||||
break;
|
||||
case XSSimpleType.FACET_MAXEXCLUSIVE:
|
||||
xsFacets.maxExclusive = (String)attrs[XSAttributeChecker.ATTIDX_VALUE];
|
||||
@ -504,6 +513,7 @@ abstract class XSDAbstractTraverser {
|
||||
break;
|
||||
case XSSimpleType.FACET_LENGTH:
|
||||
xsFacets.length = ((XInt)attrs[XSAttributeChecker.ATTIDX_VALUE]).intValue();
|
||||
hasLengthFacet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -566,16 +576,148 @@ abstract class XSDAbstractTraverser {
|
||||
xsFacets.enumNSDecls = enumNSDecls;
|
||||
xsFacets.enumAnnotations = enumAnnotations;
|
||||
}
|
||||
if ((facetsPresent & XSSimpleType.FACET_PATTERN) != 0) {
|
||||
if (seenPattern) {
|
||||
facetsPresent |= XSSimpleType.FACET_PATTERN;
|
||||
xsFacets.pattern = fPattern.toString();
|
||||
xsFacets.patternAnnotations = patternAnnotations;
|
||||
}
|
||||
|
||||
fPattern.setLength(0);
|
||||
|
||||
// check if length, minLength and maxLength facets contradict with enumeration facets.
|
||||
// currently considers the case when the baseValidator is a built-in type.
|
||||
if (enumData != null) {
|
||||
if (hasLengthFacet) {
|
||||
checkEnumerationAndLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
|
||||
}
|
||||
if (hasMinLengthFacet) {
|
||||
checkEnumerationAndMinLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
|
||||
}
|
||||
if (hasMaxLengthFacet) {
|
||||
checkEnumerationAndMaxLengthInconsistency(baseValidator, enumData, contextNode, getSchemaTypeName(typeDef));
|
||||
}
|
||||
}
|
||||
|
||||
return new FacetInfo(xsFacets, content, facetsPresent, facetsFixed);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get name of an XSD type definition as a string value (which will typically be the value of "name" attribute of a
|
||||
* type definition, or an internal name determined by the validator for anonymous types).
|
||||
*/
|
||||
public static String getSchemaTypeName(XSTypeDefinition typeDefn) {
|
||||
|
||||
String typeNameStr = "";
|
||||
if (typeDefn instanceof XSSimpleTypeDefinition) {
|
||||
typeNameStr = ((XSSimpleTypeDecl) typeDefn).getTypeName();
|
||||
}
|
||||
else {
|
||||
typeNameStr = ((XSComplexTypeDecl) typeDefn).getTypeName();
|
||||
}
|
||||
|
||||
return typeNameStr;
|
||||
|
||||
} // getSchemaTypeName
|
||||
|
||||
/*
|
||||
* Check whether values of xs:maxLength and xs:enumeration are consistent. Report a warning message if they are not.
|
||||
*/
|
||||
private void checkEnumerationAndMaxLengthInconsistency(XSSimpleType baseValidator, List<String> enumData, Element contextNode, String typeName) {
|
||||
if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
|
||||
SchemaSymbols.ATTVAL_HEXBINARY.equals(baseValidator.getName())) {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
if (enumVal.length() / 2 > xsFacets.maxLength) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MAXLENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
|
||||
SchemaSymbols.ATTVAL_BASE64BINARY.equals(baseValidator.getName())) {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
byte[] decodedVal = Base64.decode(enumVal);
|
||||
if (decodedVal != null && (new String(decodedVal)).length() > xsFacets.maxLength) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MAXLENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
if (enumVal.length() > xsFacets.maxLength) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MAXLENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // checkEnumerationAndMaxLengthInconsistency
|
||||
|
||||
/*
|
||||
* Check whether values of xs:minLength and xs:enumeration are consistent. Report a warning message if they are not.
|
||||
*/
|
||||
private void checkEnumerationAndMinLengthInconsistency(XSSimpleType baseValidator, List<String> enumData, Element contextNode, String typeName) {
|
||||
if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
|
||||
SchemaSymbols.ATTVAL_HEXBINARY.equals(baseValidator.getName())) {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
if (enumVal.length() / 2 < xsFacets.minLength) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MINLENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
|
||||
SchemaSymbols.ATTVAL_BASE64BINARY.equals(baseValidator.getName())) {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
byte[] decodedVal = Base64.decode(enumVal);
|
||||
if (decodedVal != null && (new String(decodedVal)).length() < xsFacets.minLength) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MINLENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
if (enumVal.length() < xsFacets.minLength) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_MINLENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // checkEnumerationAndMinLengthInconsistency
|
||||
|
||||
/*
|
||||
* Check whether values of xs:length and xs:enumeration are consistent. Report a warning message if they are not.
|
||||
*/
|
||||
private void checkEnumerationAndLengthInconsistency(XSSimpleType baseValidator, List<String> enumData, Element contextNode, String typeName) {
|
||||
if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
|
||||
SchemaSymbols.ATTVAL_HEXBINARY.equals(baseValidator.getName())) {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
if (enumVal.length() / 2 != xsFacets.length) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_LENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(baseValidator.getNamespace()) &&
|
||||
SchemaSymbols.ATTVAL_BASE64BINARY.equals(baseValidator.getName())) {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
byte[] decodedVal = Base64.decode(enumVal);
|
||||
if (decodedVal != null && (new String(decodedVal)).length() != xsFacets.length) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_LENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int enumIdx = 0; enumIdx < enumData.size(); enumIdx++) {
|
||||
String enumVal = (enumData.get(enumIdx));
|
||||
if (enumVal.length() != xsFacets.length) {
|
||||
reportSchemaWarning("FacetsContradict", new Object[]{enumVal, SchemaSymbols.ELT_LENGTH, typeName}, contextNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // checkEnumerationAndLengthInconsistency
|
||||
|
||||
|
||||
// return whether QName/NOTATION is part of the given type
|
||||
private boolean containsQName(XSSimpleType type) {
|
||||
@ -724,6 +866,10 @@ abstract class XSDAbstractTraverser {
|
||||
fSchemaHandler.reportSchemaError(key, args, ele);
|
||||
}
|
||||
|
||||
void reportSchemaWarning (String key, Object[] args, Element ele) {
|
||||
fSchemaHandler.reportSchemaWarning(key, args, ele);
|
||||
}
|
||||
|
||||
/**
|
||||
* Element/Attribute traversers call this method to check whether
|
||||
* the type is NOTATION without enumeration facet
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -62,7 +62,7 @@ import org.w3c.dom.Element;
|
||||
* </complexType>
|
||||
*
|
||||
* @xerces.internal
|
||||
*
|
||||
* @LastModified: Apr 2019
|
||||
*/
|
||||
|
||||
class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser {
|
||||
@ -574,7 +574,7 @@ class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser {
|
||||
short fixedFacets = 0 ;
|
||||
|
||||
if (simpleContent!=null) {
|
||||
FacetInfo fi = traverseFacets(simpleContent, baseValidator, schemaDoc);
|
||||
FacetInfo fi = traverseFacets(simpleContent, fComplexTypeDecl, baseValidator, schemaDoc);
|
||||
attrNode = fi.nodeAfterFacets;
|
||||
facetData = fi.facetdata;
|
||||
presentFacets = fi.fPresentFacets;
|
||||
@ -1193,9 +1193,6 @@ class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser {
|
||||
// REVISIT: do we need to remove all attribute uses already added into
|
||||
// the attribute group? maybe it's ok to leave them there. -SG
|
||||
fAttrGrp.fAttributeWC = getErrorWildcard();
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
private void contentBackup() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
@ -60,6 +60,7 @@ import com.sun.org.apache.xerces.internal.util.StAXLocationWrapper;
|
||||
import com.sun.org.apache.xerces.internal.util.SymbolHash;
|
||||
import com.sun.org.apache.xerces.internal.util.SymbolTable;
|
||||
import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLChar;
|
||||
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
|
||||
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
|
||||
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
|
||||
@ -129,7 +130,7 @@ import org.xml.sax.XMLReader;
|
||||
* @author Neil Graham, IBM
|
||||
* @author Pavani Mukthipudi, Sun Microsystems
|
||||
*
|
||||
* @LastModified: Nov 2017
|
||||
* @LastModified: Apr 2019
|
||||
*/
|
||||
@SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory
|
||||
public class XSDHandler {
|
||||
@ -591,10 +592,27 @@ public class XSDHandler {
|
||||
} //is instanceof XMLInputSource
|
||||
|
||||
if (schemaRoot == null) {
|
||||
// something went wrong right off the hop
|
||||
if (is instanceof XSInputSource) {
|
||||
return fGrammarBucket.getGrammar(desc.getTargetNamespace());
|
||||
// Need to return a grammar. If the XSInputSource has a list
|
||||
// of grammar objects, then get the first one and return it.
|
||||
// If it has a list of components, then get the grammar that
|
||||
// contains the first component and return it.
|
||||
// If we return null, the XMLSchemaLoader will think nothing
|
||||
// was loaded, and will not try to put the grammar objects
|
||||
// into the grammar pool.
|
||||
XSInputSource xsinput = (XSInputSource)is;
|
||||
SchemaGrammar[] grammars = xsinput.getGrammars();
|
||||
if (grammars != null && grammars.length > 0) {
|
||||
grammar = fGrammarBucket.getGrammar(grammars[0].getTargetNamespace());
|
||||
}
|
||||
else {
|
||||
XSObject[] components = xsinput.getComponents();
|
||||
if (components != null && components.length > 0) {
|
||||
grammar = fGrammarBucket.getGrammar(components[0].getNamespace());
|
||||
}
|
||||
}
|
||||
}
|
||||
// something went wrong right off the hop
|
||||
return grammar;
|
||||
}
|
||||
|
||||
@ -1299,6 +1317,7 @@ public class XSDHandler {
|
||||
String qName = currSchemaDoc.fTargetNamespace == null ?
|
||||
","+lName:
|
||||
currSchemaDoc.fTargetNamespace +","+lName;
|
||||
qName = XMLChar.trim(qName);
|
||||
String componentType = DOMUtil.getLocalName(redefineComp);
|
||||
if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
|
||||
checkForDuplicateNames(qName, ATTRIBUTEGROUP_TYPE, fUnparsedAttributeGroupRegistry, fUnparsedAttributeGroupRegistrySub, redefineComp, currSchemaDoc);
|
||||
@ -1343,6 +1362,7 @@ public class XSDHandler {
|
||||
String qName = currSchemaDoc.fTargetNamespace == null?
|
||||
","+lName:
|
||||
currSchemaDoc.fTargetNamespace +","+lName;
|
||||
qName = XMLChar.trim(qName);
|
||||
String componentType = DOMUtil.getLocalName(globalComp);
|
||||
|
||||
if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTE)) {
|
||||
@ -2466,9 +2486,15 @@ public class XSDHandler {
|
||||
return getSchemaDocument0(key, schemaId, schemaElement);
|
||||
}
|
||||
catch (XMLStreamException e) {
|
||||
StAXLocationWrapper slw = new StAXLocationWrapper();
|
||||
slw.setLocation(e.getLocation());
|
||||
throw new XMLParseException(slw, e.getMessage(), e);
|
||||
Throwable t = e.getNestedException();
|
||||
if (t instanceof IOException) {
|
||||
exception = (IOException) t;
|
||||
}
|
||||
else {
|
||||
StAXLocationWrapper slw = new StAXLocationWrapper();
|
||||
slw.setLocation(e.getLocation());
|
||||
throw new XMLParseException(slw, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
exception = e;
|
||||
@ -2741,16 +2767,29 @@ public class XSDHandler {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addNewImportedGrammars(SchemaGrammar srcGrammar, SchemaGrammar dstGrammar) {
|
||||
final ArrayList<SchemaGrammar> igs1 = (ArrayList<SchemaGrammar>)srcGrammar.getImportedGrammars();
|
||||
if (igs1 != null) {
|
||||
ArrayList<SchemaGrammar> igs2 = (ArrayList<SchemaGrammar>)dstGrammar.getImportedGrammars();
|
||||
|
||||
if (igs2 == null) {
|
||||
igs2 = (ArrayList<SchemaGrammar>)igs1.clone();
|
||||
dstGrammar.setImportedGrammars(igs2);
|
||||
final ArrayList<SchemaGrammar> src = (ArrayList<SchemaGrammar>)srcGrammar.getImportedGrammars();
|
||||
if (src != null) {
|
||||
ArrayList<SchemaGrammar> dst = (ArrayList<SchemaGrammar>)dstGrammar.getImportedGrammars();
|
||||
if (dst == null) {
|
||||
dst = new ArrayList<>();
|
||||
dstGrammar.setImportedGrammars(dst);
|
||||
}
|
||||
else {
|
||||
updateImportList(igs1, igs2);
|
||||
for (SchemaGrammar sg :src) {
|
||||
// Can't use the object from the source import list directly.
|
||||
// It's possible there is already a grammar with the same
|
||||
// namespace in the bucket but a different object.
|
||||
// This can happen if the bucket has grammar A1, and we try
|
||||
// to add B and A2, where A2 imports B. When B is added, we
|
||||
// create a new object B' and store it in the bucket. Then we
|
||||
// try to merge A2 and A1. We can't use B. Need to get B' from
|
||||
// the bucket and store it in A's import list.
|
||||
SchemaGrammar sg1 = fGrammarBucket.getGrammar(sg.getTargetNamespace());
|
||||
if (sg1 != null) {
|
||||
sg = sg1;
|
||||
}
|
||||
if (!containedImportedGrammar(dst, sg)) {
|
||||
dst.add(sg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3162,7 +3201,7 @@ public class XSDHandler {
|
||||
|
||||
private void addRelatedType(XSTypeDefinition type, List<XSObject> componentList, String namespace, Map<String, List<String>> dependencies) {
|
||||
if (!type.getAnonymous()) {
|
||||
if (!type.getNamespace().equals(SchemaSymbols.URI_SCHEMAFORSCHEMA)) { //REVISIT - do we use == instead
|
||||
if (!SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(type.getNamespace())) { //REVISIT - do we use == instead
|
||||
if (!componentList.contains(type)) {
|
||||
final List<String> importedNamespaces = findDependentNamespaces(namespace, dependencies);
|
||||
addNamespaceDependency(namespace, type.getNamespace(), importedNamespaces);
|
||||
|
@ -395,7 +395,7 @@ class XSDSimpleTypeTraverser extends XSDAbstractTraverser {
|
||||
}
|
||||
// now traverse facets, if it's derived by restriction
|
||||
if (restriction && content != null) {
|
||||
FacetInfo fi = traverseFacets(content, baseValidator, schemaDoc);
|
||||
FacetInfo fi = traverseFacets(content, newDecl, baseValidator, schemaDoc);
|
||||
content = fi.nodeAfterFacets;
|
||||
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,23 +24,70 @@
|
||||
package validation;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Listeners;
|
||||
import org.testng.annotations.Test;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149915 8222991
|
||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||
* @run testng/othervm -DrunSecMngr=true validation.SchemaTest
|
||||
* @run testng/othervm validation.SchemaTest
|
||||
* @summary Test Schema creation
|
||||
* @bug 8149915
|
||||
*/
|
||||
@Listeners({jaxp.library.FilePolicy.class})
|
||||
public class SchemaTest {
|
||||
/**
|
||||
* Verifies that an over-the-limit value of an enumeration is caught as a
|
||||
* warning.
|
||||
* @throws Exception if the test fails
|
||||
*/
|
||||
@Test
|
||||
public void testSchema() throws Exception {
|
||||
String xsd = "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n" +
|
||||
" <xsd:simpleType name=\"PaymentStatus\">\n" +
|
||||
" <xsd:restriction base=\"xsd:string\">\n" +
|
||||
" <xsd:maxLength value=\"15\"/>\n" +
|
||||
" <xsd:enumeration value=\"AWAIT_PAY_INFO\"/>\n" +
|
||||
" <xsd:enumeration value=\"AWAIT_AUTH\"/>\n" +
|
||||
" <xsd:enumeration value=\"REQUESTED_AUTH\"/>\n" +
|
||||
" <xsd:enumeration value=\"REQUESTED_CHARGE\"/>\n" +
|
||||
" <xsd:enumeration value=\"PAID\"/>\n" +
|
||||
" </xsd:restriction>\n" +
|
||||
" </xsd:simpleType> \n" +
|
||||
"</xsd:schema>";
|
||||
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
final List<SAXParseException> exceptions = new ArrayList<>();
|
||||
|
||||
factory.setErrorHandler(new ErrorHandler()
|
||||
{
|
||||
@Override
|
||||
public void warning(SAXParseException exception) throws SAXException
|
||||
{
|
||||
exceptions.add(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatalError(SAXParseException exception) throws SAXException
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void error(SAXParseException exception) throws SAXException
|
||||
{}
|
||||
});
|
||||
factory.newSchema(new StreamSource(new StringReader(xsd)));
|
||||
Assert.assertTrue(exceptions.get(0).toString().contains("FacetsContradict"),
|
||||
"Report warning when the maxLength limit is exceeded in an enumeration");
|
||||
}
|
||||
|
||||
/*
|
||||
* @bug 8149915
|
||||
|
Loading…
x
Reference in New Issue
Block a user