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:
parent
9fcb491cda
commit
478d693fa2
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
437
xmlschemas.c
437
xmlschemas.c
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user