1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-01-12 09:17:37 +03:00

Hopefully finished validation against facets to use the normalized value

* xmlschemas.c xmlschemastypes.c include/libxml/xmlschemastypes.h:
  Hopefully finished validation against facets to use the normalized
  value of both, the facets and instance values. Added
  xmlSchemaValidateLengthFacetWhtsp(), xmlSchemaValidateFacetWhtsp()
  and xmlSchemaGetValType() to the schema API.
This commit is contained in:
Kasimier T. Buchcik 2005-03-16 16:29:18 +00:00
parent 9fcb491cda
commit 478d693fa2
4 changed files with 694 additions and 319 deletions

View File

@ -1,3 +1,11 @@
Wed Mar 16 17:20:25 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
* xmlschemas.c xmlschemastypes.c include/libxml/xmlschemastypes.h:
Hopefully finished validation against facets to use the normalized
value of both, the facets and instance values. Added
xmlSchemaValidateLengthFacetWhtsp(), xmlSchemaValidateFacetWhtsp()
and xmlSchemaGetValType() to the schema API.
Wed Mar 16 13:55:31 CET 2005 Daniel Veillard <daniel@veillard.com>
* libxml.spec.in: do not package .la files

View File

@ -51,15 +51,13 @@ XMLPUBFUN int XMLCALL
xmlSchemaFacetPtr facet,
const xmlChar *value,
xmlSchemaValPtr val);
#if 0
XMLPUBFUN int XMLCALL
xmlSchemaValidateFacetWhtsp (xmlSchemaFacetPtr facet,
xmlSchemaWhitespaceValueType fws,
xmlSchemaValType valType,
xmlSchemaValPtr val,
xmlSchemaValType valType,
const xmlChar *value,
xmlSchemaValPtr val,
xmlSchemaWhitespaceValueType ws);
#endif
XMLPUBFUN void XMLCALL
xmlSchemaFreeValue (xmlSchemaValPtr val);
XMLPUBFUN xmlSchemaFacetPtr XMLCALL
@ -97,7 +95,14 @@ XMLPUBFUN int XMLCALL
xmlSchemaFacetPtr facet,
const xmlChar *value,
xmlSchemaValPtr val,
unsigned long *length) ;
unsigned long *length);
XMLPUBFUN int XMLCALL
xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacetPtr facet,
xmlSchemaValType valType,
const xmlChar *value,
xmlSchemaValPtr val,
unsigned long *length,
xmlSchemaWhitespaceValueType ws);
XMLPUBFUN int XMLCALL
xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaTypePtr type,
const xmlChar *value,
@ -120,6 +125,8 @@ XMLPUBFUN int XMLCALL
xmlSchemaWhitespaceValueType yws);
XMLPUBFUN xmlSchemaValPtr XMLCALL
xmlSchemaCopyValue (xmlSchemaValPtr val);
XMLPUBFUN xmlSchemaValType XMLCALL
xmlSchemaGetValType (xmlSchemaValPtr val);
#ifdef __cplusplus
}

View File

@ -562,6 +562,15 @@ xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name);
static void
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
static int
xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
xmlSchemaTypePtr type,
const xmlChar *value,
xmlSchemaValPtr *val);
static xmlSchemaTypePtr
xmlSchemaGetSimpleContentType(xmlSchemaTypePtr complexType);
static int
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
/************************************************************************
* *
@ -1191,6 +1200,56 @@ xmlSchemaPRequestItemDes(xmlChar **buf,
xmlSchemaFormatItemForReport(buf, NULL, item, itemNode, 1);
}
/**
* xmlSchemaGetCanonValueWhtsp:
* @val: the precomputed value
* @retValue: the returned value
* @ws: the whitespace type of the value
*
* Get a the cononical representation of the value.
* The caller has to free the returned retValue.
*
* Returns 0 if the value could be built and -1 in case of
* API errors or if the value type is not supported yet.
*/
static int
xmlSchemaGetCanonValueWhtsp(const xmlChar *value,
xmlSchemaValPtr val,
xmlSchemaWhitespaceValueType ws,
const xmlChar **retValue)
{
xmlSchemaValType valType;
if ((retValue == NULL) || (value == NULL) || (val == NULL))
return (-1);
*retValue = NULL;
valType = xmlSchemaGetValType(val);
switch (valType) {
case XML_SCHEMAS_STRING:
if (value == NULL)
*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
else
*retValue =
BAD_CAST xmlStrdup(value);
break;
case XML_SCHEMAS_NORMSTRING:
if (value == NULL)
*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
else {
if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
*retValue = xmlSchemaCollapseString(value);
else
*retValue = xmlSchemaWhiteSpaceReplace(value);
if ((*retValue) == NULL)
*retValue = BAD_CAST xmlStrdup(value);
}
break;
default:
return (xmlSchemaGetCanonValue(val, retValue));
}
return (0);
}
/**
* xmlSchemaFormatFacetEnumSet:
* @buf: the string buffer
@ -1203,11 +1262,61 @@ xmlSchemaPRequestItemDes(xmlChar **buf,
static const xmlChar *
xmlSchemaFormatFacetEnumSet(xmlChar **buf, xmlSchemaTypePtr type)
{
xmlSchemaFacetLinkPtr link;
xmlSchemaFacetPtr facet;
xmlSchemaWhitespaceValueType ws;
const xmlChar *value;
int res;
if (*buf != NULL)
xmlFree(*buf);
*buf = NULL;
do {
/*
* Use the whitespace type of the base type.
*/
if (type->type == XML_SCHEMA_TYPE_COMPLEX)
/* TODO: Get rid of this case. */
ws = (xmlSchemaWhitespaceValueType)
xmlSchemaGetWhiteSpaceFacetValue(
xmlSchemaGetSimpleContentType(type));
else
ws = (xmlSchemaWhitespaceValueType)
xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
for (facet = type->facets; facet != NULL; facet = facet->next) {
if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
continue;
res = xmlSchemaGetCanonValueWhtsp(facet->value, facet->val,
ws, &value);
if (res == -1) {
xmlSchemaVErr(NULL, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaFormatFacetEnumSet, failed to "
"compute the canonical lexical representation.\n",
NULL, NULL);
if (*buf != NULL)
xmlFree(*buf);
*buf = NULL;
return (NULL);
}
if (*buf == NULL) {
*buf = xmlStrdup(BAD_CAST "'");
*buf = xmlStrcat(*buf, value);
*buf = xmlStrcat(*buf, BAD_CAST "'");
} else {
*buf = xmlStrcat(*buf, BAD_CAST ", '");
*buf = xmlStrcat(*buf, value);
*buf = xmlStrcat(*buf, BAD_CAST "'");
}
}
if (type->type == XML_SCHEMA_TYPE_COMPLEX)
/* TODO: Get rid of this case. */
type = xmlSchemaGetSimpleContentType(type);
else
type = type->baseType;
} while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
#if 0
for (link = type->facetSet; link != NULL; link = link->next) {
if (link->facet->type == XML_SCHEMA_FACET_ENUMERATION) {
if (*buf == NULL) {
@ -1221,6 +1330,7 @@ xmlSchemaFormatFacetEnumSet(xmlChar **buf, xmlSchemaTypePtr type)
}
}
}
#endif
return ((const xmlChar *) *buf);
}
@ -8350,15 +8460,9 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
if (xmlStrEqual(schema->targetNamespace,
include->targetNamespace)) {
fprintf(stderr, "already included chameleon '%s', TNS '%s'\n",
include->schemaLocation,
include->origTargetNamespace);
goto check_targetNamespace;
}
} else {
fprintf(stderr, "already included '%s', TNS '%s'\n",
include->schemaLocation,
include->origTargetNamespace);
goto check_targetNamespace;
}
}
@ -10738,6 +10842,9 @@ xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
static xmlSchemaTypePtr
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
{
if ((type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) ||
(type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION))
return (0);
while (type != NULL) {
if (type->type == XML_SCHEMA_TYPE_BASIC)
return (type);
@ -10748,7 +10855,6 @@ xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
}
#endif
/**
* xmlSchemaBuildAttributeUsesOwned:
* @ctxt: the schema parser context
@ -13403,7 +13509,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"the complex type '%s' has no base type", type->name);
return (-1);
}
@ -13453,7 +13559,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"CT '%s' (restricting): <simpleContent> has no "
"<restriction>",
type->name);
@ -13465,7 +13571,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"CT '%s' (restricting): <restriction> has no "
"mandatory <simpleType>",
type->name);
@ -13477,7 +13583,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"CT '%s' (restricting), the base type has no "
"content type", type->name);
return (-1);
@ -13494,7 +13600,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"CT '%s' (restricting): <simpleType> has no "
"<restriction>", type->name);
return (-1);
@ -13538,7 +13644,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"CT '%s' (extending), the base type has no content "
"type", type->name);
return (-1);
@ -13547,7 +13653,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"CT '%s' (extending), the content type of the "
"base is not a simple type", type->name);
return (-1);
@ -13568,7 +13674,7 @@ xmlSchemaComputeContentType(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INTERNAL,
NULL, type, NULL,
"Internal error: xmlSchemaGetContentType, "
"Internal error: xmlSchemaComputeContentType, "
"'%s', the content type could not be determined",
type->name);
return (-1);
@ -14179,8 +14285,9 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
*/
/*
* This function is intended to deliver a compiled value
* on the facet. In XML Schemas the type holding a facet,
* cannot be a built-in type. Thus to ensure that other API
* on the facet. In this implementation of XML Schemata the
* type holding a facet, won't be a built-in type.
* Thus to ensure that other API
* calls (relaxng) do work, if the given type is a built-in
* type, we will assume that the given built-in type *is
* already* the base type.
@ -14231,21 +14338,23 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
* of the facet.
*/
ret = xmlSchemaValidateSimpleTypeValue(vctxt, base,
facet->value, 0, 1, 1, 0);
facet->val = vctxt->value;
vctxt->value = NULL;
facet->value, 0, 1, 1, 0);
if (ret > 0) {
/* error code */
if (ctxt != NULL) {
xmlSchemaPErrExt(ctxt, facet->node,
XML_SCHEMAP_INVALID_FACET,
NULL, NULL, NULL,
"Type definition '%s': The value '%s' of the "
"facet '%s' is not valid.\n",
name, facet->value,
xmlSchemaFacetTypeToString(facet->type),
NULL, NULL);
xmlChar *str = NULL;
xmlSchemaPCustomErrExt(ctxt,
XML_SCHEMAP_INVALID_FACET_VALUE,
NULL, (xmlSchemaTypePtr) facet, facet->node,
"The value '%s' of the facet does not validate "
"against the base type '%s'",
facet->value,
xmlSchemaFormatQName(&str,
base->targetNamespace, base->name), NULL);
FREE_AND_NULL(str)
}
/* xmlSchemaFacetTypeToString(facet->type), */
ret = -1;
} else if (ret < 0) {
xmlSchemaPErrExt(ctxt, facet->node,
@ -14258,7 +14367,30 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
xmlSchemaFacetTypeToString(facet->type),
base->name, NULL, NULL);
ret = -1;
}
} else {
if (vctxt->value != NULL) {
facet->val = vctxt->value;
vctxt->value = NULL;
} else {
xmlChar *str;
/*
* Ensure computed values even for type string.
* TODO OPTIMIZE MEMORY: The value will be hold twice,
* by the facet->value and by the computed value.
*/
str = xmlStrdup(facet->value);
if (xmlSchemaPostCreateVal(vctxt, typeDecl,
BAD_CAST str, &(facet->val)) == -1) {
FREE_AND_NULL(str)
xmlSchemaPErr(ctxt, typeDecl->node,
XML_SCHEMAP_INTERNAL,
"Internal error: xmlSchemaCheckFacet, "
"post-creating a computed value.\n",
NULL, NULL);
/* Note that we don't return a failure yet.*/
}
}
}
if (reuseValCtxt == 0)
xmlSchemaFreeValidCtxt(vctxt);
break;
@ -14288,14 +14420,11 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
if (tmp != 0) {
/* error code */
if (ctxt != NULL) {
xmlSchemaPErrExt(ctxt, facet->node,
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INVALID_FACET_VALUE,
NULL, NULL, NULL,
"Type definition '%s': The value '%s' of the "
"facet '%s' is not valid.\n",
name, facet->value,
xmlSchemaFacetTypeToString(facet->type),
NULL, NULL);
NULL, (xmlSchemaTypePtr) facet, facet->node,
"The value '%s' of the facet is not a valid "
"nonNegativeInteger", facet->value);
}
ret = -1;
}
@ -14310,11 +14439,12 @@ xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
} else {
if (ctxt != NULL) {
xmlSchemaPErr(ctxt, facet->node,
XML_SCHEMAP_INVALID_WHITE_SPACE,
"Type definition '%s': The value '%s' of the "
"facet 'whiteSpace' is not valid.\n",
name, facet->value);
/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_INVALID_FACET_VALUE,
NULL, (xmlSchemaTypePtr) facet, facet->node,
"The value '%s' of the facet is not a valid",
facet->value);
}
ret = -1;
}
@ -15301,8 +15431,8 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
* by ·restriction· from it) the value of whiteSpace is fixed to
* collapse
*/
if ((anc->type == XML_SCHEMA_TYPE_BASIC) &&
(anc->builtInType == XML_SCHEMAS_STRING)) {
if ((anc->builtInType == XML_SCHEMAS_STRING) ||
(anc->builtInType == XML_SCHEMAS_NORMSTRING)) {
lin = type->facetSet;
do {
@ -15311,8 +15441,11 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
break;
}
lin = lin->next;
} while (lin != NULL);
break;
} while (lin != NULL);
if (anc->builtInType == XML_SCHEMAS_NORMSTRING)
return (XML_SCHEMAS_FACET_REPLACE);
else
return (XML_SCHEMAS_FACET_PRESERVE);
}
anc = anc->baseType;
} while (anc != anyST);
@ -15345,12 +15478,24 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
{
int ret = 0;
xmlNodePtr node;
xmlSchemaTypePtr biType; /* The build-in type. */
xmlSchemaTypePtr biType; /* The build-in type. */
xmlSchemaTypePtr tmpType;
xmlSchemaFacetLinkPtr facetLink;
int retFacet;
xmlSchemaFacetPtr facet;
unsigned long len = 0;
xmlSchemaWhitespaceValueType ws;
if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
xmlSchemaTypePtr tp;
/*
* TODO: Get rid of this case: the complex type still holds facets in some
* cases.
*/
tp = xmlSchemaGetSimpleContentType(type);
ws = (xmlSchemaWhitespaceValueType) xmlSchemaGetWhiteSpaceFacetValue(tp);
} else
ws = (xmlSchemaWhitespaceValueType) xmlSchemaGetWhiteSpaceFacetValue(type);
#ifdef DEBUG_UNION_VALIDATION
printf("Facets of type: '%s'\n", (const char *) type->name);
@ -15393,15 +15538,20 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
case XML_SCHEMA_FACET_MAXLENGTH:
if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
ret = xmlSchemaValidateListSimpleTypeFacet(facet,
value, length, 0);
value, length, NULL);
len = length;
} else
ret = xmlSchemaValidateLengthFacet(biType, facet,
value, ctxt->value, &len);
ret = xmlSchemaValidateLengthFacetWhtsp(facet,
(xmlSchemaValType) biType->builtInType,
value, ctxt->value, &len, ws);
break;
default:
ret = xmlSchemaValidateFacet(biType, facet, value,
ctxt->value);
ret = xmlSchemaValidateFacetWhtsp(facet, ws,
biType->builtInType, value, ctxt->value, ws);
/*
* ret = xmlSchemaValidateFacet(biType, facet, value,
* ctxt->value);
*/
}
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@ -15416,35 +15566,64 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
facetLink = facetLink->next;
}
if (ret >= 0) {
/*
* Process enumerations.
*/
retFacet = 0;
facetLink = type->facetSet;
while (facetLink != NULL) {
if (facetLink->facet->type == XML_SCHEMA_FACET_ENUMERATION) {
retFacet = xmlSchemaValidateFacet(biType, facetLink->facet,
value, ctxt->value);
if (retFacet <= 0)
break;
}
facetLink = facetLink->next;
}
if (retFacet > 0) {
ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
if (fireErrors)
xmlSchemaVFacetErr(ctxt, ret, node,
value, 0, type, NULL, NULL, NULL, NULL, NULL);
} else if (retFacet < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaValidateFacetsInternal, "
"validating facet of type '%s'.\n",
BAD_CAST "enumeration", NULL);
ret = -1;
}
}
}
if (ret >= 0) {
xmlSchemaWhitespaceValueType fws;
/*
* Process enumerations. Facet values are in the value space
* of the defining type's base type. This seems to be a bug in the
* XML Schema 1.0 spec. For use, the normalized value is only
* significant for enumerations. We need to localize the base type for eatch
* enumeration facet, thus walk the ancestor type axis.
*/
tmpType = type;
do {
/*
* Use the whitespace type of the base type.
*/
if (tmpType->type == XML_SCHEMA_TYPE_COMPLEX)
/* TODO: Get rid of this case. */
fws = (xmlSchemaWhitespaceValueType)
xmlSchemaGetWhiteSpaceFacetValue(
xmlSchemaGetSimpleContentType(tmpType));
else
fws = (xmlSchemaWhitespaceValueType)
xmlSchemaGetWhiteSpaceFacetValue(tmpType->baseType);
retFacet = 0;
for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
continue;
retFacet = xmlSchemaValidateFacetWhtsp(facet, fws,
biType->builtInType, value, ctxt->value, ws);
if (retFacet == 0)
break;
else if (retFacet < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaValidateFacetsInternal, "
"validating enumeration facet '%s' of type '%s'.\n",
facet->value, tmpType->name);
ret = -1;
break;
}
}
if (retFacet <= 0)
break;
if (tmpType->type == XML_SCHEMA_TYPE_COMPLEX)
/* TODO: Get rid of this case. */
tmpType = xmlSchemaGetSimpleContentType(tmpType);
else
tmpType = tmpType->baseType;
} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
if (retFacet > 0) {
ret = XML_SCHEMAV_CVC_PATTERN_VALID;
if (fireErrors) {
xmlSchemaVFacetErr(ctxt, ret, node, value, 0, type, NULL,
NULL, NULL, NULL, NULL);
}
}
}
if (ret >= 0) {
/*
* Process patters. Pattern facets are ORed at type level
@ -15474,8 +15653,12 @@ xmlSchemaValidateFacetsInternal(xmlSchemaValidCtxtPtr ctxt,
facet = facetLink->facet;
}
if (retFacet != 0)
break;
tmpType = tmpType->baseType;
break;
if (tmpType->type == XML_SCHEMA_TYPE_COMPLEX)
/* TODO: Get rid of this case. */
tmpType = xmlSchemaGetSimpleContentType(tmpType);
else
tmpType = tmpType->baseType;
} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
if (retFacet > 0) {
ret = XML_SCHEMAV_CVC_PATTERN_VALID;
@ -16179,6 +16362,34 @@ xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
return (ret);
}
static xmlSchemaTypePtr
xmlSchemaGetSimpleContentType(xmlSchemaTypePtr complexType)
{
xmlSchemaTypePtr ret;
if (complexType->type != XML_SCHEMA_TYPE_COMPLEX)
return (NULL);
if (complexType->contentTypeDef != NULL)
return (complexType->contentTypeDef);
/*
* TODO: This is only a workaround until the simple content
* type is computed for complex types with simple content.
*/
ret = complexType->baseType;
while (ret != NULL) {
if (IS_SIMPLE_TYPE(ret))
return (ret);
if (ret->builtInType == XML_SCHEMAS_ANYTYPE)
return (NULL);
if ((ret->type == XML_SCHEMA_TYPE_COMPLEX) &&
(ret->contentTypeDef != NULL))
ret = ret->contentTypeDef;
else
ret = ret->baseType;
}
return (ret);
}
/**
* xmlSchemaValidateSimpleTypeValue:
* @ctxt: a schema validation context
@ -16289,18 +16500,20 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
}
if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
xmlSchemaTypePtr base, anyType;
xmlSchemaTypePtr simpType, anyType;
anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
base = type->baseType;
while ((base != NULL) &&
(base->type != XML_SCHEMA_TYPE_SIMPLE) &&
(base->type != XML_SCHEMA_TYPE_BASIC) &&
(base != anyType)) {
base = base->baseType;
simpType = xmlSchemaGetSimpleContentType(type);
if (simpType == NULL) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
"failed to obtain the simple content type of the complex "
"type '%s'\n",
type->name, NULL);
return (-1);
}
ret = xmlSchemaValidateSimpleTypeValue(ctxt, base, value, 1, 0, 1, 0);
ret = xmlSchemaValidateSimpleTypeValue(ctxt, simpType, value, 1, 0, 1, 0);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaValidateSimpleTypeValue, "
@ -16309,15 +16522,14 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
} else if ((ret == 0) && (applyFacets) && (type->facetSet != NULL)) {
/*
* Check facets.
*/
/*
* This is somehow not nice, since if an error occurs
*
* TODO: This is somehow not nice, since if an error occurs
* the reported type will be the complex type; the spec
* wants a simple type to be created on the complex type
* if it has a simple content. For now we have to live with
* it.
*/
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
*/
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@ -16393,8 +16605,8 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
} else if ((applyFacets) && (type->facetSet != NULL)) {
/*
* Check facets.
*/
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
*/
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@ -16461,7 +16673,7 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
"validating list simple type '%s'\n",
type->name, NULL);
} else if ((ret == 0) && (applyFacets)) {
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, len, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@ -16555,7 +16767,7 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
value = (const xmlChar *) normValue;
}
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
ret = xmlSchemaValidateFacetsInternal(ctxt, type,
value, 0, fireErrors);
if (ret < 0) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAV_INTERNAL,
@ -19539,7 +19751,12 @@ xmlSchemaValidateElementByComplexType(xmlSchemaValidCtxtPtr ctxt,
ctxt->type = oldtype;
return (-1);
}
}
}
#if 0
/*
* REMOVED since handled by xmlSchemaValidateSimpleTypeValue
* already.
*/
if (ret == 0) {
/*
* Apply facets of the complexType. Be sure to pass the
@ -19571,6 +19788,7 @@ xmlSchemaValidateElementByComplexType(xmlSchemaValidCtxtPtr ctxt,
return (-1);
}
}
#endif
if (value != NULL)
xmlFree(value);
@ -19660,13 +19878,14 @@ xmlSchemaValidateElementByType(xmlSchemaValidCtxtPtr ctxt,
static int
xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
xmlSchemaTypePtr type,
const xmlChar *value,
xmlSchemaValPtr *val)
{
xmlSchemaTypePtr prim;
if (val == NULL) {
xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
xmlSchemaVErr(vctxt, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaPostCreateVal, "
"bad arguments", NULL, NULL);
@ -19675,13 +19894,10 @@ xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
/*
* Only string or anySimpleType values are expected to be post-created.
*/
prim = xmlSchemaGetPrimitiveType(vctxt->nodeInfo->typeDef);
prim = xmlSchemaGetPrimitiveType(type);
if ((prim->builtInType == XML_SCHEMAS_STRING) ||
(prim->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
{
#if 0
builtIn = xmlSchemaGetBuiltInTypeAncestor(vctxt->nodeInfo->typeDef);
#endif
if (value == NULL)
/* TODO: Can this happen at all? */
*val = xmlSchemaNewStringValue(XML_SCHEMAS_STRING,
@ -19689,7 +19905,7 @@ xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
else
*val = xmlSchemaNewStringValue(XML_SCHEMAS_STRING, value);
if ((*val) == NULL) {
xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
xmlSchemaVErr(vctxt, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaPostCreateVal, "
"failed to create the value", NULL, NULL);
@ -19697,7 +19913,7 @@ xmlSchemaPostCreateVal(xmlSchemaValidCtxtPtr vctxt,
}
return (0);
}
xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
xmlSchemaVErr(vctxt, NULL,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaPostCreateVal, "
"the given type is not supported", NULL, NULL);
@ -19771,7 +19987,8 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr vctxt,
/*
* Post-create the value.
*/
if (xmlSchemaPostCreateVal(vctxt, value, &(vctxt->value)) == -1) {
if (xmlSchemaPostCreateVal(vctxt, vctxt->attrInfo->typeDef,
value, &(vctxt->value)) == -1) {
ret = -1;
goto exit;
}
@ -19787,7 +20004,8 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr vctxt,
str = xmlStrdup(BAD_CAST "");
else
str = xmlStrdup(defValue);
if (xmlSchemaPostCreateVal(vctxt, str, &defVal) == -1) {
if (xmlSchemaPostCreateVal(vctxt, vctxt->attrInfo->typeDef,
str, &defVal) == -1) {
ret = -1;
FREE_AND_NULL(str)
goto exit;
@ -20296,6 +20514,7 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche
xmlChar *str = xmlStrdup(attrDecl->defValue);
if (xmlSchemaPostCreateVal(ctxt,
ctxt->attrInfo->typeDef,
str,
&(attrDecl->defVal)) == -1) {
FREE_AND_NULL(str)

View File

@ -50,6 +50,8 @@ extern double xmlXPathNINF;
#define IS_WSP_SPACE_CH(c) ((c) == 0x20)
#define IS_WSP_BLANK_CH(c) IS_BLANK_CH(c)
/* Date value */
typedef struct _xmlSchemaValDate xmlSchemaValDate;
typedef xmlSchemaValDate *xmlSchemaValDatePtr;
@ -1766,33 +1768,33 @@ xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value,
*/
static int
xmlSchemaParseUInt(const xmlChar **str, unsigned long *llo,
unsigned long *lmi, unsigned long *lhi) {
unsigned long *lmi, unsigned long *lhi) {
unsigned long lo = 0, mi = 0, hi = 0;
const xmlChar *tmp, *cur = *str;
int ret = 0, i = 0;
while (*cur == '0') { /* ignore leading zeroes */
cur++;
while (*cur == '0') { /* ignore leading zeroes */
cur++;
}
tmp = cur;
while ((*tmp != 0) && (*tmp >= '0') && (*tmp <= '9')) {
i++;tmp++;ret++;
i++;tmp++;ret++;
}
if (i > 24) {
*str = tmp;
return(-1);
*str = tmp;
return(-1);
}
while (i > 16) {
hi = hi * 10 + (*cur++ - '0');
i--;
hi = hi * 10 + (*cur++ - '0');
i--;
}
while (i > 8) {
mi = mi * 10 + (*cur++ - '0');
i--;
mi = mi * 10 + (*cur++ - '0');
i--;
}
while (i > 0) {
lo = lo * 10 + (*cur++ - '0');
i--;
lo = lo * 10 + (*cur++ - '0');
i--;
}
*str = cur;
@ -1923,6 +1925,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
}
if (*cur != 0)
goto return1; /* error if any extraneous chars */
if (val != NULL) {
v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
if (v != NULL) {
@ -2687,7 +2690,7 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
case XML_SCHEMAS_BYTE:
case XML_SCHEMAS_SHORT:
case XML_SCHEMAS_INT:{
const xmlChar *cur = value;
const xmlChar *cur = value;
unsigned long lo, mi, hi;
int sign = 0;
@ -3687,8 +3690,8 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
/**
* xmlSchemaComparePreserveReplaceStrings:
* @xv: a first string value
* @yv: a second string value
* @x: a first string value
* @y: a second string value
* @invert: inverts the result if x < y or x > y.
*
* Compare 2 string for their normalized values.
@ -3700,16 +3703,16 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
* case of error
*/
static int
xmlSchemaComparePreserveReplaceStrings(const xmlChar *xv,
const xmlChar *yv,
xmlSchemaComparePreserveReplaceStrings(const xmlChar *x,
const xmlChar *y,
int invert)
{
int tmp;
while ((*xv != 0) && (*yv != 0)) {
if (IS_WSP_REPLACE_CH(*yv)) {
if (! IS_WSP_SPACE_CH(*xv)) {
if ((*xv - 0x20) < 0) {
while ((*x != 0) && (*y != 0)) {
if (IS_WSP_REPLACE_CH(*y)) {
if (! IS_WSP_SPACE_CH(*x)) {
if ((*x - 0x20) < 0) {
if (invert)
return(1);
else
@ -3722,7 +3725,7 @@ xmlSchemaComparePreserveReplaceStrings(const xmlChar *xv,
}
}
} else {
tmp = *xv - *yv;
tmp = *x - *y;
if (tmp < 0) {
if (invert)
return(1);
@ -3736,16 +3739,16 @@ xmlSchemaComparePreserveReplaceStrings(const xmlChar *xv,
return(1);
}
}
xv++;
yv++;
x++;
y++;
}
if (*xv != 0) {
if (*x != 0) {
if (invert)
return(-1);
else
return(1);
}
if (*yv != 0) {
if (*y != 0) {
if (invert)
return(1);
else
@ -3768,8 +3771,8 @@ xmlSchemaComparePreserveReplaceStrings(const xmlChar *xv,
* case of error
*/
static int
xmlSchemaComparePreserveCollapseStrings(const xmlChar *xv,
const xmlChar *yv,
xmlSchemaComparePreserveCollapseStrings(const xmlChar *x,
const xmlChar *y,
int invert)
{
int tmp;
@ -3777,16 +3780,16 @@ xmlSchemaComparePreserveCollapseStrings(const xmlChar *xv,
/*
* Skip leading blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
yv++;
while IS_WSP_BLANK_CH(*y)
y++;
while ((*xv != 0) && (*yv != 0)) {
if (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv)) {
if (! IS_WSP_SPACE_CH(*xv)) {
while ((*x != 0) && (*y != 0)) {
if IS_WSP_BLANK_CH(*y) {
if (! IS_WSP_SPACE_CH(*x)) {
/*
* The utf2 character would have been replaced to 0x20.
* The yv character would have been replaced to 0x20.
*/
if ((*xv - 0x20) < 0) {
if ((*x - 0x20) < 0) {
if (invert)
return(1);
else
@ -3798,15 +3801,15 @@ xmlSchemaComparePreserveCollapseStrings(const xmlChar *xv,
return(1);
}
}
xv++;
yv++;
x++;
y++;
/*
* Skip contiguous blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
yv++;
while IS_WSP_BLANK_CH(*y)
y++;
} else {
tmp = *xv++ - *yv++;
tmp = *x++ - *y++;
if (tmp < 0) {
if (invert)
return(1);
@ -3821,19 +3824,19 @@ xmlSchemaComparePreserveCollapseStrings(const xmlChar *xv,
}
}
}
if (*xv != 0) {
if (*x != 0) {
if (invert)
return(-1);
else
return(1);
}
if (*yv != 0) {
if (*y != 0) {
/*
* Skip trailing blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
yv++;
if (*yv != 0) {
while IS_WSP_BLANK_CH(*y)
y++;
if (*y != 0) {
if (invert)
return(1);
else
@ -3857,8 +3860,8 @@ xmlSchemaComparePreserveCollapseStrings(const xmlChar *xv,
* case of error
*/
static int
xmlSchemaCompareReplaceCollapseStrings(const xmlChar *xv,
const xmlChar *yv,
xmlSchemaCompareReplaceCollapseStrings(const xmlChar *x,
const xmlChar *y,
int invert)
{
int tmp;
@ -3866,16 +3869,16 @@ xmlSchemaCompareReplaceCollapseStrings(const xmlChar *xv,
/*
* Skip leading blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
yv++;
while IS_WSP_BLANK_CH(*y)
y++;
while ((*xv != 0) && (*yv != 0)) {
if (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv)) {
if (! (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv))) {
while ((*x != 0) && (*y != 0)) {
if IS_WSP_BLANK_CH(*y) {
if (! IS_WSP_BLANK_CH(*x)) {
/*
* The utf2 character would have been replaced to 0x20.
* The yv character would have been replaced to 0x20.
*/
if ((*xv - 0x20) < 0) {
if ((*x - 0x20) < 0) {
if (invert)
return(1);
else
@ -3887,19 +3890,19 @@ xmlSchemaCompareReplaceCollapseStrings(const xmlChar *xv,
return(1);
}
}
xv++;
yv++;
x++;
y++;
/*
* Skip contiguous blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
yv++;
while IS_WSP_BLANK_CH(*y)
y++;
} else {
if (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv)) {
if IS_WSP_BLANK_CH(*x) {
/*
* The utf1 character would have been replaced to 0x20.
* The xv character would have been replaced to 0x20.
*/
if ((0x20 - *yv) < 0) {
if ((0x20 - *y) < 0) {
if (invert)
return(1);
else
@ -3911,26 +3914,26 @@ xmlSchemaCompareReplaceCollapseStrings(const xmlChar *xv,
return(1);
}
}
tmp = *xv++ - *yv++;
tmp = *x++ - *y++;
if (tmp < 0)
return(-1);
if (tmp > 0)
return(1);
}
}
if (*xv != 0) {
if (*x != 0) {
if (invert)
return(-1);
else
return(1);
}
if (*yv != 0) {
if (*y != 0) {
/*
* Skip trailing blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
yv++;
if (*yv != 0) {
while IS_WSP_BLANK_CH(*y)
y++;
if (*y != 0) {
if (invert)
return(1);
else
@ -3952,38 +3955,38 @@ xmlSchemaCompareReplaceCollapseStrings(const xmlChar *xv,
* case of error
*/
static int
xmlSchemaCompareReplacedStrings(const xmlChar *xv,
const xmlChar *yv)
xmlSchemaCompareReplacedStrings(const xmlChar *x,
const xmlChar *y)
{
int tmp;
while ((*xv != 0) && (*yv != 0)) {
if (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv)) {
if (! (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv))) {
if ((*xv - 0x20) < 0)
while ((*x != 0) && (*y != 0)) {
if IS_WSP_BLANK_CH(*y) {
if (! IS_WSP_BLANK_CH(*x)) {
if ((*x - 0x20) < 0)
return(-1);
else
return(1);
}
} else {
if (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv)) {
if ((0x20 - *yv) < 0)
if IS_WSP_BLANK_CH(*x) {
if ((0x20 - *y) < 0)
return(-1);
else
return(1);
}
tmp = *xv - *yv;
tmp = *x - *y;
if (tmp < 0)
return(-1);
if (tmp > 0)
return(1);
}
xv++;
yv++;
x++;
y++;
}
if (*xv != 0)
if (*x != 0)
return(1);
if (*yv != 0)
if (*y != 0)
return(-1);
return(0);
}
@ -3999,36 +4002,36 @@ xmlSchemaCompareReplacedStrings(const xmlChar *xv,
* case of error
*/
static int
xmlSchemaCompareNormStrings(const xmlChar *xv,
const xmlChar *yv) {
xmlSchemaCompareNormStrings(const xmlChar *x,
const xmlChar *y) {
int tmp;
while (IS_BLANK_CH(*xv)) xv++;
while (IS_BLANK_CH(*yv)) yv++;
while ((*xv != 0) && (*yv != 0)) {
if (IS_BLANK_CH(*xv)) {
if (!IS_BLANK_CH(*yv)) {
tmp = *xv - *yv;
while (IS_BLANK_CH(*x)) x++;
while (IS_BLANK_CH(*y)) y++;
while ((*x != 0) && (*y != 0)) {
if (IS_BLANK_CH(*x)) {
if (!IS_BLANK_CH(*y)) {
tmp = *x - *y;
return(tmp);
}
while (IS_BLANK_CH(*xv)) xv++;
while (IS_BLANK_CH(*yv)) yv++;
while (IS_BLANK_CH(*x)) x++;
while (IS_BLANK_CH(*y)) y++;
} else {
tmp = *xv++ - *yv++;
tmp = *x++ - *y++;
if (tmp < 0)
return(-1);
if (tmp > 0)
return(1);
}
}
if (*xv != 0) {
while (IS_BLANK_CH(*xv)) xv++;
if (*xv != 0)
if (*x != 0) {
while (IS_BLANK_CH(*x)) x++;
if (*x != 0)
return(1);
}
if (*yv != 0) {
while (IS_BLANK_CH(*yv)) yv++;
if (*yv != 0)
if (*y != 0) {
while (IS_BLANK_CH(*y)) y++;
if (*y != 0)
return(-1);
}
return(0);
@ -4129,10 +4132,8 @@ xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
xmlSchemaValType ytype,
xmlSchemaValPtr y,
const xmlChar *yvalue,
xmlSchemaWhitespaceValueType yws) {
if ((x == NULL) || (y == NULL))
return(-2);
xmlSchemaWhitespaceValueType yws)
{
switch (xtype) {
case XML_SCHEMAS_UNKNOWN:
case XML_SCHEMAS_ANYTYPE:
@ -4174,7 +4175,7 @@ xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
case XML_SCHEMAS_DURATION:
if ((x == NULL) || (y == NULL))
return(-2);
if (y->type == XML_SCHEMAS_DURATION)
if (ytype == XML_SCHEMAS_DURATION)
return(xmlSchemaCompareDurations(x, y));
return(-2);
case XML_SCHEMAS_TIME:
@ -4409,8 +4410,6 @@ xmlSchemaCompareValuesWhtsp(xmlSchemaValPtr x,
xmlSchemaValPtr y,
xmlSchemaWhitespaceValueType yws)
{
if ((x == NULL) || (y == NULL))
return(-2);
return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
y, NULL, yws));
}
@ -4532,19 +4531,19 @@ xmlSchemaValidateListSimpleTypeFacet(xmlSchemaFacetPtr facet,
*/
if (facet->type == XML_SCHEMA_FACET_LENGTH) {
if (actualLen != facet->val->value.decimal.lo) {
if (expectedLen != 0)
if (expectedLen != NULL)
*expectedLen = facet->val->value.decimal.lo;
return (XML_SCHEMAV_CVC_LENGTH_VALID);
}
} else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
if (actualLen < facet->val->value.decimal.lo) {
if (expectedLen != 0)
if (expectedLen != NULL)
*expectedLen = facet->val->value.decimal.lo;
return (XML_SCHEMAV_CVC_MINLENGTH_VALID);
}
} else if (facet->type == XML_SCHEMA_FACET_MAXLENGTH) {
if (actualLen > facet->val->value.decimal.lo) {
if (expectedLen != 0)
if (expectedLen != NULL)
*expectedLen = facet->val->value.decimal.lo;
return (XML_SCHEMAV_CVC_MAXLENGTH_VALID);
}
@ -4558,6 +4557,114 @@ xmlSchemaValidateListSimpleTypeFacet(xmlSchemaFacetPtr facet,
return (0);
}
/**
* xmlSchemaValidateLengthFacet:
* @type: the built-in type
* @facet: the facet to check
* @value: the lexical repr. of the value to be validated
* @val: the precomputed value
* @ws: the whitespace type of the value
* @length: the actual length of the value
*
* Checka a value against a "length", "minLength" and "maxLength"
* facet; sets @length to the computed length of @value.
*
* Returns 0 if the value is valid, a positive error code
* otherwise and -1 in case of an internal or API error.
*/
static int
xmlSchemaValidateLengthFacetInternal(xmlSchemaFacetPtr facet,
xmlSchemaTypeType valType,
const xmlChar *value,
xmlSchemaValPtr val,
unsigned long *length,
xmlSchemaWhitespaceValueType ws)
{
unsigned int len = 0;
if ((length == NULL) || (facet == NULL))
return (-1);
*length = 0;
if ((facet->type != XML_SCHEMA_FACET_LENGTH) &&
(facet->type != XML_SCHEMA_FACET_MAXLENGTH) &&
(facet->type != XML_SCHEMA_FACET_MINLENGTH))
return (-1);
/*
* TODO: length, maxLength and minLength must be of type
* nonNegativeInteger only. Check if decimal is used somehow.
*/
if ((facet->val == NULL) ||
((facet->val->type != XML_SCHEMAS_DECIMAL) &&
(facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
(facet->val->value.decimal.frac != 0)) {
return(-1);
}
if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
len = val->value.hex.total;
else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
len = val->value.base64.total;
else {
switch (valType) {
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_NORMSTRING:
if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateLengthFacet(). Anyway, this was and
* is not the correct handling.
* TODO: Get rid of this case somehow.
*/
if (valType == XML_SCHEMAS_STRING)
len = xmlUTF8Strlen(value);
else
len = xmlSchemaNormLen(value);
} else if (value != NULL) {
if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
len = xmlSchemaNormLen(value);
else
/*
* Should be OK for "preserve" as well.
*/
len = xmlUTF8Strlen(value);
}
break;
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN:
case XML_SCHEMAS_NAME:
case XML_SCHEMAS_NCNAME:
case XML_SCHEMAS_ID:
/*
* FIXME: What exactly to do with anyURI?
*/
case XML_SCHEMAS_ANYURI:
if (value != NULL)
len = xmlSchemaNormLen(value);
break;
default:
TODO
}
}
*length = (unsigned long) len;
/*
* TODO: Return the whole expected value, i.e. "lo", "mi" and "hi".
*/
if (facet->type == XML_SCHEMA_FACET_LENGTH) {
if (len != facet->val->value.decimal.lo)
return(XML_SCHEMAV_CVC_LENGTH_VALID);
} else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
if (len < facet->val->value.decimal.lo)
return(XML_SCHEMAV_CVC_MINLENGTH_VALID);
} else {
if (len > facet->val->value.decimal.lo)
return(XML_SCHEMAV_CVC_MAXLENGTH_VALID);
}
return (0);
}
/**
* xmlSchemaValidateLengthFacet:
* @type: the built-in type
@ -4579,71 +4686,46 @@ xmlSchemaValidateLengthFacet(xmlSchemaTypePtr type,
xmlSchemaValPtr val,
unsigned long *length)
{
unsigned int len = 0;
return (xmlSchemaValidateLengthFacetInternal(facet,
type->builtInType, value, val, length,
XML_SCHEMA_WHITESPACE_UNKNOWN));
}
if ((length == NULL) || (facet == NULL) || (type == NULL))
return (-1);
*length = 0;
if ((facet->type != XML_SCHEMA_FACET_LENGTH) &&
(facet->type != XML_SCHEMA_FACET_MAXLENGTH) &&
(facet->type != XML_SCHEMA_FACET_MINLENGTH))
return (-1);
if ((facet->val == NULL) ||
((facet->val->type != XML_SCHEMAS_DECIMAL) &&
(facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
(facet->val->value.decimal.frac != 0)) {
return(-1);
}
if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
len = val->value.hex.total;
else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
len = val->value.base64.total;
else {
switch (type->builtInType) {
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_NORMSTRING:
case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN:
case XML_SCHEMAS_NAME:
case XML_SCHEMAS_NCNAME:
case XML_SCHEMAS_ID:
len = xmlSchemaNormLen(value);
break;
case XML_SCHEMAS_STRING:
/*
* FIXME: What exactly to do with anyURI?
*/
case XML_SCHEMAS_ANYURI:
if (value != NULL)
len = xmlUTF8Strlen(value);
break;
default:
TODO
}
}
*length = (unsigned long) len;
if (facet->type == XML_SCHEMA_FACET_LENGTH) {
if (len != facet->val->value.decimal.lo)
return(XML_SCHEMAV_CVC_LENGTH_VALID);
} else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
if (len < facet->val->value.decimal.lo)
return(XML_SCHEMAV_CVC_MINLENGTH_VALID);
} else {
if (len > facet->val->value.decimal.lo)
return(XML_SCHEMAV_CVC_MAXLENGTH_VALID);
}
return (0);
/**
* xmlSchemaValidateLengthFacetWhtsp:
* @facet: the facet to check
* @valType: the built-in type
* @value: the lexical repr. of the value to be validated
* @val: the precomputed value
* @ws: the whitespace type of the value
* @length: the actual length of the value
*
* Checka a value against a "length", "minLength" and "maxLength"
* facet; sets @length to the computed length of @value.
*
* Returns 0 if the value is valid, a positive error code
* otherwise and -1 in case of an internal or API error.
*/
int
xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacetPtr facet,
xmlSchemaValType valType,
const xmlChar *value,
xmlSchemaValPtr val,
unsigned long *length,
xmlSchemaWhitespaceValueType ws)
{
return (xmlSchemaValidateLengthFacetInternal(facet, valType, value, val,
length, ws));
}
/**
* xmlSchemaValidateFacetInternal:
* @base: the base type
* @facet: the facet to check
* @fws: the whitespace type of the facet's value
* @valType: the built-in type of the value
* @value: the lexical repr of the value to validate
* @val: the precomputed value
* @ws: the whitespace type of the value
*
* Check a value against a facet condition
*
@ -4653,9 +4735,9 @@ xmlSchemaValidateLengthFacet(xmlSchemaTypePtr type,
static int
xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
xmlSchemaWhitespaceValueType fws,
xmlSchemaValType valType,
xmlSchemaValPtr val,
xmlSchemaValType valType,
const xmlChar *value,
xmlSchemaValPtr val,
xmlSchemaWhitespaceValueType ws)
{
int ret;
@ -4714,7 +4796,12 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
*/
return(0);
case XML_SCHEMA_FACET_ENUMERATION:
if (fws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateFacet().
* TODO: Get rid of this case.
*/
if ((facet->value != NULL) &&
(xmlStrEqual(facet->value, value)))
return(0);
@ -4732,8 +4819,11 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
case XML_SCHEMA_FACET_MAXLENGTH:
case XML_SCHEMA_FACET_MINLENGTH: {
unsigned int len = 0;
/* TODO: Take the whitespace of the value into account. */
/*
* TODO: length, maxLength and minLength must be of type
* nonNegativeInteger only. Check if decimal is used somehow.
*/
if ((facet->val == NULL) ||
((facet->val->type != XML_SCHEMAS_DECIMAL) &&
(facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
@ -4746,24 +4836,43 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
len = val->value.base64.total;
else {
switch (valType) {
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_NORMSTRING:
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_NORMSTRING:
if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateFacet(). Anyway, this was and
* is not the correct handling.
* TODO: Get rid of this case somehow.
*/
if (valType == XML_SCHEMAS_STRING)
len = xmlUTF8Strlen(value);
else
len = xmlSchemaNormLen(value);
} else if (value != NULL) {
if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
len = xmlSchemaNormLen(value);
else
/*
* Should be OK for "preserve" as well.
*/
len = xmlUTF8Strlen(value);
}
break;
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN:
case XML_SCHEMAS_NAME:
case XML_SCHEMAS_NCNAME:
case XML_SCHEMAS_ID:
len = xmlSchemaNormLen(value);
break;
case XML_SCHEMAS_STRING:
/*
* FIXME: What exactly to do with anyURI?
*/
case XML_SCHEMAS_ANYURI:
if (value != NULL)
len = xmlUTF8Strlen(value);
break;
if (value != NULL)
len = xmlSchemaNormLen(value);
break;
default:
TODO
}
@ -4835,7 +4944,7 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
* number otherwise and -1 in case of internal or API error.
*/
int
xmlSchemaValidateFacet(xmlSchemaTypePtr base,
xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
xmlSchemaFacetPtr facet,
const xmlChar *value,
xmlSchemaValPtr val)
@ -4845,16 +4954,14 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base,
* xmlSchemaValidateFacet() and the new xmlSchemaValidateFacetInternal() and
* xmlSchemaValidateFacetWhtsp().
*/
if (val != NULL) {
if (base != NULL)
return(xmlSchemaValidateFacetInternal(facet,
XML_SCHEMA_WHITESPACE_UNKNOWN, val->type, val, value,
XML_SCHEMA_WHITESPACE_UNKNOWN, base->builtInType, value, val,
XML_SCHEMA_WHITESPACE_UNKNOWN));
} else if (base != NULL) {
else
return(xmlSchemaValidateFacetInternal(facet,
XML_SCHEMA_WHITESPACE_UNKNOWN, base->builtInType, val, value,
XML_SCHEMA_WHITESPACE_UNKNOWN));
}
return(-1);
XML_SCHEMA_WHITESPACE_UNKNOWN, XML_SCHEMAS_UNKNOWN, value, val,
XML_SCHEMA_WHITESPACE_UNKNOWN));
}
/**
@ -4874,30 +4981,30 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base,
* Returns 0 if the element is schemas valid, a positive error code
* number otherwise and -1 in case of internal or API error.
*/
#if 0
int
xmlSchemaValidateFacetWhtsp(xmlSchemaFacetPtr facet,
xmlSchemaWhitespaceValueType fws,
xmlSchemaValType valType,
xmlSchemaValPtr val,
xmlSchemaValType valType,
const xmlChar *value,
xmlSchemaValPtr val,
xmlSchemaWhitespaceValueType ws)
{
return(xmlSchemaValidateFacetInternal(facet, fws, valType,
val, value, ws));
value, val, ws));
}
#endif
/**
* xmlSchemaGetCanonValue:
* @val: the precomputed value
* @retValue: the returned value
*
* Get a the cononical representation of the value.
* Get a the cononical lexical representation of the value.
* The caller has to free the returned retValue.
* WARNING: Some value types are not supported yet, resulting
* in a @retValue of "???".
*
* Returns 0 if the value could be built and -1 in case of
* API errors or if the value type is not supported yet.
* API errors.
*/
int
xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
@ -4906,32 +5013,66 @@ xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
return (-1);
*retValue = NULL;
switch (val->type) {
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_STRING:
if (val->value.str == NULL)
*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
else
*retValue =
BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
break;
case XML_SCHEMAS_NORMSTRING:
/*
if (val->value.str == NULL)
*retValue = BAD_CAST xmlStrdup(BAD_CAST "");
else {
*retValue = xmlSchemaWhiteSpaceReplace(
(const xmlChar *) val->value.str);
if ((*retValue) == NULL)
*retValue = BAD_CAST xmlStrdup(
(const xmlChar *) val->value.str);
}
break;
case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN:
case XML_SCHEMAS_NAME:
case XML_SCHEMAS_QNAME:
case XML_SCHEMAS_NAME:
case XML_SCHEMAS_NCNAME:
case XML_SCHEMAS_ID:
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_ENTITY:
case XML_SCHEMAS_NOTATION:
case XML_SCHEMAS_ANYURI:
*/
case XML_SCHEMAS_ANYURI:
if (val->value.str == NULL)
*retValue = NULL;
else
/* TODO: This is not yet correct for non-normalized values. */
*retValue =
BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
return (0);
return (-1);
*retValue = BAD_CAST xmlSchemaCollapseString(BAD_CAST val->value.str);
break;
case XML_SCHEMAS_QNAME:
/*
* TODO: What exactly to do with QNames?
*/
if (val->value.qname.uri == NULL) {
*retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.qname.name);
return (0);
} else {
*retValue = BAD_CAST xmlStrdup(BAD_CAST "{");
*retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
BAD_CAST val->value.qname.uri);
*retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
BAD_CAST "}");
*retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
BAD_CAST val->value.qname.uri);
}
break;
default:
return (-1);
*retValue = BAD_CAST xmlStrdup(BAD_CAST "???");
break;
}
return (-1);
return (0);
}
xmlSchemaValType
xmlSchemaGetValType(xmlSchemaValPtr val)
{
return (val->type);
}
#endif /* LIBXML_SCHEMAS_ENABLED */