Back to home page

Wine source

 
 

    


File indexing completed on 2024-02-23 23:43:48

9d9d4fcc3 Alex*0001 /*
                0002  * schemas.c : implementation of the XML Schema handling and
                0003  *             schema validity checking
                0004  *
                0005  * See Copyright for the status of this software.
                0006  *
                0007  * Daniel Veillard <veillard@redhat.com>
                0008  */
                0009 
                0010 /*
                0011  * TODO:
                0012  *   - when types are redefined in includes, check that all
                0013  *     types in the redef list are equal
                0014  *     -> need a type equality operation.
                0015  *   - if we don't intend to use the schema for schemas, we
                0016  *     need to validate all schema attributes (ref, type, name)
                0017  *     against their types.
                0018  *   - Eliminate item creation for: ??
                0019  *
                0020  * URGENT TODO:
                0021  *   - For xsi-driven schema acquisition, augment the IDCs after every
                0022  *     acquisition episode (xmlSchemaAugmentIDC).
                0023  *
                0024  * NOTES:
                0025  *   - Eliminated item creation for: <restriction>, <extension>,
                0026  *     <simpleContent>, <complexContent>, <list>, <union>
                0027  *
                0028  * PROBLEMS:
                0029  *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
                0030  *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
                0031  *     XPath will have trouble to resolve to this namespace, since not known.
                0032  *
                0033  *
                0034  * CONSTRAINTS:
                0035  *
                0036  * Schema Component Constraint:
                0037  *   All Group Limited (cos-all-limited)
                0038  *   Status: complete
                0039  *   (1.2)
                0040  *     In xmlSchemaGroupDefReferenceTermFixup() and
                0041  *   (2)
                0042  *     In xmlSchemaParseModelGroup()
                0043  *     TODO: Actually this should go to component-level checks,
                0044  *     but is done here due to performance. Move it to an other layer
                0045  *     is schema construction via an API is implemented.
                0046  */
                0047 
                0048 /* To avoid EBCDIC trouble when parsing on zOS */
                0049 #if defined(__MVS__)
                0050 #pragma convert("ISO8859-1")
                0051 #endif
                0052 
                0053 #define IN_LIBXML
                0054 #include "libxml.h"
                0055 
                0056 #ifdef LIBXML_SCHEMAS_ENABLED
                0057 
                0058 #include <string.h>
                0059 #include <libxml/xmlmemory.h>
                0060 #include <libxml/parser.h>
                0061 #include <libxml/parserInternals.h>
                0062 #include <libxml/hash.h>
                0063 #include <libxml/uri.h>
                0064 #include <libxml/xmlschemas.h>
                0065 #include <libxml/schemasInternals.h>
                0066 #include <libxml/xmlschemastypes.h>
                0067 #include <libxml/xmlautomata.h>
                0068 #include <libxml/xmlregexp.h>
                0069 #include <libxml/dict.h>
                0070 #include <libxml/encoding.h>
                0071 #include <libxml/xmlIO.h>
                0072 #ifdef LIBXML_PATTERN_ENABLED
                0073 #include <libxml/pattern.h>
                0074 #endif
                0075 #ifdef LIBXML_READER_ENABLED
                0076 #include <libxml/xmlreader.h>
                0077 #endif
                0078 
ad7b9726c Alex*0079 #include "private/error.h"
                0080 #include "private/string.h"
                0081 
9d9d4fcc3 Alex*0082 /* #define DEBUG 1 */
                0083 
                0084 /* #define DEBUG_CONTENT 1 */
                0085 
                0086 /* #define DEBUG_TYPE 1 */
                0087 
                0088 /* #define DEBUG_CONTENT_REGEXP 1 */
                0089 
                0090 /* #define DEBUG_AUTOMATA 1 */
                0091 
                0092 /* #define DEBUG_IDC */
                0093 
                0094 /* #define DEBUG_IDC_NODE_TABLE */
                0095 
                0096 /* #define WXS_ELEM_DECL_CONS_ENABLED */
                0097 
                0098 #ifdef DEBUG_IDC
                0099  #ifndef DEBUG_IDC_NODE_TABLE
                0100   #define DEBUG_IDC_NODE_TABLE
                0101  #endif
                0102 #endif
                0103 
                0104 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
                0105 
                0106 #define ENABLE_REDEFINE
                0107 
                0108 /* #define ENABLE_NAMED_LOCALS */
                0109 
                0110 /* #define ENABLE_IDC_NODE_TABLES_TEST */
                0111 
                0112 #define DUMP_CONTENT_MODEL
                0113 
                0114 #ifdef LIBXML_READER_ENABLED
                0115 /* #define XML_SCHEMA_READER_ENABLED */
                0116 #endif
                0117 
                0118 #define UNBOUNDED (1 << 30)
                0119 #define TODO                                \
                0120     xmlGenericError(xmlGenericErrorContext,             \
                0121         "Unimplemented block at %s:%d\n",               \
                0122             __FILE__, __LINE__);
                0123 
                0124 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
                0125 
                0126 /*
                0127  * The XML Schemas namespaces
                0128  */
                0129 static const xmlChar *xmlSchemaNs = (const xmlChar *)
                0130     "http://www.w3.org/2001/XMLSchema";
                0131 
                0132 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
                0133     "http://www.w3.org/2001/XMLSchema-instance";
                0134 
                0135 static const xmlChar *xmlNamespaceNs = (const xmlChar *)
                0136     "http://www.w3.org/2000/xmlns/";
                0137 
                0138 /*
                0139 * Come casting macros.
                0140 */
                0141 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
                0142 #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
                0143 #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
                0144 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
                0145 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
                0146 #define WXS_PTC_CAST (xmlSchemaParticlePtr)
                0147 #define WXS_TYPE_CAST (xmlSchemaTypePtr)
                0148 #define WXS_ELEM_CAST (xmlSchemaElementPtr)
                0149 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
                0150 #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
                0151 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
                0152 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
                0153 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
                0154 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
                0155 #define WXS_IDC_CAST (xmlSchemaIDCPtr)
                0156 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
                0157 #define WXS_LIST_CAST (xmlSchemaItemListPtr)
                0158 
                0159 /*
                0160 * Macros to query common properties of components.
                0161 */
                0162 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
                0163 
                0164 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
                0165 /*
                0166 * Macros for element declarations.
                0167 */
                0168 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
                0169 
                0170 #define WXS_SUBST_HEAD(item) (item)->refDecl
                0171 /*
                0172 * Macros for attribute declarations.
                0173 */
                0174 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
                0175 /*
                0176 * Macros for attribute uses.
                0177 */
                0178 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
                0179 
                0180 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
                0181 
                0182 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
                0183 
                0184 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
                0185 /*
                0186 * Macros for attribute groups.
                0187 */
                0188 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
                0189 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
                0190 /*
                0191 * Macros for particles.
                0192 */
                0193 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
                0194 
                0195 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
                0196 
                0197 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
                0198 
                0199 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
                0200 /*
                0201 * Macros for model groups definitions.
                0202 */
                0203 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
                0204 /*
                0205 * Macros for model groups.
                0206 */
                0207 #define WXS_IS_MODEL_GROUP(i) \
                0208     (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
                0209      ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
                0210      ((i)->type == XML_SCHEMA_TYPE_ALL))
                0211 
                0212 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
                0213 /*
                0214 * Macros for schema buckets.
                0215 */
                0216 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
                0217     ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
                0218 
                0219 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
                0220     ((t) == XML_SCHEMA_SCHEMA_IMPORT))
                0221 
                0222 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
                0223 
                0224 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
                0225 /*
                0226 * Macros for complex/simple types.
                0227 */
                0228 #define WXS_IS_ANYTYPE(i) \
                0229      (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
                0230       ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
                0231 
                0232 #define WXS_IS_COMPLEX(i) \
                0233     (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
                0234      ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
                0235 
                0236 #define WXS_IS_SIMPLE(item) \
                0237     ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
                0238      ((item->type == XML_SCHEMA_TYPE_BASIC) && \
                0239       (item->builtInType != XML_SCHEMAS_ANYTYPE)))
                0240 
                0241 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
                0242     (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
                0243       ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
                0244 
                0245 #define WXS_IS_RESTRICTION(t) \
                0246     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
                0247 
                0248 #define WXS_IS_EXTENSION(t) \
                0249     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
                0250 
                0251 #define WXS_IS_TYPE_NOT_FIXED(i) \
                0252     (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
                0253      (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
                0254 
                0255 #define WXS_IS_TYPE_NOT_FIXED_1(item) \
                0256     (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
                0257      (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
                0258 
                0259 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
                0260 
                0261 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
                0262 /*
                0263 * Macros for exclusively for complex types.
                0264 */
                0265 #define WXS_HAS_COMPLEX_CONTENT(item) \
                0266     ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
                0267      (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
                0268      (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
                0269 
                0270 #define WXS_HAS_SIMPLE_CONTENT(item) \
                0271     ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
                0272      (item->contentType == XML_SCHEMA_CONTENT_BASIC))
                0273 
                0274 #define WXS_HAS_MIXED_CONTENT(item) \
                0275     (item->contentType == XML_SCHEMA_CONTENT_MIXED)
                0276 
                0277 #define WXS_EMPTIABLE(t) \
                0278     (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
                0279 
                0280 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
                0281 
                0282 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
                0283 
                0284 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
                0285 /*
                0286 * Macros for exclusively for simple types.
                0287 */
                0288 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
                0289 
                0290 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
                0291 
                0292 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
                0293 
                0294 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
                0295 /*
                0296 * Misc parser context macros.
                0297 */
                0298 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
                0299 
                0300 #define WXS_HAS_BUCKETS(ctx) \
                0301 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
                0302 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
                0303 
                0304 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
                0305 
                0306 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
                0307 
                0308 #define WXS_SCHEMA(ctx) (ctx)->schema
                0309 
                0310 #define WXS_ADD_LOCAL(ctx, item) \
ad7b9726c Alex*0311     do { \
                0312         if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) < 0) { \
                0313             xmlFree(item); \
                0314             item = NULL; \
                0315         } \
                0316     } while (0)
9d9d4fcc3 Alex*0317 
                0318 #define WXS_ADD_GLOBAL(ctx, item) \
ad7b9726c Alex*0319     do { \
                0320         if (xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) < 0) { \
                0321             xmlFree(item); \
                0322             item = NULL; \
                0323         } \
                0324     } while (0)
9d9d4fcc3 Alex*0325 
                0326 #define WXS_ADD_PENDING(ctx, item) \
                0327     xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
                0328 /*
                0329 * xmlSchemaItemList macros.
                0330 */
                0331 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
                0332 /*
                0333 * Misc macros.
                0334 */
                0335 #define IS_SCHEMA(node, type) \
                0336    ((node != NULL) && (node->ns != NULL) && \
                0337     (xmlStrEqual(node->name, (const xmlChar *) type)) && \
                0338     (xmlStrEqual(node->ns->href, xmlSchemaNs)))
                0339 
                0340 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
                0341 
                0342 /*
                0343 * Since we put the default/fixed values into the dict, we can
                0344 * use pointer comparison for those values.
                0345 * REMOVED: (xmlStrEqual((v1), (v2)))
                0346 */
                0347 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
                0348 
                0349 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
                0350 
                0351 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
                0352 
                0353 #define HFAILURE if (res == -1) goto exit_failure;
                0354 
                0355 #define HERROR if (res != 0) goto exit_error;
                0356 
                0357 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
                0358 /*
                0359 * Some flags used for various schema constraints.
                0360 */
                0361 #define SUBSET_RESTRICTION  1<<0
                0362 #define SUBSET_EXTENSION    1<<1
                0363 #define SUBSET_SUBSTITUTION 1<<2
                0364 #define SUBSET_LIST         1<<3
                0365 #define SUBSET_UNION        1<<4
                0366 
                0367 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
                0368 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
                0369 
                0370 typedef struct _xmlSchemaItemList xmlSchemaItemList;
                0371 typedef xmlSchemaItemList *xmlSchemaItemListPtr;
                0372 struct _xmlSchemaItemList {
                0373     void **items;  /* used for dynamic addition of schemata */
                0374     int nbItems; /* used for dynamic addition of schemata */
                0375     int sizeItems; /* used for dynamic addition of schemata */
                0376 };
                0377 
                0378 #define XML_SCHEMA_CTXT_PARSER 1
                0379 #define XML_SCHEMA_CTXT_VALIDATOR 2
                0380 
                0381 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
                0382 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
                0383 struct _xmlSchemaAbstractCtxt {
                0384     int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
                0385     void *dummy; /* Fix alignment issues */
                0386 };
                0387 
                0388 typedef struct _xmlSchemaBucket xmlSchemaBucket;
                0389 typedef xmlSchemaBucket *xmlSchemaBucketPtr;
                0390 
                0391 #define XML_SCHEMA_SCHEMA_MAIN 0
                0392 #define XML_SCHEMA_SCHEMA_IMPORT 1
                0393 #define XML_SCHEMA_SCHEMA_INCLUDE 2
                0394 #define XML_SCHEMA_SCHEMA_REDEFINE 3
                0395 
                0396 /**
                0397  * xmlSchemaSchemaRelation:
                0398  *
                0399  * Used to create a graph of schema relationships.
                0400  */
                0401 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
                0402 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
                0403 struct _xmlSchemaSchemaRelation {
                0404     xmlSchemaSchemaRelationPtr next;
                0405     int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
                0406     const xmlChar *importNamespace;
                0407     xmlSchemaBucketPtr bucket;
                0408 };
                0409 
                0410 #define XML_SCHEMA_BUCKET_MARKED 1<<0
                0411 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
                0412 
                0413 struct _xmlSchemaBucket {
                0414     int type;
                0415     int flags;
                0416     const xmlChar *schemaLocation;
                0417     const xmlChar *origTargetNamespace;
                0418     const xmlChar *targetNamespace;
                0419     xmlDocPtr doc;
                0420     xmlSchemaSchemaRelationPtr relations;
                0421     int located;
                0422     int parsed;
                0423     int imported;
                0424     int preserveDoc;
                0425     xmlSchemaItemListPtr globals; /* Global components. */
                0426     xmlSchemaItemListPtr locals; /* Local components. */
                0427 };
                0428 
                0429 /**
                0430  * xmlSchemaImport:
                0431  * (extends xmlSchemaBucket)
                0432  *
                0433  * Reflects a schema. Holds some information
                0434  * about the schema and its toplevel components. Duplicate
                0435  * toplevel components are not checked at this level.
                0436  */
                0437 typedef struct _xmlSchemaImport xmlSchemaImport;
                0438 typedef xmlSchemaImport *xmlSchemaImportPtr;
                0439 struct _xmlSchemaImport {
                0440     int type; /* Main OR import OR include. */
                0441     int flags;
                0442     const xmlChar *schemaLocation; /* The URI of the schema document. */
                0443     /* For chameleon includes, @origTargetNamespace will be NULL */
                0444     const xmlChar *origTargetNamespace;
                0445     /*
                0446     * For chameleon includes, @targetNamespace will be the
                0447     * targetNamespace of the including schema.
                0448     */
                0449     const xmlChar *targetNamespace;
                0450     xmlDocPtr doc; /* The schema node-tree. */
                0451     /* @relations will hold any included/imported/redefined schemas. */
                0452     xmlSchemaSchemaRelationPtr relations;
                0453     int located;
                0454     int parsed;
                0455     int imported;
                0456     int preserveDoc;
                0457     xmlSchemaItemListPtr globals;
                0458     xmlSchemaItemListPtr locals;
                0459     /* The imported schema. */
                0460     xmlSchemaPtr schema;
                0461 };
                0462 
                0463 /*
                0464 * (extends xmlSchemaBucket)
                0465 */
                0466 typedef struct _xmlSchemaInclude xmlSchemaInclude;
                0467 typedef xmlSchemaInclude *xmlSchemaIncludePtr;
                0468 struct _xmlSchemaInclude {
                0469     int type;
                0470     int flags;
                0471     const xmlChar *schemaLocation;
                0472     const xmlChar *origTargetNamespace;
                0473     const xmlChar *targetNamespace;
                0474     xmlDocPtr doc;
                0475     xmlSchemaSchemaRelationPtr relations;
                0476     int located;
                0477     int parsed;
                0478     int imported;
                0479     int preserveDoc;
                0480     xmlSchemaItemListPtr globals; /* Global components. */
                0481     xmlSchemaItemListPtr locals; /* Local components. */
                0482 
                0483     /* The owning main or import schema bucket. */
                0484     xmlSchemaImportPtr ownerImport;
                0485 };
                0486 
                0487 /**
                0488  * xmlSchemaBasicItem:
                0489  *
                0490  * The abstract base type for schema components.
                0491  */
                0492 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
                0493 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
                0494 struct _xmlSchemaBasicItem {
                0495     xmlSchemaTypeType type;
                0496     void *dummy; /* Fix alignment issues */
                0497 };
                0498 
                0499 /**
                0500  * xmlSchemaAnnotItem:
                0501  *
                0502  * The abstract base type for annotated schema components.
                0503  * (Extends xmlSchemaBasicItem)
                0504  */
                0505 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
                0506 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
                0507 struct _xmlSchemaAnnotItem {
                0508     xmlSchemaTypeType type;
                0509     xmlSchemaAnnotPtr annot;
                0510 };
                0511 
                0512 /**
                0513  * xmlSchemaTreeItem:
                0514  *
                0515  * The abstract base type for tree-like structured schema components.
                0516  * (Extends xmlSchemaAnnotItem)
                0517  */
                0518 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
                0519 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
                0520 struct _xmlSchemaTreeItem {
                0521     xmlSchemaTypeType type;
                0522     xmlSchemaAnnotPtr annot;
                0523     xmlSchemaTreeItemPtr next;
                0524     xmlSchemaTreeItemPtr children;
                0525 };
                0526 
                0527 
                0528 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
                0529 /**
                0530  * xmlSchemaAttributeUsePtr:
                0531  *
                0532  * The abstract base type for tree-like structured schema components.
                0533  * (Extends xmlSchemaTreeItem)
                0534  */
                0535 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
                0536 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
                0537 struct _xmlSchemaAttributeUse {
                0538     xmlSchemaTypeType type;
                0539     xmlSchemaAnnotPtr annot;
                0540     xmlSchemaAttributeUsePtr next; /* The next attr. use. */
                0541     /*
                0542     * The attr. decl. OR a QName-ref. to an attr. decl. OR
                0543     * a QName-ref. to an attribute group definition.
                0544     */
                0545     xmlSchemaAttributePtr attrDecl;
                0546 
                0547     int flags;
                0548     xmlNodePtr node;
                0549     int occurs; /* required, optional */
                0550     const xmlChar * defValue;
                0551     xmlSchemaValPtr defVal;
                0552 };
                0553 
                0554 /**
                0555  * xmlSchemaAttributeUseProhibPtr:
                0556  *
                0557  * A helper component to reflect attribute prohibitions.
                0558  * (Extends xmlSchemaBasicItem)
                0559  */
                0560 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
                0561 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
                0562 struct _xmlSchemaAttributeUseProhib {
                0563     xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
                0564     xmlNodePtr node;
                0565     const xmlChar *name;
                0566     const xmlChar *targetNamespace;
                0567     int isRef;
                0568 };
                0569 
                0570 /**
                0571  * xmlSchemaRedef:
                0572  */
                0573 typedef struct _xmlSchemaRedef xmlSchemaRedef;
                0574 typedef xmlSchemaRedef *xmlSchemaRedefPtr;
                0575 struct _xmlSchemaRedef {
                0576     xmlSchemaRedefPtr next;
                0577     xmlSchemaBasicItemPtr item; /* The redefining component. */
                0578     xmlSchemaBasicItemPtr reference; /* The referencing component. */
                0579     xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
                0580     const xmlChar *refName; /* The name of the to-be-redefined component. */
                0581     const xmlChar *refTargetNs; /* The target namespace of the
                0582                                    to-be-redefined comp. */
                0583     xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
                0584 };
                0585 
                0586 /**
                0587  * xmlSchemaConstructionCtxt:
                0588  */
                0589 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
                0590 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
                0591 struct _xmlSchemaConstructionCtxt {
                0592     xmlSchemaPtr mainSchema; /* The main schema. */
                0593     xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
                0594     xmlDictPtr dict;
                0595     xmlSchemaItemListPtr buckets; /* List of schema buckets. */
                0596     /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
                0597     xmlSchemaBucketPtr bucket; /* The current schema bucket */
                0598     xmlSchemaItemListPtr pending; /* All Components of all schemas that
                0599                                      need to be fixed. */
                0600     xmlHashTablePtr substGroups;
                0601     xmlSchemaRedefPtr redefs;
                0602     xmlSchemaRedefPtr lastRedef;
                0603 };
                0604 
                0605 #define XML_SCHEMAS_PARSE_ERROR     1
                0606 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
                0607 
                0608 struct _xmlSchemaParserCtxt {
                0609     int type;
                0610     void *errCtxt;             /* user specific error context */
                0611     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
                0612     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
                0613     int err;
                0614     int nberrors;
                0615     xmlStructuredErrorFunc serror;
                0616 
                0617     xmlSchemaConstructionCtxtPtr constructor;
                0618     int ownsConstructor; /* TODO: Move this to parser *flags*. */
                0619 
                0620     /* xmlSchemaPtr topschema;  */
                0621     /* xmlHashTablePtr namespaces;  */
                0622 
                0623     xmlSchemaPtr schema;        /* The main schema in use */
                0624     int counter;
                0625 
                0626     const xmlChar *URL;
                0627     xmlDocPtr doc;
                0628     int preserve;       /* Whether the doc should be freed  */
                0629 
                0630     const char *buffer;
                0631     int size;
                0632 
                0633     /*
                0634      * Used to build complex element content models
                0635      */
                0636     xmlAutomataPtr am;
                0637     xmlAutomataStatePtr start;
                0638     xmlAutomataStatePtr end;
                0639     xmlAutomataStatePtr state;
                0640 
                0641     xmlDictPtr dict;        /* dictionary for interned string names */
                0642     xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
                0643     int options;
                0644     xmlSchemaValidCtxtPtr vctxt;
                0645     int isS4S;
                0646     int isRedefine;
                0647     int xsiAssemble;
                0648     int stop; /* If the parser should stop; i.e. a critical error. */
                0649     const xmlChar *targetNamespace;
                0650     xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
                0651 
                0652     xmlSchemaRedefPtr redef; /* Used for redefinitions. */
                0653     int redefCounter; /* Used for redefinitions. */
                0654     xmlSchemaItemListPtr attrProhibs;
                0655 };
                0656 
                0657 /**
                0658  * xmlSchemaQNameRef:
                0659  *
                0660  * A component reference item (not a schema component)
                0661  * (Extends xmlSchemaBasicItem)
                0662  */
                0663 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
                0664 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
                0665 struct _xmlSchemaQNameRef {
                0666     xmlSchemaTypeType type;
                0667     xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
                0668     xmlSchemaTypeType itemType;
                0669     const xmlChar *name;
                0670     const xmlChar *targetNamespace;
                0671     xmlNodePtr node;
                0672 };
                0673 
                0674 /**
                0675  * xmlSchemaParticle:
                0676  *
                0677  * A particle component.
                0678  * (Extends xmlSchemaTreeItem)
                0679  */
                0680 typedef struct _xmlSchemaParticle xmlSchemaParticle;
                0681 typedef xmlSchemaParticle *xmlSchemaParticlePtr;
                0682 struct _xmlSchemaParticle {
                0683     xmlSchemaTypeType type;
                0684     xmlSchemaAnnotPtr annot;
                0685     xmlSchemaTreeItemPtr next; /* next particle */
                0686     xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
                0687     a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
                0688         etc.) */
                0689     int minOccurs;
                0690     int maxOccurs;
                0691     xmlNodePtr node;
                0692 };
                0693 
                0694 /**
                0695  * xmlSchemaModelGroup:
                0696  *
                0697  * A model group component.
                0698  * (Extends xmlSchemaTreeItem)
                0699  */
                0700 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
                0701 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
                0702 struct _xmlSchemaModelGroup {
                0703     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
                0704     xmlSchemaAnnotPtr annot;
                0705     xmlSchemaTreeItemPtr next; /* not used */
                0706     xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
                0707     xmlNodePtr node;
                0708 };
                0709 
                0710 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
                0711 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
                0712 /**
                0713  * xmlSchemaModelGroupDef:
                0714  *
                0715  * A model group definition component.
                0716  * (Extends xmlSchemaTreeItem)
                0717  */
                0718 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
                0719 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
                0720 struct _xmlSchemaModelGroupDef {
                0721     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
                0722     xmlSchemaAnnotPtr annot;
                0723     xmlSchemaTreeItemPtr next; /* not used */
                0724     xmlSchemaTreeItemPtr children; /* the "model group" */
                0725     const xmlChar *name;
                0726     const xmlChar *targetNamespace;
                0727     xmlNodePtr node;
                0728     int flags;
                0729 };
                0730 
                0731 typedef struct _xmlSchemaIDC xmlSchemaIDC;
                0732 typedef xmlSchemaIDC *xmlSchemaIDCPtr;
                0733 
                0734 /**
                0735  * xmlSchemaIDCSelect:
                0736  *
                0737  * The identity-constraint "field" and "selector" item, holding the
                0738  * XPath expression.
                0739  */
                0740 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
                0741 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
                0742 struct _xmlSchemaIDCSelect {
                0743     xmlSchemaIDCSelectPtr next;
                0744     xmlSchemaIDCPtr idc;
                0745     int index; /* an index position if significant for IDC key-sequences */
                0746     const xmlChar *xpath; /* the XPath expression */
                0747     void *xpathComp; /* the compiled XPath expression */
                0748 };
                0749 
                0750 /**
                0751  * xmlSchemaIDC:
                0752  *
                0753  * The identity-constraint definition component.
                0754  * (Extends xmlSchemaAnnotItem)
                0755  */
                0756 
                0757 struct _xmlSchemaIDC {
                0758     xmlSchemaTypeType type;
                0759     xmlSchemaAnnotPtr annot;
                0760     xmlSchemaIDCPtr next;
                0761     xmlNodePtr node;
                0762     const xmlChar *name;
                0763     const xmlChar *targetNamespace;
                0764     xmlSchemaIDCSelectPtr selector;
                0765     xmlSchemaIDCSelectPtr fields;
                0766     int nbFields;
                0767     xmlSchemaQNameRefPtr ref;
                0768 };
                0769 
                0770 /**
                0771  * xmlSchemaIDCAug:
                0772  *
                0773  * The augmented IDC information used for validation.
                0774  */
                0775 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
                0776 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
                0777 struct _xmlSchemaIDCAug {
                0778     xmlSchemaIDCAugPtr next; /* next in a list */
                0779     xmlSchemaIDCPtr def; /* the IDC definition */
                0780     int keyrefDepth; /* the lowest tree level to which IDC
                0781                         tables need to be bubbled upwards */
                0782 };
                0783 
                0784 /**
                0785  * xmlSchemaPSVIIDCKeySequence:
                0786  *
                0787  * The key sequence of a node table item.
                0788  */
                0789 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
                0790 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
                0791 struct _xmlSchemaPSVIIDCKey {
                0792     xmlSchemaTypePtr type;
                0793     xmlSchemaValPtr val;
                0794 };
                0795 
                0796 /**
                0797  * xmlSchemaPSVIIDCNode:
                0798  *
                0799  * The node table item of a node table.
                0800  */
                0801 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
                0802 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
                0803 struct _xmlSchemaPSVIIDCNode {
                0804     xmlNodePtr node;
                0805     xmlSchemaPSVIIDCKeyPtr *keys;
                0806     int nodeLine;
                0807     int nodeQNameID;
                0808 
                0809 };
                0810 
                0811 /**
                0812  * xmlSchemaPSVIIDCBinding:
                0813  *
                0814  * The identity-constraint binding item of the [identity-constraint table].
                0815  */
                0816 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
                0817 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
                0818 struct _xmlSchemaPSVIIDCBinding {
                0819     xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
                0820     xmlSchemaIDCPtr definition; /* the IDC definition */
                0821     xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
                0822     int nbNodes; /* number of entries in the node table */
                0823     int sizeNodes; /* size of the node table */
                0824     xmlSchemaItemListPtr dupls;
                0825 };
                0826 
                0827 
                0828 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
                0829 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
                0830 
                0831 #define XPATH_STATE_OBJ_MATCHES -2
                0832 #define XPATH_STATE_OBJ_BLOCKED -3
                0833 
                0834 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
                0835 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
                0836 
                0837 /**
                0838  * xmlSchemaIDCStateObj:
                0839  *
                0840  * The state object used to evaluate XPath expressions.
                0841  */
                0842 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
                0843 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
                0844 struct _xmlSchemaIDCStateObj {
                0845     int type;
                0846     xmlSchemaIDCStateObjPtr next; /* next if in a list */
                0847     int depth; /* depth of creation */
                0848     int *history; /* list of (depth, state-id) tuples */
                0849     int nbHistory;
                0850     int sizeHistory;
                0851     xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
                0852                                        matcher */
                0853     xmlSchemaIDCSelectPtr sel;
                0854     void *xpathCtxt;
                0855 };
                0856 
                0857 #define IDC_MATCHER 0
                0858 
                0859 /**
                0860  * xmlSchemaIDCMatcher:
                0861  *
                0862  * Used to evaluate IDC selectors (and fields).
                0863  */
                0864 struct _xmlSchemaIDCMatcher {
                0865     int type;
                0866     int depth; /* the tree depth at creation time */
                0867     xmlSchemaIDCMatcherPtr next; /* next in the list */
                0868     xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
                0869     xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
                0870     int idcType;
                0871     xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
                0872                                          elements */
                0873     int sizeKeySeqs;
                0874     xmlSchemaItemListPtr targets; /* list of target-node
                0875                                      (xmlSchemaPSVIIDCNodePtr) entries */
                0876     xmlHashTablePtr htab;
                0877 };
                0878 
                0879 /*
                0880 * Element info flags.
                0881 */
                0882 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
                0883 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
                0884 #define XML_SCHEMA_ELEM_INFO_NILLED        1<<2
                0885 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE        1<<3
                0886 
                0887 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
                0888 #define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
                0889 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
                0890 
                0891 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
                0892 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
                0893 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
                0894 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
                0895 
                0896 /**
                0897  * xmlSchemaNodeInfo:
                0898  *
                0899  * Holds information of an element node.
                0900  */
                0901 struct _xmlSchemaNodeInfo {
                0902     int nodeType;
                0903     xmlNodePtr node;
                0904     int nodeLine;
                0905     const xmlChar *localName;
                0906     const xmlChar *nsName;
                0907     const xmlChar *value;
                0908     xmlSchemaValPtr val; /* the pre-computed value if any */
                0909     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
                0910 
                0911     int flags; /* combination of node info flags */
                0912 
                0913     int valNeeded;
                0914     int normVal;
                0915 
                0916     xmlSchemaElementPtr decl; /* the element/attribute declaration */
                0917     int depth;
                0918     xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
                0919                                             for the scope element*/
                0920     xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
                0921                                            element */
                0922     xmlRegExecCtxtPtr regexCtxt;
                0923 
                0924     const xmlChar **nsBindings; /* Namespace bindings on this element */
                0925     int nbNsBindings;
                0926     int sizeNsBindings;
                0927 
                0928     int hasKeyrefs;
                0929     int appliedXPath; /* Indicates that an XPath has been applied. */
                0930 };
                0931 
                0932 #define XML_SCHEMAS_ATTR_UNKNOWN 1
                0933 #define XML_SCHEMAS_ATTR_ASSESSED 2
                0934 #define XML_SCHEMAS_ATTR_PROHIBITED 3
                0935 #define XML_SCHEMAS_ATTR_ERR_MISSING 4
                0936 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
                0937 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
                0938 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
                0939 #define XML_SCHEMAS_ATTR_DEFAULT 8
                0940 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
                0941 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
                0942 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
                0943 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
                0944 #define XML_SCHEMAS_ATTR_WILD_SKIP 13
                0945 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
                0946 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
                0947 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
                0948 #define XML_SCHEMAS_ATTR_META 17
                0949 /*
                0950 * @metaType values of xmlSchemaAttrInfo.
                0951 */
                0952 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
                0953 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
                0954 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
                0955 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
                0956 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
                0957 
                0958 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
                0959 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
                0960 struct _xmlSchemaAttrInfo {
                0961     int nodeType;
                0962     xmlNodePtr node;
                0963     int nodeLine;
                0964     const xmlChar *localName;
                0965     const xmlChar *nsName;
                0966     const xmlChar *value;
                0967     xmlSchemaValPtr val; /* the pre-computed value if any */
                0968     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
                0969     int flags; /* combination of node info flags */
                0970 
                0971     xmlSchemaAttributePtr decl; /* the attribute declaration */
                0972     xmlSchemaAttributeUsePtr use;  /* the attribute use */
                0973     int state;
                0974     int metaType;
                0975     const xmlChar *vcValue; /* the value constraint value */
                0976     xmlSchemaNodeInfoPtr parent;
                0977 };
                0978 
                0979 
                0980 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
                0981 /**
                0982  * xmlSchemaValidCtxt:
                0983  *
                0984  * A Schemas validation context
                0985  */
                0986 struct _xmlSchemaValidCtxt {
                0987     int type;
                0988     void *errCtxt;             /* user specific data block */
                0989     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
                0990     xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
                0991     xmlStructuredErrorFunc serror;
                0992 
                0993     xmlSchemaPtr schema;        /* The schema in use */
                0994     xmlDocPtr doc;
                0995     xmlParserInputBufferPtr input;
                0996     xmlCharEncoding enc;
                0997     xmlSAXHandlerPtr sax;
                0998     xmlParserCtxtPtr parserCtxt;
                0999     void *user_data; /* TODO: What is this for? */
                1000     char *filename;
                1001 
                1002     int err;
                1003     int nberrors;
                1004 
                1005     xmlNodePtr node;
                1006     xmlNodePtr cur;
                1007     /* xmlSchemaTypePtr type; */
                1008 
                1009     xmlRegExecCtxtPtr regexp;
                1010     xmlSchemaValPtr value;
                1011 
                1012     int valueWS;
                1013     int options;
                1014     xmlNodePtr validationRoot;
                1015     xmlSchemaParserCtxtPtr pctxt;
                1016     int xsiAssemble;
                1017 
                1018     int depth;
                1019     xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
                1020     int sizeElemInfos;
                1021     xmlSchemaNodeInfoPtr inode; /* the current element information */
                1022 
                1023     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
                1024 
                1025     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
                1026     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
                1027     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
                1028 
                1029     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
                1030     int nbIdcNodes;
                1031     int sizeIdcNodes;
                1032 
                1033     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
                1034     int nbIdcKeys;
                1035     int sizeIdcKeys;
                1036 
                1037     int flags;
                1038 
                1039     xmlDictPtr dict;
                1040 
                1041 #ifdef LIBXML_READER_ENABLED
                1042     xmlTextReaderPtr reader;
                1043 #endif
                1044 
                1045     xmlSchemaAttrInfoPtr *attrInfos;
                1046     int nbAttrInfos;
                1047     int sizeAttrInfos;
                1048 
                1049     int skipDepth;
                1050     xmlSchemaItemListPtr nodeQNames;
                1051     int hasKeyrefs;
                1052     int createIDCNodeTables;
                1053     int psviExposeIDCNodeTables;
                1054 
                1055     /* Locator for error reporting in streaming mode */
                1056     xmlSchemaValidityLocatorFunc locFunc;
                1057     void *locCtxt;
                1058 };
                1059 
                1060 /**
                1061  * xmlSchemaSubstGroup:
                1062  *
                1063  *
                1064  */
                1065 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
                1066 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
                1067 struct _xmlSchemaSubstGroup {
                1068     xmlSchemaElementPtr head;
                1069     xmlSchemaItemListPtr members;
                1070 };
                1071 
                1072 /**
                1073  * xmlIDCHashEntry:
                1074  *
                1075  * an entry in hash tables to quickly look up keys/uniques
                1076  */
                1077 typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
                1078 typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
                1079 struct _xmlIDCHashEntry {
                1080     xmlIDCHashEntryPtr next; /* next item with same hash */
                1081     int index;               /* index into associated item list */
                1082 };
                1083 
                1084 /************************************************************************
                1085  *                                  *
                1086  *          Some predeclarations                *
                1087  *                                  *
                1088  ************************************************************************/
                1089 
                1090 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
                1091                                  xmlSchemaPtr schema,
                1092                                  xmlNodePtr node);
                1093 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
                1094                                  xmlSchemaPtr schema,
                1095                                  xmlNodePtr node);
                1096 static int
                1097 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
                1098                    xmlSchemaAbstractCtxtPtr ctxt);
                1099 static const xmlChar *
                1100 xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
                1101 static int
                1102 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                1103                      xmlNodePtr node);
                1104 static int
                1105 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
                1106                        xmlSchemaParserCtxtPtr ctxt);
                1107 static void
                1108 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
                1109 static xmlSchemaWhitespaceValueType
                1110 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
                1111 static xmlSchemaTreeItemPtr
                1112 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                1113              xmlNodePtr node, xmlSchemaTypeType type,
                1114              int withParticle);
                1115 static const xmlChar *
                1116 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
                1117 static xmlSchemaTypeLinkPtr
                1118 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
                1119 static void
                1120 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
                1121              const char *funcName,
                1122              const char *message) LIBXML_ATTR_FORMAT(3,0);
                1123 static int
                1124 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
                1125                  xmlSchemaTypePtr type,
                1126                  xmlSchemaTypePtr baseType,
                1127                  int subset);
                1128 static void
                1129 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
                1130                    xmlSchemaParserCtxtPtr ctxt);
                1131 static void
                1132 xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
                1133 static xmlSchemaQNameRefPtr
                1134 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
                1135                 xmlSchemaPtr schema,
                1136                 xmlNodePtr node);
                1137 
                1138 /************************************************************************
                1139  *                                  *
                1140  *          Helper functions                    *
                1141  *                                  *
                1142  ************************************************************************/
                1143 
                1144 /**
                1145  * xmlSchemaItemTypeToStr:
                1146  * @type: the type of the schema item
                1147  *
                1148  * Returns the component name of a schema item.
                1149  */
                1150 static const xmlChar *
                1151 xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
                1152 {
                1153     switch (type) {
                1154     case XML_SCHEMA_TYPE_BASIC:
                1155         return(BAD_CAST "simple type definition");
                1156     case XML_SCHEMA_TYPE_SIMPLE:
                1157         return(BAD_CAST "simple type definition");
                1158     case XML_SCHEMA_TYPE_COMPLEX:
                1159         return(BAD_CAST "complex type definition");
                1160     case XML_SCHEMA_TYPE_ELEMENT:
                1161         return(BAD_CAST "element declaration");
                1162     case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                1163         return(BAD_CAST "attribute use");
                1164     case XML_SCHEMA_TYPE_ATTRIBUTE:
                1165         return(BAD_CAST "attribute declaration");
                1166     case XML_SCHEMA_TYPE_GROUP:
                1167         return(BAD_CAST "model group definition");
                1168     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                1169         return(BAD_CAST "attribute group definition");
                1170     case XML_SCHEMA_TYPE_NOTATION:
                1171         return(BAD_CAST "notation declaration");
                1172     case XML_SCHEMA_TYPE_SEQUENCE:
                1173         return(BAD_CAST "model group (sequence)");
                1174     case XML_SCHEMA_TYPE_CHOICE:
                1175         return(BAD_CAST "model group (choice)");
                1176     case XML_SCHEMA_TYPE_ALL:
                1177         return(BAD_CAST "model group (all)");
                1178     case XML_SCHEMA_TYPE_PARTICLE:
                1179         return(BAD_CAST "particle");
                1180     case XML_SCHEMA_TYPE_IDC_UNIQUE:
                1181         return(BAD_CAST "unique identity-constraint");
                1182         /* return(BAD_CAST "IDC (unique)"); */
                1183     case XML_SCHEMA_TYPE_IDC_KEY:
                1184         return(BAD_CAST "key identity-constraint");
                1185         /* return(BAD_CAST "IDC (key)"); */
                1186     case XML_SCHEMA_TYPE_IDC_KEYREF:
                1187         return(BAD_CAST "keyref identity-constraint");
                1188         /* return(BAD_CAST "IDC (keyref)"); */
                1189     case XML_SCHEMA_TYPE_ANY:
                1190         return(BAD_CAST "wildcard (any)");
                1191     case XML_SCHEMA_EXTRA_QNAMEREF:
                1192         return(BAD_CAST "[helper component] QName reference");
                1193     case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
                1194         return(BAD_CAST "[helper component] attribute use prohibition");
                1195     default:
                1196         return(BAD_CAST "Not a schema component");
                1197     }
                1198 }
                1199 
                1200 /**
                1201  * xmlSchemaGetComponentTypeStr:
                1202  * @type: the type of the schema item
                1203  *
                1204  * Returns the component name of a schema item.
                1205  */
                1206 static const xmlChar *
                1207 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
                1208 {
                1209     switch (item->type) {
                1210     case XML_SCHEMA_TYPE_BASIC:
                1211         if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
                1212         return(BAD_CAST "complex type definition");
                1213         else
                1214         return(BAD_CAST "simple type definition");
                1215     default:
                1216         return(xmlSchemaItemTypeToStr(item->type));
                1217     }
                1218 }
                1219 
                1220 /**
                1221  * xmlSchemaGetComponentNode:
                1222  * @item: a schema component
                1223  *
                1224  * Returns node associated with the schema component.
                1225  * NOTE that such a node need not be available; plus, a component's
                1226  * node need not to reflect the component directly, since there is no
                1227  * one-to-one relationship between the XML Schema representation and
                1228  * the component representation.
                1229  */
                1230 static xmlNodePtr
                1231 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
                1232 {
                1233     switch (item->type) {
                1234     case XML_SCHEMA_TYPE_ELEMENT:
                1235         return (((xmlSchemaElementPtr) item)->node);
                1236     case XML_SCHEMA_TYPE_ATTRIBUTE:
                1237         return (((xmlSchemaAttributePtr) item)->node);
                1238     case XML_SCHEMA_TYPE_COMPLEX:
                1239     case XML_SCHEMA_TYPE_SIMPLE:
                1240         return (((xmlSchemaTypePtr) item)->node);
                1241     case XML_SCHEMA_TYPE_ANY:
                1242     case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
                1243         return (((xmlSchemaWildcardPtr) item)->node);
                1244     case XML_SCHEMA_TYPE_PARTICLE:
                1245         return (((xmlSchemaParticlePtr) item)->node);
                1246     case XML_SCHEMA_TYPE_SEQUENCE:
                1247     case XML_SCHEMA_TYPE_CHOICE:
                1248     case XML_SCHEMA_TYPE_ALL:
                1249         return (((xmlSchemaModelGroupPtr) item)->node);
                1250     case XML_SCHEMA_TYPE_GROUP:
                1251         return (((xmlSchemaModelGroupDefPtr) item)->node);
                1252     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                1253         return (((xmlSchemaAttributeGroupPtr) item)->node);
                1254     case XML_SCHEMA_TYPE_IDC_UNIQUE:
                1255     case XML_SCHEMA_TYPE_IDC_KEY:
                1256     case XML_SCHEMA_TYPE_IDC_KEYREF:
                1257         return (((xmlSchemaIDCPtr) item)->node);
                1258     case XML_SCHEMA_EXTRA_QNAMEREF:
                1259         return(((xmlSchemaQNameRefPtr) item)->node);
                1260     /* TODO: What to do with NOTATIONs?
                1261     case XML_SCHEMA_TYPE_NOTATION:
                1262         return (((xmlSchemaNotationPtr) item)->node);
                1263     */
                1264     case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                1265         return (((xmlSchemaAttributeUsePtr) item)->node);
                1266     default:
                1267         return (NULL);
                1268     }
                1269 }
                1270 
                1271 #if 0
                1272 /**
                1273  * xmlSchemaGetNextComponent:
                1274  * @item: a schema component
                1275  *
                1276  * Returns the next sibling of the schema component.
                1277  */
                1278 static xmlSchemaBasicItemPtr
                1279 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
                1280 {
                1281     switch (item->type) {
                1282     case XML_SCHEMA_TYPE_ELEMENT:
                1283         return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
                1284     case XML_SCHEMA_TYPE_ATTRIBUTE:
                1285         return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
                1286     case XML_SCHEMA_TYPE_COMPLEX:
                1287     case XML_SCHEMA_TYPE_SIMPLE:
                1288         return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
                1289     case XML_SCHEMA_TYPE_ANY:
                1290     case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
                1291         return (NULL);
                1292     case XML_SCHEMA_TYPE_PARTICLE:
                1293         return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
                1294     case XML_SCHEMA_TYPE_SEQUENCE:
                1295     case XML_SCHEMA_TYPE_CHOICE:
                1296     case XML_SCHEMA_TYPE_ALL:
                1297         return (NULL);
                1298     case XML_SCHEMA_TYPE_GROUP:
                1299         return (NULL);
                1300     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                1301         return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
                1302     case XML_SCHEMA_TYPE_IDC_UNIQUE:
                1303     case XML_SCHEMA_TYPE_IDC_KEY:
                1304     case XML_SCHEMA_TYPE_IDC_KEYREF:
                1305         return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
                1306     default:
                1307         return (NULL);
                1308     }
                1309 }
                1310 #endif
                1311 
                1312 
                1313 /**
                1314  * xmlSchemaFormatQName:
                1315  * @buf: the string buffer
                1316  * @namespaceName:  the namespace name
                1317  * @localName: the local name
                1318  *
                1319  * Returns the given QName in the format "{namespaceName}localName" or
                1320  * just "localName" if @namespaceName is NULL.
                1321  *
                1322  * Returns the localName if @namespaceName is NULL, a formatted
                1323  * string otherwise.
                1324  */
                1325 static const xmlChar*
                1326 xmlSchemaFormatQName(xmlChar **buf,
                1327              const xmlChar *namespaceName,
                1328              const xmlChar *localName)
                1329 {
                1330     FREE_AND_NULL(*buf)
                1331     if (namespaceName != NULL) {
                1332     *buf = xmlStrdup(BAD_CAST "{");
                1333     *buf = xmlStrcat(*buf, namespaceName);
                1334     *buf = xmlStrcat(*buf, BAD_CAST "}");
                1335     }
                1336     if (localName != NULL) {
                1337     if (namespaceName == NULL)
                1338         return(localName);
                1339     *buf = xmlStrcat(*buf, localName);
                1340     } else {
                1341     *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
                1342     }
                1343     return ((const xmlChar *) *buf);
                1344 }
                1345 
                1346 static const xmlChar*
                1347 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
                1348 {
                1349     if (ns != NULL)
                1350     return (xmlSchemaFormatQName(buf, ns->href, localName));
                1351     else
                1352     return (xmlSchemaFormatQName(buf, NULL, localName));
                1353 }
                1354 
                1355 static const xmlChar *
                1356 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
                1357 {
a279c2783 Alex*1358     if (item == NULL) {
                1359         return (NULL);
                1360     }
9d9d4fcc3 Alex*1361     switch (item->type) {
                1362     case XML_SCHEMA_TYPE_ELEMENT:
                1363         return (((xmlSchemaElementPtr) item)->name);
                1364     case XML_SCHEMA_TYPE_ATTRIBUTE:
                1365         return (((xmlSchemaAttributePtr) item)->name);
                1366     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                1367         return (((xmlSchemaAttributeGroupPtr) item)->name);
                1368     case XML_SCHEMA_TYPE_BASIC:
                1369     case XML_SCHEMA_TYPE_SIMPLE:
                1370     case XML_SCHEMA_TYPE_COMPLEX:
                1371         return (((xmlSchemaTypePtr) item)->name);
                1372     case XML_SCHEMA_TYPE_GROUP:
                1373         return (((xmlSchemaModelGroupDefPtr) item)->name);
                1374     case XML_SCHEMA_TYPE_IDC_KEY:
                1375     case XML_SCHEMA_TYPE_IDC_UNIQUE:
                1376     case XML_SCHEMA_TYPE_IDC_KEYREF:
                1377         return (((xmlSchemaIDCPtr) item)->name);
                1378     case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                1379         if (WXS_ATTRUSE_DECL(item) != NULL) {
                1380         return(xmlSchemaGetComponentName(
                1381             WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
                1382         } else
                1383         return(NULL);
                1384     case XML_SCHEMA_EXTRA_QNAMEREF:
                1385         return (((xmlSchemaQNameRefPtr) item)->name);
                1386     case XML_SCHEMA_TYPE_NOTATION:
                1387         return (((xmlSchemaNotationPtr) item)->name);
                1388     default:
                1389         /*
                1390         * Other components cannot have names.
                1391         */
                1392         break;
                1393     }
                1394     return (NULL);
                1395 }
                1396 
                1397 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
                1398 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
                1399 /*
                1400 static const xmlChar *
                1401 xmlSchemaGetQNameRefName(void *ref)
                1402 {
                1403     return(((xmlSchemaQNameRefPtr) ref)->name);
                1404 }
                1405 
                1406 static const xmlChar *
                1407 xmlSchemaGetQNameRefTargetNs(void *ref)
                1408 {
                1409     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
                1410 }
                1411 */
                1412 
                1413 static const xmlChar *
                1414 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
                1415 {
a279c2783 Alex*1416     if (item == NULL) {
                1417         return (NULL);
                1418     }
9d9d4fcc3 Alex*1419     switch (item->type) {
                1420     case XML_SCHEMA_TYPE_ELEMENT:
                1421         return (((xmlSchemaElementPtr) item)->targetNamespace);
                1422     case XML_SCHEMA_TYPE_ATTRIBUTE:
                1423         return (((xmlSchemaAttributePtr) item)->targetNamespace);
                1424     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                1425         return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
                1426     case XML_SCHEMA_TYPE_BASIC:
                1427         return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
                1428     case XML_SCHEMA_TYPE_SIMPLE:
                1429     case XML_SCHEMA_TYPE_COMPLEX:
                1430         return (((xmlSchemaTypePtr) item)->targetNamespace);
                1431     case XML_SCHEMA_TYPE_GROUP:
                1432         return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
                1433     case XML_SCHEMA_TYPE_IDC_KEY:
                1434     case XML_SCHEMA_TYPE_IDC_UNIQUE:
                1435     case XML_SCHEMA_TYPE_IDC_KEYREF:
                1436         return (((xmlSchemaIDCPtr) item)->targetNamespace);
                1437     case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                1438         if (WXS_ATTRUSE_DECL(item) != NULL) {
                1439         return(xmlSchemaGetComponentTargetNs(
                1440             WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
                1441         }
                1442         /* TODO: Will returning NULL break something? */
                1443         break;
                1444     case XML_SCHEMA_EXTRA_QNAMEREF:
                1445         return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
                1446     case XML_SCHEMA_TYPE_NOTATION:
                1447         return (((xmlSchemaNotationPtr) item)->targetNamespace);
                1448     default:
                1449         /*
                1450         * Other components cannot have names.
                1451         */
                1452         break;
                1453     }
                1454     return (NULL);
                1455 }
                1456 
                1457 static const xmlChar*
                1458 xmlSchemaGetComponentQName(xmlChar **buf,
                1459                void *item)
                1460 {
                1461     return (xmlSchemaFormatQName(buf,
                1462     xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
                1463     xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
                1464 }
                1465 
                1466 static const xmlChar*
                1467 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
                1468 {
                1469     xmlChar *str = NULL;
                1470 
                1471     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
                1472     *buf = xmlStrcat(*buf, BAD_CAST " '");
                1473     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
                1474     (xmlSchemaBasicItemPtr) item));
                1475     *buf = xmlStrcat(*buf, BAD_CAST "'");
                1476     FREE_AND_NULL(str);
                1477     return(*buf);
                1478 }
                1479 
                1480 static const xmlChar*
                1481 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
                1482 {
                1483     return(xmlSchemaGetComponentDesignation(buf, idc));
                1484 }
                1485 
                1486 /**
                1487  * xmlSchemaWildcardPCToString:
                1488  * @pc: the type of processContents
                1489  *
                1490  * Returns a string representation of the type of
                1491  * processContents.
                1492  */
                1493 static const xmlChar *
                1494 xmlSchemaWildcardPCToString(int pc)
                1495 {
                1496     switch (pc) {
                1497     case XML_SCHEMAS_ANY_SKIP:
                1498         return (BAD_CAST "skip");
                1499     case XML_SCHEMAS_ANY_LAX:
                1500         return (BAD_CAST "lax");
                1501     case XML_SCHEMAS_ANY_STRICT:
                1502         return (BAD_CAST "strict");
                1503     default:
                1504         return (BAD_CAST "invalid process contents");
                1505     }
                1506 }
                1507 
                1508 /**
                1509  * xmlSchemaGetCanonValueWhtspExt:
                1510  * @val: the precomputed value
                1511  * @retValue: the returned value
                1512  * @ws: the whitespace type of the value
                1513  * @for_hash: non-zero if this is supposed to generate a string for hashing
                1514  *
                1515  * Get a the canonical representation of the value.
                1516  * The caller has to free the returned retValue.
                1517  *
                1518  * Returns 0 if the value could be built and -1 in case of
                1519  *         API errors or if the value type is not supported yet.
                1520  */
                1521 static int
                1522 xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
                1523                      xmlSchemaWhitespaceValueType ws,
                1524                      xmlChar **retValue,
                1525                  int for_hash)
                1526 {
                1527     int list;
                1528     xmlSchemaValType valType;
                1529     const xmlChar *value, *value2 = NULL;
                1530 
                1531 
                1532     if ((retValue == NULL) || (val == NULL))
                1533     return (-1);
                1534     list = xmlSchemaValueGetNext(val) ? 1 : 0;
                1535     *retValue = NULL;
                1536     do {
                1537     value = NULL;
                1538     valType = xmlSchemaGetValType(val);
                1539     switch (valType) {
                1540         case XML_SCHEMAS_STRING:
                1541         case XML_SCHEMAS_NORMSTRING:
                1542         case XML_SCHEMAS_ANYSIMPLETYPE:
                1543         value = xmlSchemaValueGetAsString(val);
                1544         if (value != NULL) {
                1545             if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
                1546             value2 = xmlSchemaCollapseString(value);
                1547             else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
                1548             value2 = xmlSchemaWhiteSpaceReplace(value);
                1549             if (value2 != NULL)
                1550             value = value2;
                1551         }
                1552         break;
                1553         default:
                1554         if (xmlSchemaGetCanonValue(val, &value2) == -1) {
                1555             if (value2 != NULL)
                1556             xmlFree((xmlChar *) value2);
                1557             goto internal_error;
                1558         }
                1559         if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
                1560             /* We can mostly use the canonical value for hashing,
                1561                except in the case of decimal.  There the canonical
                1562                representation requires a trailing '.0' even for
                1563                non-fractional numbers, but for the derived integer
                1564                types it forbids any decimal point.  Nevertheless they
                1565                compare equal if the value is equal.  We need to generate
                1566                the same hash value for this to work, and it's easiest
                1567                to just cut off the useless '.0' suffix for the
                1568                decimal type.  */
                1569             int len = xmlStrlen(value2);
                1570             if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
                1571               ((xmlChar*)value2)[len-2] = 0;
                1572         }
                1573         value = value2;
                1574     }
                1575     if (*retValue == NULL)
                1576         if (value == NULL) {
                1577         if (! list)
                1578             *retValue = xmlStrdup(BAD_CAST "");
                1579         } else
                1580         *retValue = xmlStrdup(value);
                1581     else if (value != NULL) {
                1582         /* List. */
                1583         *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
                1584         *retValue = xmlStrcat((xmlChar *) *retValue, value);
                1585     }
                1586     FREE_AND_NULL(value2)
                1587     val = xmlSchemaValueGetNext(val);
                1588     } while (val != NULL);
                1589 
                1590     return (0);
                1591 internal_error:
                1592     if (*retValue != NULL)
                1593     xmlFree((xmlChar *) (*retValue));
                1594     if (value2 != NULL)
                1595     xmlFree((xmlChar *) value2);
                1596     return (-1);
                1597 }
                1598 
                1599 static int
                1600 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
                1601                    xmlSchemaWhitespaceValueType ws,
                1602                    xmlChar **retValue)
                1603 {
                1604     return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
                1605 }
                1606 
                1607 static int
                1608 xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
                1609                xmlChar **retValue)
                1610 {
                1611     return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
                1612                         retValue, 1);
                1613 }
                1614 
                1615 /**
                1616  * xmlSchemaFormatItemForReport:
                1617  * @buf: the string buffer
                1618  * @itemDes: the designation of the item
                1619  * @itemName: the name of the item
                1620  * @item: the item as an object
                1621  * @itemNode: the node of the item
                1622  * @local: the local name
                1623  * @parsing: if the function is used during the parse
                1624  *
                1625  * Returns a representation of the given item used
                1626  * for error reports.
                1627  *
                1628  * The following order is used to build the resulting
                1629  * designation if the arguments are not NULL:
                1630  * 1a. If itemDes not NULL -> itemDes
                1631  * 1b. If (itemDes not NULL) and (itemName not NULL)
                1632  *     -> itemDes + itemName
                1633  * 2. If the preceding was NULL and (item not NULL) -> item
                1634  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
                1635  *
                1636  * If the itemNode is an attribute node, the name of the attribute
                1637  * will be appended to the result.
                1638  *
                1639  * Returns the formatted string and sets @buf to the resulting value.
                1640  */
                1641 static xmlChar*
                1642 xmlSchemaFormatItemForReport(xmlChar **buf,
                1643              const xmlChar *itemDes,
                1644              xmlSchemaBasicItemPtr item,
                1645              xmlNodePtr itemNode)
                1646 {
                1647     xmlChar *str = NULL;
                1648     int named = 1;
                1649 
                1650     if (*buf != NULL) {
                1651     xmlFree(*buf);
                1652     *buf = NULL;
                1653     }
                1654 
                1655     if (itemDes != NULL) {
                1656     *buf = xmlStrdup(itemDes);
                1657     } else if (item != NULL) {
                1658     switch (item->type) {
                1659     case XML_SCHEMA_TYPE_BASIC: {
                1660         xmlSchemaTypePtr type = WXS_TYPE_CAST item;
                1661 
                1662         if (WXS_IS_ATOMIC(type))
                1663         *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
                1664         else if (WXS_IS_LIST(type))
                1665         *buf = xmlStrdup(BAD_CAST "list type 'xs:");
                1666         else if (WXS_IS_UNION(type))
                1667         *buf = xmlStrdup(BAD_CAST "union type 'xs:");
                1668         else
                1669         *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
                1670         *buf = xmlStrcat(*buf, type->name);
                1671         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1672         }
                1673         break;
                1674     case XML_SCHEMA_TYPE_SIMPLE: {
                1675         xmlSchemaTypePtr type = WXS_TYPE_CAST item;
                1676 
                1677         if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
                1678         *buf = xmlStrdup(BAD_CAST"");
                1679         } else {
                1680         *buf = xmlStrdup(BAD_CAST "local ");
                1681         }
                1682         if (WXS_IS_ATOMIC(type))
                1683         *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
                1684         else if (WXS_IS_LIST(type))
                1685         *buf = xmlStrcat(*buf, BAD_CAST "list type");
                1686         else if (WXS_IS_UNION(type))
                1687         *buf = xmlStrcat(*buf, BAD_CAST "union type");
                1688         else
                1689         *buf = xmlStrcat(*buf, BAD_CAST "simple type");
                1690         if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
                1691         *buf = xmlStrcat(*buf, BAD_CAST " '");
                1692         *buf = xmlStrcat(*buf, type->name);
                1693         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1694         }
                1695         }
                1696         break;
                1697     case XML_SCHEMA_TYPE_COMPLEX: {
                1698         xmlSchemaTypePtr type = WXS_TYPE_CAST item;
                1699 
                1700         if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
                1701         *buf = xmlStrdup(BAD_CAST "");
                1702         else
                1703         *buf = xmlStrdup(BAD_CAST "local ");
                1704         *buf = xmlStrcat(*buf, BAD_CAST "complex type");
                1705         if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
                1706         *buf = xmlStrcat(*buf, BAD_CAST " '");
                1707         *buf = xmlStrcat(*buf, type->name);
                1708         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1709         }
                1710         }
                1711         break;
                1712     case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
                1713         xmlSchemaAttributeUsePtr ause;
                1714 
                1715         ause = WXS_ATTR_USE_CAST item;
                1716         *buf = xmlStrdup(BAD_CAST "attribute use ");
                1717         if (WXS_ATTRUSE_DECL(ause) != NULL) {
                1718             *buf = xmlStrcat(*buf, BAD_CAST "'");
                1719             *buf = xmlStrcat(*buf,
                1720             xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
                1721             FREE_AND_NULL(str)
                1722             *buf = xmlStrcat(*buf, BAD_CAST "'");
                1723         } else {
                1724             *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
                1725         }
                1726         }
                1727         break;
                1728     case XML_SCHEMA_TYPE_ATTRIBUTE: {
                1729         xmlSchemaAttributePtr attr;
                1730 
                1731         attr = (xmlSchemaAttributePtr) item;
                1732         *buf = xmlStrdup(BAD_CAST "attribute decl.");
                1733         *buf = xmlStrcat(*buf, BAD_CAST " '");
                1734         *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
                1735             attr->targetNamespace, attr->name));
                1736         FREE_AND_NULL(str)
                1737             *buf = xmlStrcat(*buf, BAD_CAST "'");
                1738         }
                1739         break;
                1740     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                1741         xmlSchemaGetComponentDesignation(buf, item);
                1742         break;
                1743     case XML_SCHEMA_TYPE_ELEMENT: {
                1744         xmlSchemaElementPtr elem;
                1745 
                1746         elem = (xmlSchemaElementPtr) item;
                1747         *buf = xmlStrdup(BAD_CAST "element decl.");
                1748         *buf = xmlStrcat(*buf, BAD_CAST " '");
                1749         *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
                1750             elem->targetNamespace, elem->name));
                1751         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1752         }
                1753         break;
                1754     case XML_SCHEMA_TYPE_IDC_UNIQUE:
                1755     case XML_SCHEMA_TYPE_IDC_KEY:
                1756     case XML_SCHEMA_TYPE_IDC_KEYREF:
                1757         if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
                1758         *buf = xmlStrdup(BAD_CAST "unique '");
                1759         else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
                1760         *buf = xmlStrdup(BAD_CAST "key '");
                1761         else
                1762         *buf = xmlStrdup(BAD_CAST "keyRef '");
                1763         *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
                1764         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1765         break;
                1766     case XML_SCHEMA_TYPE_ANY:
                1767     case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
                1768         *buf = xmlStrdup(xmlSchemaWildcardPCToString(
                1769             ((xmlSchemaWildcardPtr) item)->processContents));
                1770         *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
                1771         break;
                1772     case XML_SCHEMA_FACET_MININCLUSIVE:
                1773     case XML_SCHEMA_FACET_MINEXCLUSIVE:
                1774     case XML_SCHEMA_FACET_MAXINCLUSIVE:
                1775     case XML_SCHEMA_FACET_MAXEXCLUSIVE:
                1776     case XML_SCHEMA_FACET_TOTALDIGITS:
                1777     case XML_SCHEMA_FACET_FRACTIONDIGITS:
                1778     case XML_SCHEMA_FACET_PATTERN:
                1779     case XML_SCHEMA_FACET_ENUMERATION:
                1780     case XML_SCHEMA_FACET_WHITESPACE:
                1781     case XML_SCHEMA_FACET_LENGTH:
                1782     case XML_SCHEMA_FACET_MAXLENGTH:
                1783     case XML_SCHEMA_FACET_MINLENGTH:
                1784         *buf = xmlStrdup(BAD_CAST "facet '");
                1785         *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
                1786         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1787         break;
                1788     case XML_SCHEMA_TYPE_GROUP: {
                1789         *buf = xmlStrdup(BAD_CAST "model group def.");
                1790         *buf = xmlStrcat(*buf, BAD_CAST " '");
                1791         *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
                1792         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1793         FREE_AND_NULL(str)
                1794         }
                1795         break;
                1796     case XML_SCHEMA_TYPE_SEQUENCE:
                1797     case XML_SCHEMA_TYPE_CHOICE:
                1798     case XML_SCHEMA_TYPE_ALL:
                1799     case XML_SCHEMA_TYPE_PARTICLE:
                1800         *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
                1801         break;
                1802     case XML_SCHEMA_TYPE_NOTATION: {
                1803         *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
                1804         *buf = xmlStrcat(*buf, BAD_CAST " '");
                1805         *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
                1806         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1807         FREE_AND_NULL(str);
                1808         }
                1809             /* Falls through. */
                1810     default:
                1811         named = 0;
                1812     }
                1813     } else
                1814     named = 0;
                1815 
                1816     if ((named == 0) && (itemNode != NULL)) {
                1817     xmlNodePtr elem;
                1818 
                1819     if (itemNode->type == XML_ATTRIBUTE_NODE)
                1820         elem = itemNode->parent;
                1821     else
                1822         elem = itemNode;
                1823     *buf = xmlStrdup(BAD_CAST "Element '");
                1824     if (elem->ns != NULL) {
                1825         *buf = xmlStrcat(*buf,
                1826         xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
                1827         FREE_AND_NULL(str)
                1828     } else
                1829         *buf = xmlStrcat(*buf, elem->name);
                1830     *buf = xmlStrcat(*buf, BAD_CAST "'");
                1831 
                1832     }
                1833     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
                1834     *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
                1835     if (itemNode->ns != NULL) {
                1836         *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
                1837         itemNode->ns->href, itemNode->name));
                1838         FREE_AND_NULL(str)
                1839     } else
                1840         *buf = xmlStrcat(*buf, itemNode->name);
                1841     *buf = xmlStrcat(*buf, BAD_CAST "'");
                1842     }
                1843     FREE_AND_NULL(str)
                1844 
                1845     return (xmlEscapeFormatString(buf));
                1846 }
                1847 
                1848 /**
                1849  * xmlSchemaFormatFacetEnumSet:
                1850  * @buf: the string buffer
                1851  * @type: the type holding the enumeration facets
                1852  *
                1853  * Builds a string consisting of all enumeration elements.
                1854  *
                1855  * Returns a string of all enumeration elements.
                1856  */
                1857 static const xmlChar *
                1858 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
                1859                 xmlChar **buf, xmlSchemaTypePtr type)
                1860 {
                1861     xmlSchemaFacetPtr facet;
                1862     xmlSchemaWhitespaceValueType ws;
                1863     xmlChar *value = NULL;
                1864     int res, found = 0;
                1865 
                1866     if (*buf != NULL)
                1867     xmlFree(*buf);
                1868     *buf = NULL;
                1869 
                1870     do {
                1871     /*
                1872     * Use the whitespace type of the base type.
                1873     */
                1874     ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
                1875     for (facet = type->facets; facet != NULL; facet = facet->next) {
                1876         if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
                1877         continue;
                1878         found = 1;
                1879         res = xmlSchemaGetCanonValueWhtspExt(facet->val,
                1880         ws, &value);
                1881         if (res == -1) {
                1882         xmlSchemaInternalErr(actxt,
                1883             "xmlSchemaFormatFacetEnumSet",
                1884             "compute the canonical lexical representation");
                1885         if (*buf != NULL)
                1886             xmlFree(*buf);
                1887         *buf = NULL;
                1888         return (NULL);
                1889         }
                1890         if (*buf == NULL)
                1891         *buf = xmlStrdup(BAD_CAST "'");
                1892         else
                1893         *buf = xmlStrcat(*buf, BAD_CAST ", '");
                1894         *buf = xmlStrcat(*buf, BAD_CAST value);
                1895         *buf = xmlStrcat(*buf, BAD_CAST "'");
                1896         if (value != NULL) {
                1897         xmlFree((xmlChar *)value);
                1898         value = NULL;
                1899         }
                1900     }
                1901     /*
                1902     * The enumeration facet of a type restricts the enumeration
                1903     * facet of the ancestor type; i.e., such restricted enumerations
                1904     * do not belong to the set of the given type. Thus we break
                1905     * on the first found enumeration.
                1906     */
                1907     if (found)
                1908         break;
                1909     type = type->baseType;
                1910     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
                1911 
                1912     return ((const xmlChar *) *buf);
                1913 }
                1914 
                1915 /************************************************************************
                1916  *                                  *
                1917  *          Error functions                     *
                1918  *                                  *
                1919  ************************************************************************/
                1920 
                1921 #if 0
                1922 static void
                1923 xmlSchemaErrMemory(const char *msg)
                1924 {
                1925     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
                1926                      msg);
                1927 }
                1928 #endif
                1929 
                1930 static void
                1931 xmlSchemaPSimpleErr(const char *msg)
                1932 {
                1933     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
                1934                      msg);
                1935 }
                1936 
                1937 /**
                1938  * xmlSchemaPErrMemory:
                1939  * @node: a context node
                1940  * @extra:  extra information
                1941  *
                1942  * Handle an out of memory condition
                1943  */
                1944 static void
                1945 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
                1946                     const char *extra, xmlNodePtr node)
                1947 {
                1948     if (ctxt != NULL)
                1949         ctxt->nberrors++;
                1950     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
                1951                      extra);
                1952 }
                1953 
                1954 /**
                1955  * xmlSchemaPErr:
                1956  * @ctxt: the parsing context
                1957  * @node: the context node
                1958  * @error: the error code
                1959  * @msg: the error message
                1960  * @str1: extra data
                1961  * @str2: extra data
                1962  *
                1963  * Handle a parser error
                1964  */
                1965 static void LIBXML_ATTR_FORMAT(4,0)
                1966 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
                1967               const char *msg, const xmlChar * str1, const xmlChar * str2)
                1968 {
                1969     xmlGenericErrorFunc channel = NULL;
                1970     xmlStructuredErrorFunc schannel = NULL;
                1971     void *data = NULL;
                1972 
                1973     if (ctxt != NULL) {
                1974         ctxt->nberrors++;
                1975     ctxt->err = error;
                1976         channel = ctxt->error;
                1977         data = ctxt->errCtxt;
                1978     schannel = ctxt->serror;
                1979     }
                1980     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
                1981                     error, XML_ERR_ERROR, NULL, 0,
                1982                     (const char *) str1, (const char *) str2, NULL, 0, 0,
                1983                     msg, str1, str2);
                1984 }
                1985 
                1986 /**
                1987  * xmlSchemaPErr2:
                1988  * @ctxt: the parsing context
                1989  * @node: the context node
                1990  * @node: the current child
                1991  * @error: the error code
                1992  * @msg: the error message
                1993  * @str1: extra data
                1994  * @str2: extra data
                1995  *
                1996  * Handle a parser error
                1997  */
                1998 static void LIBXML_ATTR_FORMAT(5,0)
                1999 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                2000                xmlNodePtr child, int error,
                2001                const char *msg, const xmlChar * str1, const xmlChar * str2)
                2002 {
                2003     if (child != NULL)
                2004         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
                2005     else
                2006         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
                2007 }
                2008 
                2009 
                2010 /**
                2011  * xmlSchemaPErrExt:
                2012  * @ctxt: the parsing context
                2013  * @node: the context node
                2014  * @error: the error code
                2015  * @strData1: extra data
                2016  * @strData2: extra data
                2017  * @strData3: extra data
                2018  * @msg: the message
                2019  * @str1:  extra parameter for the message display
                2020  * @str2:  extra parameter for the message display
                2021  * @str3:  extra parameter for the message display
                2022  * @str4:  extra parameter for the message display
                2023  * @str5:  extra parameter for the message display
                2024  *
                2025  * Handle a parser error
                2026  */
                2027 static void LIBXML_ATTR_FORMAT(7,0)
                2028 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
                2029         const xmlChar * strData1, const xmlChar * strData2,
                2030         const xmlChar * strData3, const char *msg, const xmlChar * str1,
                2031         const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
                2032         const xmlChar * str5)
                2033 {
                2034 
                2035     xmlGenericErrorFunc channel = NULL;
                2036     xmlStructuredErrorFunc schannel = NULL;
                2037     void *data = NULL;
                2038 
                2039     if (ctxt != NULL) {
                2040         ctxt->nberrors++;
                2041     ctxt->err = error;
                2042         channel = ctxt->error;
                2043         data = ctxt->errCtxt;
                2044     schannel = ctxt->serror;
                2045     }
                2046     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
                2047                     error, XML_ERR_ERROR, NULL, 0,
                2048                     (const char *) strData1, (const char *) strData2,
                2049             (const char *) strData3, 0, 0, msg, str1, str2,
                2050             str3, str4, str5);
                2051 }
                2052 
                2053 /************************************************************************
                2054  *                                  *
                2055  *          Allround error functions            *
                2056  *                                  *
                2057  ************************************************************************/
                2058 
                2059 /**
                2060  * xmlSchemaVTypeErrMemory:
                2061  * @node: a context node
                2062  * @extra:  extra information
                2063  *
                2064  * Handle an out of memory condition
                2065  */
                2066 static void
                2067 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
                2068                     const char *extra, xmlNodePtr node)
                2069 {
                2070     if (ctxt != NULL) {
                2071         ctxt->nberrors++;
                2072         ctxt->err = XML_SCHEMAV_INTERNAL;
                2073     }
                2074     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
                2075                      extra);
                2076 }
                2077 
                2078 static void LIBXML_ATTR_FORMAT(2,0)
                2079 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
                2080                 const char *msg, const xmlChar *str)
                2081 {
                2082      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
                2083      msg, (const char *) str);
                2084 }
                2085 
                2086 #define WXS_ERROR_TYPE_ERROR 1
                2087 #define WXS_ERROR_TYPE_WARNING 2
                2088 /**
                2089  * xmlSchemaErr4Line:
                2090  * @ctxt: the validation context
                2091  * @errorLevel: the error level
                2092  * @error: the error code
                2093  * @node: the context node
                2094  * @line: the line number
                2095  * @msg: the error message
                2096  * @str1: extra data
                2097  * @str2: extra data
                2098  * @str3: extra data
                2099  * @str4: extra data
                2100  *
                2101  * Handle a validation error
                2102  */
                2103 static void LIBXML_ATTR_FORMAT(6,0)
                2104 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
                2105           xmlErrorLevel errorLevel,
                2106           int error, xmlNodePtr node, int line, const char *msg,
                2107           const xmlChar *str1, const xmlChar *str2,
                2108           const xmlChar *str3, const xmlChar *str4)
                2109 {
                2110     xmlStructuredErrorFunc schannel = NULL;
                2111     xmlGenericErrorFunc channel = NULL;
                2112     void *data = NULL;
                2113 
                2114     if (ctxt != NULL) {
                2115     if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
                2116         xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
                2117         const char *file = NULL;
                2118         int col = 0;
                2119         if (errorLevel != XML_ERR_WARNING) {
                2120         vctxt->nberrors++;
                2121         vctxt->err = error;
                2122         channel = vctxt->error;
                2123         } else {
                2124         channel = vctxt->warning;
                2125         }
                2126         schannel = vctxt->serror;
                2127         data = vctxt->errCtxt;
                2128 
                2129         /*
                2130         * Error node. If we specify a line number, then
                2131         * do not channel any node to the error function.
                2132         */
                2133         if (line == 0) {
                2134         if ((node == NULL) &&
                2135             (vctxt->depth >= 0) &&
                2136             (vctxt->inode != NULL)) {
                2137             node = vctxt->inode->node;
                2138         }
                2139         /*
                2140         * Get filename and line if no node-tree.
                2141         */
                2142         if ((node == NULL) &&
                2143             (vctxt->parserCtxt != NULL) &&
                2144             (vctxt->parserCtxt->input != NULL)) {
                2145             file = vctxt->parserCtxt->input->filename;
                2146             line = vctxt->parserCtxt->input->line;
                2147             col = vctxt->parserCtxt->input->col;
                2148         }
                2149         } else {
                2150         /*
                2151         * Override the given node's (if any) position
                2152         * and channel only the given line number.
                2153         */
                2154         node = NULL;
                2155         /*
                2156         * Get filename.
                2157         */
                2158         if (vctxt->doc != NULL)
                2159             file = (const char *) vctxt->doc->URL;
                2160         else if ((vctxt->parserCtxt != NULL) &&
                2161             (vctxt->parserCtxt->input != NULL))
                2162             file = vctxt->parserCtxt->input->filename;
                2163         }
                2164         if (vctxt->locFunc != NULL) {
                2165             if ((file == NULL) || (line == 0)) {
                2166             unsigned long l;
                2167             const char *f;
                2168             vctxt->locFunc(vctxt->locCtxt, &f, &l);
                2169             if (file == NULL)
                2170                 file = f;
                2171             if (line == 0)
                2172                 line = (int) l;
                2173         }
                2174         }
                2175         if ((file == NULL) && (vctxt->filename != NULL))
                2176             file = vctxt->filename;
                2177 
                2178         __xmlRaiseError(schannel, channel, data, ctxt,
                2179         node, XML_FROM_SCHEMASV,
                2180         error, errorLevel, file, line,
                2181         (const char *) str1, (const char *) str2,
                2182         (const char *) str3, 0, col, msg, str1, str2, str3, str4);
                2183 
                2184     } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
                2185         xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
                2186         if (errorLevel != XML_ERR_WARNING) {
                2187         pctxt->nberrors++;
                2188         pctxt->err = error;
                2189         channel = pctxt->error;
                2190         } else {
                2191         channel = pctxt->warning;
                2192         }
                2193         schannel = pctxt->serror;
                2194         data = pctxt->errCtxt;
                2195         __xmlRaiseError(schannel, channel, data, ctxt,
                2196         node, XML_FROM_SCHEMASP, error,
                2197         errorLevel, NULL, 0,
                2198         (const char *) str1, (const char *) str2,
                2199         (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
                2200     } else {
                2201         TODO
                2202     }
                2203     }
                2204 }
                2205 
                2206 /**
                2207  * xmlSchemaErr3:
                2208  * @ctxt: the validation context
                2209  * @node: the context node
                2210  * @error: the error code
                2211  * @msg: the error message
                2212  * @str1: extra data
                2213  * @str2: extra data
                2214  * @str3: extra data
                2215  *
                2216  * Handle a validation error
                2217  */
                2218 static void LIBXML_ATTR_FORMAT(4,0)
                2219 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
                2220           int error, xmlNodePtr node, const char *msg,
                2221           const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
                2222 {
                2223     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
                2224     msg, str1, str2, str3, NULL);
                2225 }
                2226 
                2227 static void LIBXML_ATTR_FORMAT(4,0)
                2228 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
                2229           int error, xmlNodePtr node, const char *msg,
                2230           const xmlChar *str1, const xmlChar *str2,
                2231           const xmlChar *str3, const xmlChar *str4)
                2232 {
                2233     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
                2234     msg, str1, str2, str3, str4);
                2235 }
                2236 
                2237 static void LIBXML_ATTR_FORMAT(4,0)
                2238 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
                2239          int error, xmlNodePtr node, const char *msg,
                2240          const xmlChar *str1, const xmlChar *str2)
                2241 {
                2242     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
                2243 }
                2244 
                2245 static xmlChar *
                2246 xmlSchemaFormatNodeForError(xmlChar ** msg,
                2247                 xmlSchemaAbstractCtxtPtr actxt,
                2248                 xmlNodePtr node)
                2249 {
                2250     xmlChar *str = NULL;
                2251 
                2252     *msg = NULL;
                2253     if ((node != NULL) &&
                2254     (node->type != XML_ELEMENT_NODE) &&
                2255     (node->type != XML_ATTRIBUTE_NODE))
                2256     {
                2257     /*
                2258     * Don't try to format other nodes than element and
                2259     * attribute nodes.
                2260     * Play safe and return an empty string.
                2261     */
                2262     *msg = xmlStrdup(BAD_CAST "");
                2263     return(*msg);
                2264     }
                2265     if (node != NULL) {
                2266     /*
                2267     * Work on tree nodes.
                2268     */
                2269     if (node->type == XML_ATTRIBUTE_NODE) {
                2270         xmlNodePtr elem = node->parent;
                2271 
                2272         *msg = xmlStrdup(BAD_CAST "Element '");
                2273         if (elem->ns != NULL)
                2274         *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
                2275             elem->ns->href, elem->name));
                2276         else
                2277         *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
                2278             NULL, elem->name));
                2279         FREE_AND_NULL(str);
                2280         *msg = xmlStrcat(*msg, BAD_CAST "', ");
                2281         *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
                2282     } else {
                2283         *msg = xmlStrdup(BAD_CAST "Element '");
                2284     }
                2285     if (node->ns != NULL)
                2286         *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
                2287         node->ns->href, node->name));
                2288     else
                2289         *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
                2290         NULL, node->name));
                2291     FREE_AND_NULL(str);
                2292     *msg = xmlStrcat(*msg, BAD_CAST "': ");
                2293     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
                2294     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
                2295     /*
                2296     * Work on node infos.
                2297     */
                2298     if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
                2299         xmlSchemaNodeInfoPtr ielem =
                2300         vctxt->elemInfos[vctxt->depth];
                2301 
                2302         *msg = xmlStrdup(BAD_CAST "Element '");
                2303         *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
                2304         ielem->nsName, ielem->localName));
                2305         FREE_AND_NULL(str);
                2306         *msg = xmlStrcat(*msg, BAD_CAST "', ");
                2307         *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
                2308     } else {
                2309         *msg = xmlStrdup(BAD_CAST "Element '");
                2310     }
                2311     *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
                2312         vctxt->inode->nsName, vctxt->inode->localName));
                2313     FREE_AND_NULL(str);
                2314     *msg = xmlStrcat(*msg, BAD_CAST "': ");
                2315     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
                2316     /*
                2317     * Hmm, no node while parsing?
                2318     * Return an empty string, in case NULL will break something.
                2319     */
                2320     *msg = xmlStrdup(BAD_CAST "");
                2321     } else {
                2322     TODO
                2323     return (NULL);
                2324     }
                2325 
                2326     /*
                2327      * xmlSchemaFormatItemForReport() also returns an escaped format
                2328      * string, so do this before calling it below (in the future).
                2329      */
                2330     xmlEscapeFormatString(msg);
                2331 
                2332     /*
                2333     * VAL TODO: The output of the given schema component is currently
                2334     * disabled.
                2335     */
                2336 #if 0
                2337     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
                2338     *msg = xmlStrcat(*msg, BAD_CAST " [");
                2339     *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
                2340         NULL, type, NULL, 0));
                2341     FREE_AND_NULL(str)
                2342     *msg = xmlStrcat(*msg, BAD_CAST "]");
                2343     }
                2344 #endif
                2345     return (*msg);
                2346 }
                2347 
                2348 static void LIBXML_ATTR_FORMAT(3,0)
                2349 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
                2350              const char *funcName,
                2351              const char *message,
                2352              const xmlChar *str1,
                2353              const xmlChar *str2)
                2354 {
                2355     xmlChar *msg = NULL;
                2356 
                2357     if (actxt == NULL)
                2358         return;
                2359     msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
                2360     msg = xmlStrcat(msg, BAD_CAST message);
                2361     msg = xmlStrcat(msg, BAD_CAST ".\n");
                2362 
                2363     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
                2364     xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
                2365         (const char *) msg, (const xmlChar *) funcName, str1, str2);
                2366     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
                2367     xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
                2368         (const char *) msg, (const xmlChar *) funcName, str1, str2);
                2369 
                2370     FREE_AND_NULL(msg)
                2371 }
                2372 
                2373 static void LIBXML_ATTR_FORMAT(3,0)
                2374 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
                2375              const char *funcName,
                2376              const char *message)
                2377 {
                2378     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
                2379 }
                2380 
                2381 #if 0
                2382 static void LIBXML_ATTR_FORMAT(3,0)
                2383 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
                2384              const char *funcName,
                2385              const char *message,
                2386              const xmlChar *str1,
                2387              const xmlChar *str2)
                2388 {
                2389     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
                2390     str1, str2);
                2391 }
                2392 #endif
                2393 
                2394 static void LIBXML_ATTR_FORMAT(5,0)
                2395 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
                2396            xmlParserErrors error,
                2397            xmlNodePtr node,
                2398            xmlSchemaBasicItemPtr item,
                2399            const char *message,
                2400            const xmlChar *str1, const xmlChar *str2,
                2401            const xmlChar *str3, const xmlChar *str4)
                2402 {
                2403     xmlChar *msg = NULL;
                2404 
                2405     if ((node == NULL) && (item != NULL) &&
                2406     (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
                2407     node = WXS_ITEM_NODE(item);
                2408     xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
                2409     msg = xmlStrcat(msg, BAD_CAST ": ");
                2410     } else
                2411     xmlSchemaFormatNodeForError(&msg, actxt, node);
                2412     msg = xmlStrcat(msg, (const xmlChar *) message);
                2413     msg = xmlStrcat(msg, BAD_CAST ".\n");
                2414     xmlSchemaErr4(actxt, error, node,
                2415     (const char *) msg, str1, str2, str3, str4);
                2416     FREE_AND_NULL(msg)
                2417 }
                2418 
                2419 static void LIBXML_ATTR_FORMAT(5,0)
                2420 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
                2421            xmlParserErrors error,
                2422            xmlNodePtr node,
                2423            xmlSchemaBasicItemPtr item,
                2424            const char *message,
                2425            const xmlChar *str1,
                2426            const xmlChar *str2)
                2427 {
                2428     xmlSchemaCustomErr4(actxt, error, node, item,
                2429     message, str1, str2, NULL, NULL);
                2430 }
                2431 
                2432 
                2433 
                2434 static void LIBXML_ATTR_FORMAT(5,0)
                2435 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
                2436            xmlParserErrors error,
                2437            xmlNodePtr node,
                2438            xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
                2439            const char *message,
                2440            const xmlChar *str1,
                2441            const xmlChar *str2,
                2442            const xmlChar *str3)
                2443 {
                2444     xmlChar *msg = NULL;
                2445 
                2446     xmlSchemaFormatNodeForError(&msg, actxt, node);
                2447     msg = xmlStrcat(msg, (const xmlChar *) message);
                2448     msg = xmlStrcat(msg, BAD_CAST ".\n");
                2449 
                2450     /* URGENT TODO: Set the error code to something sane. */
                2451     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
                2452     (const char *) msg, str1, str2, str3, NULL);
                2453 
                2454     FREE_AND_NULL(msg)
                2455 }
                2456 
                2457 
                2458 
                2459 static void LIBXML_ATTR_FORMAT(5,0)
                2460 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
                2461            xmlParserErrors error,
                2462            xmlSchemaPSVIIDCNodePtr idcNode,
                2463            xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
                2464            const char *message,
                2465            const xmlChar *str1,
                2466            const xmlChar *str2)
                2467 {
                2468     xmlChar *msg = NULL, *qname = NULL;
                2469 
                2470     msg = xmlStrdup(BAD_CAST "Element '%s': ");
                2471     msg = xmlStrcat(msg, (const xmlChar *) message);
                2472     msg = xmlStrcat(msg, BAD_CAST ".\n");
                2473     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
                2474     error, NULL, idcNode->nodeLine, (const char *) msg,
                2475     xmlSchemaFormatQName(&qname,
                2476         vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
                2477         vctxt->nodeQNames->items[idcNode->nodeQNameID]),
                2478     str1, str2, NULL);
                2479     FREE_AND_NULL(qname);
                2480     FREE_AND_NULL(msg);
                2481 }
                2482 
                2483 static int
                2484 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
                2485                xmlNodePtr node)
                2486 {
                2487     if (node != NULL)
                2488     return (node->type);
                2489     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
                2490     (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
                2491     return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
                2492     return (-1);
                2493 }
                2494 
                2495 static int
                2496 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
                2497 {
                2498     switch (item->type) {
                2499     case XML_SCHEMA_TYPE_COMPLEX:
                2500     case XML_SCHEMA_TYPE_SIMPLE:
                2501         if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
                2502         return(1);
                2503         break;
                2504     case XML_SCHEMA_TYPE_GROUP:
                2505         return (1);
                2506     case XML_SCHEMA_TYPE_ELEMENT:
                2507         if ( ((xmlSchemaElementPtr) item)->flags &
                2508         XML_SCHEMAS_ELEM_GLOBAL)
                2509         return(1);
                2510         break;
                2511     case XML_SCHEMA_TYPE_ATTRIBUTE:
                2512         if ( ((xmlSchemaAttributePtr) item)->flags &
                2513         XML_SCHEMAS_ATTR_GLOBAL)
                2514         return(1);
                2515         break;
                2516     /* Note that attribute groups are always global. */
                2517     default:
                2518         return(1);
                2519     }
                2520     return (0);
                2521 }
                2522 
                2523 static void
                2524 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
                2525                xmlParserErrors error,
                2526                xmlNodePtr node,
                2527                const xmlChar *value,
                2528                xmlSchemaTypePtr type,
                2529                int displayValue)
                2530 {
                2531     xmlChar *msg = NULL;
                2532 
                2533     xmlSchemaFormatNodeForError(&msg, actxt, node);
                2534 
                2535     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
                2536         XML_ATTRIBUTE_NODE))
                2537     msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
                2538     else
                2539     msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
                2540         "value of ");
                2541 
                2542     if (! xmlSchemaIsGlobalItem(type))
                2543     msg = xmlStrcat(msg, BAD_CAST "the local ");
                2544     else
                2545     msg = xmlStrcat(msg, BAD_CAST "the ");
                2546 
                2547     if (WXS_IS_ATOMIC(type))
                2548     msg = xmlStrcat(msg, BAD_CAST "atomic type");
                2549     else if (WXS_IS_LIST(type))
                2550     msg = xmlStrcat(msg, BAD_CAST "list type");
                2551     else if (WXS_IS_UNION(type))
                2552     msg = xmlStrcat(msg, BAD_CAST "union type");
                2553 
                2554     if (xmlSchemaIsGlobalItem(type)) {
                2555     xmlChar *str = NULL;
                2556     msg = xmlStrcat(msg, BAD_CAST " '");
                2557     if (type->builtInType != 0) {
                2558         msg = xmlStrcat(msg, BAD_CAST "xs:");
                2559         str = xmlStrdup(type->name);
                2560     } else {
                2561         const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
                2562         if (!str)
                2563         str = xmlStrdup(qName);
                2564     }
                2565     msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
                2566     msg = xmlStrcat(msg, BAD_CAST "'");
                2567     FREE_AND_NULL(str);
                2568     }
                2569     msg = xmlStrcat(msg, BAD_CAST ".\n");
                2570     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
                2571         XML_ATTRIBUTE_NODE))
                2572     xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
                2573     else
                2574     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
                2575     FREE_AND_NULL(msg)
                2576 }
                2577 
                2578 static const xmlChar *
                2579 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
                2580                   xmlSchemaNodeInfoPtr ni,
                2581                   xmlNodePtr node)
                2582 {
                2583     if (node != NULL) {
                2584     if (node->ns != NULL)
                2585         return (xmlSchemaFormatQName(str, node->ns->href, node->name));
                2586     else
                2587         return (xmlSchemaFormatQName(str, NULL, node->name));
                2588     } else if (ni != NULL)
                2589     return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
                2590     return (NULL);
                2591 }
                2592 
                2593 static void
                2594 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
                2595             xmlParserErrors error,
                2596             xmlSchemaAttrInfoPtr ni,
                2597             xmlNodePtr node)
                2598 {
                2599     xmlChar *msg = NULL, *str = NULL;
                2600 
                2601     xmlSchemaFormatNodeForError(&msg, actxt, node);
                2602     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
                2603     xmlSchemaErr(actxt, error, node, (const char *) msg,
                2604     xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
                2605     NULL);
                2606     FREE_AND_NULL(str)
                2607     FREE_AND_NULL(msg)
                2608 }
                2609 
                2610 static void LIBXML_ATTR_FORMAT(5,0)
                2611 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
                2612                 xmlParserErrors error,
                2613                 xmlNodePtr node,
                2614             xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
                2615             const char *message,
                2616             int nbval,
                2617             int nbneg,
                2618             xmlChar **values)
                2619 {
                2620     xmlChar *str = NULL, *msg = NULL;
                2621     xmlChar *localName, *nsName;
                2622     const xmlChar *cur, *end;
                2623     int i;
                2624 
                2625     xmlSchemaFormatNodeForError(&msg, actxt, node);
                2626     msg = xmlStrcat(msg, (const xmlChar *) message);
                2627     msg = xmlStrcat(msg, BAD_CAST ".");
                2628     /*
                2629     * Note that is does not make sense to report that we have a
                2630     * wildcard here, since the wildcard might be unfolded into
                2631     * multiple transitions.
                2632     */
                2633     if (nbval + nbneg > 0) {
                2634     if (nbval + nbneg > 1) {
                2635         str = xmlStrdup(BAD_CAST " Expected is one of ( ");
                2636     } else
                2637         str = xmlStrdup(BAD_CAST " Expected is ( ");
                2638     nsName = NULL;
                2639 
                2640     for (i = 0; i < nbval + nbneg; i++) {
                2641         cur = values[i];
                2642         if (cur == NULL)
                2643             continue;
                2644         if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
                2645             (cur[3] == ' ')) {
                2646         cur += 4;
                2647         str = xmlStrcat(str, BAD_CAST "##other");
                2648         }
                2649         /*
                2650         * Get the local name.
                2651         */
                2652         localName = NULL;
                2653 
                2654         end = cur;
                2655         if (*end == '*') {
                2656         localName = xmlStrdup(BAD_CAST "*");
                2657         end++;
                2658         } else {
                2659         while ((*end != 0) && (*end != '|'))
                2660             end++;
                2661         localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
                2662         }
                2663         if (*end != 0) {
                2664         end++;
                2665         /*
                2666         * Skip "*|*" if they come with negated expressions, since
                2667         * they represent the same negated wildcard.
                2668         */
                2669         if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
                2670             /*
                2671             * Get the namespace name.
                2672             */
                2673             cur = end;
                2674             if (*end == '*') {
                2675             nsName = xmlStrdup(BAD_CAST "{*}");
                2676             } else {
                2677             while (*end != 0)
                2678                 end++;
                2679 
                2680             if (i >= nbval)
                2681                 nsName = xmlStrdup(BAD_CAST "{##other:");
                2682             else
                2683                 nsName = xmlStrdup(BAD_CAST "{");
                2684 
                2685             nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
                2686             nsName = xmlStrcat(nsName, BAD_CAST "}");
                2687             }
                2688             str = xmlStrcat(str, BAD_CAST nsName);
                2689             FREE_AND_NULL(nsName)
                2690         } else {
                2691             FREE_AND_NULL(localName);
                2692             continue;
                2693         }
                2694         }
                2695         str = xmlStrcat(str, BAD_CAST localName);
                2696         FREE_AND_NULL(localName);
                2697 
                2698         if (i < nbval + nbneg -1)
                2699         str = xmlStrcat(str, BAD_CAST ", ");
                2700     }
                2701     str = xmlStrcat(str, BAD_CAST " ).\n");
                2702     msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
                2703     FREE_AND_NULL(str)
                2704     } else
                2705       msg = xmlStrcat(msg, BAD_CAST "\n");
                2706     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
                2707     xmlFree(msg);
                2708 }
                2709 
                2710 static void LIBXML_ATTR_FORMAT(8,0)
                2711 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
                2712           xmlParserErrors error,
                2713           xmlNodePtr node,
                2714           const xmlChar *value,
                2715           unsigned long length,
                2716           xmlSchemaTypePtr type,
                2717           xmlSchemaFacetPtr facet,
                2718           const char *message,
                2719           const xmlChar *str1,
                2720           const xmlChar *str2)
                2721 {
                2722     xmlChar *str = NULL, *msg = NULL;
                2723     xmlSchemaTypeType facetType;
                2724     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
                2725 
                2726     xmlSchemaFormatNodeForError(&msg, actxt, node);
                2727     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
                2728     facetType = XML_SCHEMA_FACET_ENUMERATION;
                2729     /*
                2730     * If enumerations are validated, one must not expect the
                2731     * facet to be given.
                2732     */
                2733     } else
                2734     facetType = facet->type;
                2735     msg = xmlStrcat(msg, BAD_CAST "[");
                2736     msg = xmlStrcat(msg, BAD_CAST "facet '");
                2737     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
                2738     msg = xmlStrcat(msg, BAD_CAST "'] ");
                2739     if (message == NULL) {
                2740     /*
                2741     * Use a default message.
                2742     */
                2743     if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
                2744         (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
                2745         (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
                2746 
                2747         char len[25], actLen[25];
                2748 
                2749         /* FIXME, TODO: What is the max expected string length of the
                2750         * this value?
                2751         */
                2752         if (nodeType == XML_ATTRIBUTE_NODE)
                2753         msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
                2754         else
                2755         msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
                2756 
                2757         snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
                2758         snprintf(actLen, 24, "%lu", length);
                2759 
                2760         if (facetType == XML_SCHEMA_FACET_LENGTH)
                2761         msg = xmlStrcat(msg,
                2762         BAD_CAST "this differs from the allowed length of '%s'.\n");
                2763         else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
                2764         msg = xmlStrcat(msg,
                2765         BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
                2766         else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
                2767         msg = xmlStrcat(msg,
                2768         BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
                2769 
                2770         if (nodeType == XML_ATTRIBUTE_NODE)
                2771         xmlSchemaErr3(actxt, error, node, (const char *) msg,
                2772             value, (const xmlChar *) actLen, (const xmlChar *) len);
                2773         else
                2774         xmlSchemaErr(actxt, error, node, (const char *) msg,
                2775             (const xmlChar *) actLen, (const xmlChar *) len);
                2776 
                2777     } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
                2778         msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
                2779         "of the set {%s}.\n");
                2780         xmlSchemaErr(actxt, error, node, (const char *) msg, value,
                2781         xmlSchemaFormatFacetEnumSet(actxt, &str, type));
                2782     } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
                2783         msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
                2784         "by the pattern '%s'.\n");
                2785         xmlSchemaErr(actxt, error, node, (const char *) msg, value,
                2786         facet->value);
                2787     } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
                2788         msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
                2789         "minimum value allowed ('%s').\n");
                2790         xmlSchemaErr(actxt, error, node, (const char *) msg, value,
                2791         facet->value);
                2792     } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
                2793         msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
                2794         "maximum value allowed ('%s').\n");
                2795         xmlSchemaErr(actxt, error, node, (const char *) msg, value,
                2796         facet->value);
                2797     } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
                2798         msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
                2799         "'%s'.\n");
                2800         xmlSchemaErr(actxt, error, node, (const char *) msg, value,
                2801         facet->value);
                2802     } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
                2803         msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
                2804         "'%s'.\n");
                2805         xmlSchemaErr(actxt, error, node, (const char *) msg, value,
                2806         facet->value);
                2807     } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
                2808         msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
                2809         "digits than are allowed ('%s').\n");
                2810         xmlSchemaErr(actxt, error, node, (const char*) msg, value,
                2811         facet->value);
                2812     } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
                2813         msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
                2814         "digits than are allowed ('%s').\n");
                2815         xmlSchemaErr(actxt, error, node, (const char*) msg, value,
                2816         facet->value);
                2817     } else if (nodeType == XML_ATTRIBUTE_NODE) {
                2818         msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
                2819         xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
                2820     } else {
                2821         msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
                2822         xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
                2823     }
                2824     } else {
                2825     msg = xmlStrcat(msg, (const xmlChar *) message);
                2826     msg = xmlStrcat(msg, BAD_CAST ".\n");
                2827     xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
                2828     }
                2829     FREE_AND_NULL(str)
                2830     xmlFree(msg);
                2831 }
                2832 
                2833 #define VERROR(err, type, msg) \
                2834     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
                2835 
                2836 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
                2837 
                2838 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
                2839 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
                2840 
                2841 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
                2842 
                2843 
                2844 /**
                2845  * xmlSchemaPMissingAttrErr:
                2846  * @ctxt: the schema validation context
                2847  * @ownerItem: the owner as a schema object
                2848  * @ownerElem: the owner as an element node
                2849  * @node: the parent element node of the missing attribute node
                2850  * @type: the corresponding type of the attribute node
                2851  *
                2852  * Reports an illegal attribute.
                2853  */
                2854 static void
                2855 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
                2856              xmlParserErrors error,
                2857              xmlSchemaBasicItemPtr ownerItem,
                2858              xmlNodePtr ownerElem,
                2859              const char *name,
                2860              const char *message)
                2861 {
                2862     xmlChar *des = NULL;
                2863 
                2864     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
                2865 
                2866     if (message != NULL)
                2867     xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
                2868     else
                2869     xmlSchemaPErr(ctxt, ownerElem, error,
                2870         "%s: The attribute '%s' is required but missing.\n",
                2871         BAD_CAST des, BAD_CAST name);
                2872     FREE_AND_NULL(des);
                2873 }
                2874 
                2875 
                2876 /**
                2877  * xmlSchemaPResCompAttrErr:
                2878  * @ctxt: the schema validation context
                2879  * @error: the error code
                2880  * @ownerItem: the owner as a schema object
                2881  * @ownerElem: the owner as an element node
                2882  * @name: the name of the attribute holding the QName
                2883  * @refName: the referenced local name
                2884  * @refURI: the referenced namespace URI
                2885  * @message: optional message
                2886  *
                2887  * Used to report QName attribute values that failed to resolve
                2888  * to schema components.
                2889  */
                2890 static void
                2891 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
                2892              xmlParserErrors error,
                2893              xmlSchemaBasicItemPtr ownerItem,
                2894              xmlNodePtr ownerElem,
                2895              const char *name,
                2896              const xmlChar *refName,
                2897              const xmlChar *refURI,
                2898              xmlSchemaTypeType refType,
                2899              const char *refTypeStr)
                2900 {
                2901     xmlChar *des = NULL, *strA = NULL;
                2902 
                2903     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
                2904     if (refTypeStr == NULL)
                2905     refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
                2906     xmlSchemaPErrExt(ctxt, ownerElem, error,
                2907         NULL, NULL, NULL,
                2908         "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
                2909         "%s.\n", BAD_CAST des, BAD_CAST name,
                2910         xmlSchemaFormatQName(&strA, refURI, refName),
                2911         BAD_CAST refTypeStr, NULL);
                2912     FREE_AND_NULL(des)
                2913     FREE_AND_NULL(strA)
                2914 }
                2915 
                2916 /**
                2917  * xmlSchemaPCustomAttrErr:
                2918  * @ctxt: the schema parser context
                2919  * @error: the error code
                2920  * @ownerDes: the designation of the owner
                2921  * @ownerItem: the owner as a schema object
                2922  * @attr: the illegal attribute node
                2923  *
                2924  * Reports an illegal attribute during the parse.
                2925  */
                2926 static void
                2927 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
                2928             xmlParserErrors error,
                2929             xmlChar **ownerDes,
                2930             xmlSchemaBasicItemPtr ownerItem,
                2931             xmlAttrPtr attr,
                2932             const char *msg)
                2933 {
                2934     xmlChar *des = NULL;
                2935 
                2936     if (ownerDes == NULL)
                2937     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
                2938     else if (*ownerDes == NULL) {
                2939     xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
                2940     des = *ownerDes;
                2941     } else
                2942     des = *ownerDes;
                2943     if (attr == NULL) {
                2944     xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
                2945         "%s, attribute '%s': %s.\n",
                2946         BAD_CAST des, (const xmlChar *) "Unknown",
                2947         (const xmlChar *) msg, NULL, NULL);
                2948     } else {
                2949     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
                2950         "%s, attribute '%s': %s.\n",
                2951         BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
                2952     }
                2953     if (ownerDes == NULL)
                2954     FREE_AND_NULL(des);
                2955 }
                2956 
                2957 /**
                2958  * xmlSchemaPIllegalAttrErr:
                2959  * @ctxt: the schema parser context
                2960  * @error: the error code
                2961  * @ownerItem: the attribute's owner item
                2962  * @attr: the illegal attribute node
                2963  *
                2964  * Reports an illegal attribute during the parse.
                2965  */
                2966 static void
                2967 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
                2968              xmlParserErrors error,
                2969              xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
                2970              xmlAttrPtr attr)
                2971 {
                2972     xmlChar *strA = NULL, *strB = NULL;
                2973 
                2974     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
                2975     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
                2976     "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
                2977     xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
                2978     NULL, NULL);
                2979     FREE_AND_NULL(strA);
                2980     FREE_AND_NULL(strB);
                2981 }
                2982 
                2983 /**
                2984  * xmlSchemaPCustomErr:
                2985  * @ctxt: the schema parser context
                2986  * @error: the error code
                2987  * @itemDes: the designation of the schema item
                2988  * @item: the schema item
                2989  * @itemElem: the node of the schema item
                2990  * @message: the error message
                2991  * @str1: an optional param for the error message
                2992  * @str2: an optional param for the error message
                2993  * @str3: an optional param for the error message
                2994  *
                2995  * Reports an error during parsing.
                2996  */
                2997 static void LIBXML_ATTR_FORMAT(5,0)
                2998 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
                2999             xmlParserErrors error,
                3000             xmlSchemaBasicItemPtr item,
                3001             xmlNodePtr itemElem,
                3002             const char *message,
                3003             const xmlChar *str1,
                3004             const xmlChar *str2,
                3005             const xmlChar *str3)
                3006 {
                3007     xmlChar *des = NULL, *msg = NULL;
                3008 
                3009     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
                3010     msg = xmlStrdup(BAD_CAST "%s: ");
                3011     msg = xmlStrcat(msg, (const xmlChar *) message);
                3012     msg = xmlStrcat(msg, BAD_CAST ".\n");
                3013     if ((itemElem == NULL) && (item != NULL))
                3014     itemElem = WXS_ITEM_NODE(item);
                3015     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
                3016     (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
                3017     FREE_AND_NULL(des);
                3018     FREE_AND_NULL(msg);
                3019 }
                3020 
                3021 /**
                3022  * xmlSchemaPCustomErr:
                3023  * @ctxt: the schema parser context
                3024  * @error: the error code
                3025  * @itemDes: the designation of the schema item
                3026  * @item: the schema item
                3027  * @itemElem: the node of the schema item
                3028  * @message: the error message
                3029  * @str1: the optional param for the error message
                3030  *
                3031  * Reports an error during parsing.
                3032  */
                3033 static void LIBXML_ATTR_FORMAT(5,0)
                3034 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
                3035             xmlParserErrors error,
                3036             xmlSchemaBasicItemPtr item,
                3037             xmlNodePtr itemElem,
                3038             const char *message,
                3039             const xmlChar *str1)
                3040 {
                3041     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
                3042     str1, NULL, NULL);
                3043 }
                3044 
                3045 /**
                3046  * xmlSchemaPAttrUseErr:
                3047  * @ctxt: the schema parser context
                3048  * @error: the error code
                3049  * @itemDes: the designation of the schema type
                3050  * @item: the schema type
                3051  * @itemElem: the node of the schema type
                3052  * @attr: the invalid schema attribute
                3053  * @message: the error message
                3054  * @str1: the optional param for the error message
                3055  *
                3056  * Reports an attribute use error during parsing.
                3057  */
                3058 static void LIBXML_ATTR_FORMAT(6,0)
                3059 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
                3060             xmlParserErrors error,
                3061             xmlNodePtr node,
                3062             xmlSchemaBasicItemPtr ownerItem,
                3063             const xmlSchemaAttributeUsePtr attruse,
                3064             const char *message,
                3065             const xmlChar *str1, const xmlChar *str2,
                3066             const xmlChar *str3,const xmlChar *str4)
                3067 {
                3068     xmlChar *str = NULL, *msg = NULL;
                3069 
                3070     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
                3071     msg = xmlStrcat(msg, BAD_CAST ", ");
                3072     msg = xmlStrcat(msg,
                3073     BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
                3074     WXS_BASIC_CAST attruse, NULL));
                3075     FREE_AND_NULL(str);
                3076     msg = xmlStrcat(msg, BAD_CAST ": ");
                3077     msg = xmlStrcat(msg, (const xmlChar *) message);
                3078     msg = xmlStrcat(msg, BAD_CAST ".\n");
                3079     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
                3080     (const char *) msg, str1, str2, str3, str4);
                3081     xmlFree(msg);
                3082 }
                3083 
                3084 /**
                3085  * xmlSchemaPIllegalFacetAtomicErr:
                3086  * @ctxt: the schema parser context
                3087  * @error: the error code
                3088  * @type: the schema type
                3089  * @baseType: the base type of type
                3090  * @facet: the illegal facet
                3091  *
                3092  * Reports an illegal facet for atomic simple types.
                3093  */
                3094 static void
                3095 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
                3096               xmlParserErrors error,
                3097               xmlSchemaTypePtr type,
                3098               xmlSchemaTypePtr baseType,
                3099               xmlSchemaFacetPtr facet)
                3100 {
                3101     xmlChar *des = NULL, *strT = NULL;
                3102 
                3103     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
                3104     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
                3105     "%s: The facet '%s' is not allowed on types derived from the "
                3106     "type %s.\n",
                3107     BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
                3108     xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
                3109     NULL, NULL);
                3110     FREE_AND_NULL(des);
                3111     FREE_AND_NULL(strT);
                3112 }
                3113 
                3114 /**
                3115  * xmlSchemaPIllegalFacetListUnionErr:
                3116  * @ctxt: the schema parser context
                3117  * @error: the error code
                3118  * @itemDes: the designation of the schema item involved
                3119  * @item: the schema item involved
                3120  * @facet: the illegal facet
                3121  *
                3122  * Reports an illegal facet for <list> and <union>.
                3123  */
                3124 static void
                3125 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
                3126               xmlParserErrors error,
                3127               xmlSchemaTypePtr type,
                3128               xmlSchemaFacetPtr facet)
                3129 {
                3130     xmlChar *des = NULL;
                3131 
                3132     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
                3133     type->node);
                3134     xmlSchemaPErr(ctxt, type->node, error,
                3135     "%s: The facet '%s' is not allowed.\n",
                3136     BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
                3137     FREE_AND_NULL(des);
                3138 }
                3139 
                3140 /**
                3141  * xmlSchemaPMutualExclAttrErr:
                3142  * @ctxt: the schema validation context
                3143  * @error: the error code
                3144  * @elemDes: the designation of the parent element node
                3145  * @attr: the bad attribute node
                3146  * @type: the corresponding type of the attribute node
                3147  *
                3148  * Reports an illegal attribute.
                3149  */
                3150 static void
                3151 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
                3152              xmlParserErrors error,
                3153              xmlSchemaBasicItemPtr ownerItem,
                3154              xmlAttrPtr attr,
                3155              const char *name1,
                3156              const char *name2)
                3157 {
                3158     xmlChar *des = NULL;
                3159 
                3160     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
                3161     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
                3162     "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
                3163     BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
                3164     FREE_AND_NULL(des);
                3165 }
                3166 
                3167 /**
                3168  * xmlSchemaPSimpleTypeErr:
                3169  * @ctxt:  the schema validation context
                3170  * @error: the error code
                3171  * @type: the type specifier
                3172  * @ownerItem: the schema object if existent
                3173  * @node: the validated node
                3174  * @value: the validated value
                3175  *
                3176  * Reports a simple type validation error.
                3177  * TODO: Should this report the value of an element as well?
                3178  */
                3179 static void LIBXML_ATTR_FORMAT(8,0)
                3180 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
                3181             xmlParserErrors error,
                3182             xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
                3183             xmlNodePtr node,
                3184             xmlSchemaTypePtr type,
                3185             const char *expected,
                3186             const xmlChar *value,
                3187             const char *message,
                3188             const xmlChar *str1,
                3189             const xmlChar *str2)
                3190 {
                3191     xmlChar *msg = NULL;
                3192 
                3193     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
                3194     if (message == NULL) {
                3195     /*
                3196     * Use default messages.
                3197     */
                3198     if (type != NULL) {
                3199         if (node->type == XML_ATTRIBUTE_NODE)
                3200         msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
                3201         else
                3202         msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
                3203         "valid value of ");
                3204         if (! xmlSchemaIsGlobalItem(type))
                3205         msg = xmlStrcat(msg, BAD_CAST "the local ");
                3206         else
                3207         msg = xmlStrcat(msg, BAD_CAST "the ");
                3208 
                3209         if (WXS_IS_ATOMIC(type))
                3210         msg = xmlStrcat(msg, BAD_CAST "atomic type");
                3211         else if (WXS_IS_LIST(type))
                3212         msg = xmlStrcat(msg, BAD_CAST "list type");
                3213         else if (WXS_IS_UNION(type))
                3214         msg = xmlStrcat(msg, BAD_CAST "union type");
                3215 
                3216         if (xmlSchemaIsGlobalItem(type)) {
                3217         xmlChar *str = NULL;
                3218         msg = xmlStrcat(msg, BAD_CAST " '");
                3219         if (type->builtInType != 0) {
                3220             msg = xmlStrcat(msg, BAD_CAST "xs:");
                3221             str = xmlStrdup(type->name);
                3222         } else {
                3223             const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
                3224             if (!str)
                3225             str = xmlStrdup(qName);
                3226         }
                3227         msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
                3228         msg = xmlStrcat(msg, BAD_CAST "'.");
                3229         FREE_AND_NULL(str);
                3230         }
                3231     } else {
                3232         if (node->type == XML_ATTRIBUTE_NODE)
                3233         msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
                3234         else
                3235         msg = xmlStrcat(msg, BAD_CAST "The character content is not "
                3236         "valid.");
                3237     }
                3238     if (expected) {
                3239         xmlChar *expectedEscaped = xmlCharStrdup(expected);
                3240         msg = xmlStrcat(msg, BAD_CAST " Expected is '");
                3241         msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
                3242         FREE_AND_NULL(expectedEscaped);
                3243         msg = xmlStrcat(msg, BAD_CAST "'.\n");
                3244     } else
                3245         msg = xmlStrcat(msg, BAD_CAST "\n");
                3246     if (node->type == XML_ATTRIBUTE_NODE)
                3247         xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
                3248     else
                3249         xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
                3250     } else {
                3251     msg = xmlStrcat(msg, BAD_CAST message);
                3252     msg = xmlStrcat(msg, BAD_CAST ".\n");
                3253     xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
                3254          (const char*) msg, str1, str2, NULL, NULL, NULL);
                3255     }
                3256     /* Cleanup. */
                3257     FREE_AND_NULL(msg)
                3258 }
                3259 
                3260 /**
                3261  * xmlSchemaPContentErr:
                3262  * @ctxt: the schema parser context
                3263  * @error: the error code
                3264  * @ownerItem: the owner item of the holder of the content
                3265  * @ownerElem: the node of the holder of the content
                3266  * @child: the invalid child node
                3267  * @message: the optional error message
                3268  * @content: the optional string describing the correct content
                3269  *
                3270  * Reports an error concerning the content of a schema element.
                3271  */
                3272 static void
                3273 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
                3274              xmlParserErrors error,
                3275              xmlSchemaBasicItemPtr ownerItem,
                3276              xmlNodePtr ownerElem,
                3277              xmlNodePtr child,
                3278              const char *message,
                3279              const char *content)
                3280 {
                3281     xmlChar *des = NULL;
                3282 
                3283     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
                3284     if (message != NULL)
                3285     xmlSchemaPErr2(ctxt, ownerElem, child, error,
                3286         "%s: %s.\n",
                3287         BAD_CAST des, BAD_CAST message);
                3288     else {
                3289     if (content != NULL) {
                3290         xmlSchemaPErr2(ctxt, ownerElem, child, error,
                3291         "%s: The content is not valid. Expected is %s.\n",
                3292         BAD_CAST des, BAD_CAST content);
                3293     } else {
                3294         xmlSchemaPErr2(ctxt, ownerElem, child, error,
                3295         "%s: The content is not valid.\n",
                3296         BAD_CAST des, NULL);
                3297     }
                3298     }
                3299     FREE_AND_NULL(des)
                3300 }
                3301 
                3302 /************************************************************************
                3303  *                                  *
                3304  *          Streamable error functions                      *
                3305  *                                  *
                3306  ************************************************************************/
                3307 
                3308 
                3309 
                3310 
                3311 /************************************************************************
                3312  *                                  *
                3313  *          Validation helper functions         *
                3314  *                                  *
                3315  ************************************************************************/
                3316 
                3317 
                3318 /************************************************************************
                3319  *                                  *
                3320  *          Allocation functions                *
                3321  *                                  *
                3322  ************************************************************************/
                3323 
                3324 /**
                3325  * xmlSchemaNewSchemaForParserCtxt:
                3326  * @ctxt:  a schema validation context
                3327  *
                3328  * Allocate a new Schema structure.
                3329  *
                3330  * Returns the newly allocated structure or NULL in case or error
                3331  */
                3332 static xmlSchemaPtr
                3333 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
                3334 {
                3335     xmlSchemaPtr ret;
                3336 
                3337     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
                3338     if (ret == NULL) {
                3339         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
                3340         return (NULL);
                3341     }
                3342     memset(ret, 0, sizeof(xmlSchema));
                3343     ret->dict = ctxt->dict;
                3344     xmlDictReference(ret->dict);
                3345 
                3346     return (ret);
                3347 }
                3348 
                3349 /**
                3350  * xmlSchemaNewFacet:
                3351  *
                3352  * Allocate a new Facet structure.
                3353  *
                3354  * Returns the newly allocated structure or NULL in case or error
                3355  */
                3356 xmlSchemaFacetPtr
                3357 xmlSchemaNewFacet(void)
                3358 {
                3359     xmlSchemaFacetPtr ret;
                3360 
                3361     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
                3362     if (ret == NULL) {
                3363         return (NULL);
                3364     }
                3365     memset(ret, 0, sizeof(xmlSchemaFacet));
                3366 
                3367     return (ret);
                3368 }
                3369 
                3370 /**
                3371  * xmlSchemaNewAnnot:
                3372  * @ctxt:  a schema validation context
                3373  * @node:  a node
                3374  *
                3375  * Allocate a new annotation structure.
                3376  *
                3377  * Returns the newly allocated structure or NULL in case or error
                3378  */
                3379 static xmlSchemaAnnotPtr
                3380 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
                3381 {
                3382     xmlSchemaAnnotPtr ret;
                3383 
                3384     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
                3385     if (ret == NULL) {
                3386         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
                3387         return (NULL);
                3388     }
                3389     memset(ret, 0, sizeof(xmlSchemaAnnot));
                3390     ret->content = node;
                3391     return (ret);
                3392 }
                3393 
                3394 static xmlSchemaItemListPtr
                3395 xmlSchemaItemListCreate(void)
                3396 {
                3397     xmlSchemaItemListPtr ret;
                3398 
                3399     ret = xmlMalloc(sizeof(xmlSchemaItemList));
                3400     if (ret == NULL) {
                3401     xmlSchemaPErrMemory(NULL,
                3402         "allocating an item list structure", NULL);
                3403     return (NULL);
                3404     }
                3405     memset(ret, 0, sizeof(xmlSchemaItemList));
                3406     return (ret);
                3407 }
                3408 
                3409 static void
                3410 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
                3411 {
                3412     if (list->items != NULL) {
                3413     xmlFree(list->items);
                3414     list->items = NULL;
                3415     }
                3416     list->nbItems = 0;
                3417     list->sizeItems = 0;
                3418 }
                3419 
                3420 static int
                3421 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
                3422 {
ad7b9726c Alex*3423     if (list->sizeItems <= list->nbItems) {
                3424         void **tmp;
                3425         size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
                3426 
                3427     tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
                3428     if (tmp == NULL) {
9d9d4fcc3 Alex*3429         xmlSchemaPErrMemory(NULL, "growing item list", NULL);
                3430         return(-1);
                3431     }
ad7b9726c Alex*3432         list->items = tmp;
                3433     list->sizeItems = newSize;
9d9d4fcc3 Alex*3434     }
                3435     list->items[list->nbItems++] = item;
                3436     return(0);
                3437 }
                3438 
                3439 static int
                3440 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
                3441              int initialSize,
                3442              void *item)
                3443 {
                3444     if (list->items == NULL) {
                3445     if (initialSize <= 0)
                3446         initialSize = 1;
                3447     list->items = (void **) xmlMalloc(
                3448         initialSize * sizeof(void *));
                3449     if (list->items == NULL) {
                3450         xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
                3451         return(-1);
                3452     }
                3453     list->sizeItems = initialSize;
                3454     } else if (list->sizeItems <= list->nbItems) {
ad7b9726c Alex*3455         void **tmp;
                3456 
9d9d4fcc3 Alex*3457     list->sizeItems *= 2;
ad7b9726c Alex*3458     tmp = (void **) xmlRealloc(list->items,
9d9d4fcc3 Alex*3459         list->sizeItems * sizeof(void *));
ad7b9726c Alex*3460     if (tmp == NULL) {
9d9d4fcc3 Alex*3461         xmlSchemaPErrMemory(NULL, "growing item list", NULL);
ad7b9726c Alex*3462         list->sizeItems /= 2;
9d9d4fcc3 Alex*3463         return(-1);
                3464     }
ad7b9726c Alex*3465         list->items = tmp;
9d9d4fcc3 Alex*3466     }
                3467     list->items[list->nbItems++] = item;
                3468     return(0);
                3469 }
                3470 
                3471 static int
                3472 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
                3473 {
ad7b9726c Alex*3474     if (list->sizeItems <= list->nbItems) {
                3475         void **tmp;
                3476         size_t newSize = list->sizeItems == 0 ? 20 : list->sizeItems * 2;
                3477 
                3478     tmp = (void **) xmlRealloc(list->items, newSize * sizeof(void *));
                3479     if (tmp == NULL) {
9d9d4fcc3 Alex*3480         xmlSchemaPErrMemory(NULL, "growing item list", NULL);
                3481         return(-1);
                3482     }
ad7b9726c Alex*3483         list->items = tmp;
                3484     list->sizeItems = newSize;
9d9d4fcc3 Alex*3485     }
                3486     /*
                3487     * Just append if the index is greater/equal than the item count.
                3488     */
                3489     if (idx >= list->nbItems) {
                3490     list->items[list->nbItems++] = item;
                3491     } else {
                3492     int i;
                3493     for (i = list->nbItems; i > idx; i--)
                3494         list->items[i] = list->items[i-1];
                3495     list->items[idx] = item;
                3496     list->nbItems++;
                3497     }
                3498     return(0);
                3499 }
                3500 
                3501 #if 0 /* enable if ever needed */
                3502 static int
                3503 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
                3504                 int initialSize,
                3505                 void *item,
                3506                 int idx)
                3507 {
                3508     if (list->items == NULL) {
                3509     if (initialSize <= 0)
                3510         initialSize = 1;
                3511     list->items = (void **) xmlMalloc(
                3512         initialSize * sizeof(void *));
                3513     if (list->items == NULL) {
                3514         xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
                3515         return(-1);
                3516     }
                3517     list->sizeItems = initialSize;
                3518     } else if (list->sizeItems <= list->nbItems) {
                3519     list->sizeItems *= 2;
                3520     list->items = (void **) xmlRealloc(list->items,
                3521         list->sizeItems * sizeof(void *));
                3522     if (list->items == NULL) {
                3523         xmlSchemaPErrMemory(NULL, "growing item list", NULL);
                3524         list->sizeItems = 0;
                3525         return(-1);
                3526     }
                3527     }
                3528     /*
                3529     * Just append if the index is greater/equal than the item count.
                3530     */
                3531     if (idx >= list->nbItems) {
                3532     list->items[list->nbItems++] = item;
                3533     } else {
                3534     int i;
                3535     for (i = list->nbItems; i > idx; i--)
                3536         list->items[i] = list->items[i-1];
                3537     list->items[idx] = item;
                3538     list->nbItems++;
                3539     }
                3540     return(0);
                3541 }
                3542 #endif
                3543 
                3544 static int
                3545 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
                3546 {
                3547     int i;
                3548     if ((list->items == NULL) || (idx >= list->nbItems)) {
                3549     xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
                3550         "index error.\n");
                3551     return(-1);
                3552     }
                3553 
                3554     if (list->nbItems == 1) {
                3555     /* TODO: Really free the list? */
                3556     xmlFree(list->items);
                3557     list->items = NULL;
                3558     list->nbItems = 0;
                3559     list->sizeItems = 0;
                3560     } else if (list->nbItems -1 == idx) {
                3561     list->nbItems--;
                3562     } else {
                3563     for (i = idx; i < list->nbItems -1; i++)
                3564         list->items[i] = list->items[i+1];
                3565     list->nbItems--;
                3566     }
                3567     return(0);
                3568 }
                3569 
                3570 /**
                3571  * xmlSchemaItemListFree:
                3572  * @annot:  a schema type structure
                3573  *
                3574  * Deallocate a annotation structure
                3575  */
                3576 static void
                3577 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
                3578 {
                3579     if (list == NULL)
                3580     return;
                3581     if (list->items != NULL)
                3582     xmlFree(list->items);
                3583     xmlFree(list);
                3584 }
                3585 
                3586 static void
                3587 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
                3588 {
                3589     if (bucket == NULL)
                3590     return;
                3591     if (bucket->globals != NULL) {
                3592     xmlSchemaComponentListFree(bucket->globals);
                3593     xmlSchemaItemListFree(bucket->globals);
                3594     }
                3595     if (bucket->locals != NULL) {
                3596     xmlSchemaComponentListFree(bucket->locals);
                3597     xmlSchemaItemListFree(bucket->locals);
                3598     }
                3599     if (bucket->relations != NULL) {
                3600     xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
                3601     do {
                3602         prev = cur;
                3603         cur = cur->next;
                3604         xmlFree(prev);
                3605     } while (cur != NULL);
                3606     }
                3607     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
                3608     xmlFreeDoc(bucket->doc);
                3609     }
                3610     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
                3611     if (WXS_IMPBUCKET(bucket)->schema != NULL)
                3612         xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
                3613     }
                3614     xmlFree(bucket);
                3615 }
                3616 
                3617 static void
                3618 xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
                3619 {
                3620     xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
                3621 }
                3622 
                3623 static xmlSchemaBucketPtr
                3624 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
                3625              int type, const xmlChar *targetNamespace)
                3626 {
                3627     xmlSchemaBucketPtr ret;
                3628     int size;
                3629     xmlSchemaPtr mainSchema;
                3630 
                3631     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
                3632     PERROR_INT("xmlSchemaBucketCreate",
                3633         "no main schema on constructor");
                3634     return(NULL);
                3635     }
                3636     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
                3637     /* Create the schema bucket. */
                3638     if (WXS_IS_BUCKET_INCREDEF(type))
                3639     size = sizeof(xmlSchemaInclude);
                3640     else
                3641     size = sizeof(xmlSchemaImport);
                3642     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
                3643     if (ret == NULL) {
                3644     xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
                3645     return(NULL);
                3646     }
                3647     memset(ret, 0, size);
                3648     ret->targetNamespace = targetNamespace;
                3649     ret->type = type;
                3650     ret->globals = xmlSchemaItemListCreate();
                3651     if (ret->globals == NULL) {
ad7b9726c Alex*3652     xmlSchemaBucketFree(ret);
9d9d4fcc3 Alex*3653     return(NULL);
                3654     }
                3655     ret->locals = xmlSchemaItemListCreate();
                3656     if (ret->locals == NULL) {
ad7b9726c Alex*3657     xmlSchemaBucketFree(ret);
9d9d4fcc3 Alex*3658     return(NULL);
                3659     }
                3660     /*
                3661     * The following will assure that only the first bucket is marked as
                3662     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
                3663     * For each following import buckets an xmlSchema will be created.
                3664     * An xmlSchema will be created for every distinct targetNamespace.
                3665     * We assign the targetNamespace to the schemata here.
                3666     */
                3667     if (! WXS_HAS_BUCKETS(pctxt)) {
                3668     if (WXS_IS_BUCKET_INCREDEF(type)) {
                3669         PERROR_INT("xmlSchemaBucketCreate",
                3670         "first bucket but it's an include or redefine");
                3671         xmlSchemaBucketFree(ret);
                3672         return(NULL);
                3673     }
                3674     /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
                3675     ret->type = XML_SCHEMA_SCHEMA_MAIN;
                3676     /* Point to the *main* schema. */
                3677     WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
                3678     WXS_IMPBUCKET(ret)->schema = mainSchema;
                3679     /*
                3680     * Ensure that the main schema gets a targetNamespace.
                3681     */
                3682     mainSchema->targetNamespace = targetNamespace;
                3683     } else {
                3684     if (type == XML_SCHEMA_SCHEMA_MAIN) {
                3685         PERROR_INT("xmlSchemaBucketCreate",
                3686         "main bucket but it's not the first one");
                3687         xmlSchemaBucketFree(ret);
                3688         return(NULL);
                3689     } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
                3690         /*
                3691         * Create a schema for imports and assign the
                3692         * targetNamespace.
                3693         */
                3694         WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
                3695         if (WXS_IMPBUCKET(ret)->schema == NULL) {
                3696         xmlSchemaBucketFree(ret);
                3697         return(NULL);
                3698         }
                3699         WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
                3700     }
                3701     }
                3702     if (WXS_IS_BUCKET_IMPMAIN(type)) {
                3703     int res;
                3704     /*
                3705     * Imports go into the "schemasImports" slot of the main *schema*.
                3706     * Note that we create an import entry for the main schema as well; i.e.,
                3707     * even if there's only one schema, we'll get an import.
                3708     */
                3709     if (mainSchema->schemasImports == NULL) {
                3710         mainSchema->schemasImports = xmlHashCreateDict(5,
                3711         WXS_CONSTRUCTOR(pctxt)->dict);
                3712         if (mainSchema->schemasImports == NULL) {
                3713         xmlSchemaBucketFree(ret);
                3714         return(NULL);
                3715         }
                3716     }
                3717     if (targetNamespace == NULL)
                3718         res = xmlHashAddEntry(mainSchema->schemasImports,
                3719         XML_SCHEMAS_NO_NAMESPACE, ret);
                3720     else
                3721         res = xmlHashAddEntry(mainSchema->schemasImports,
                3722         targetNamespace, ret);
                3723     if (res != 0) {
                3724         PERROR_INT("xmlSchemaBucketCreate",
                3725         "failed to add the schema bucket to the hash");
                3726         xmlSchemaBucketFree(ret);
                3727         return(NULL);
                3728     }
                3729     } else {
                3730     /* Set the @ownerImport of an include bucket. */
                3731     if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
                3732         WXS_INCBUCKET(ret)->ownerImport =
                3733         WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
                3734     else
                3735         WXS_INCBUCKET(ret)->ownerImport =
                3736         WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
                3737 
                3738     /* Includes got into the "includes" slot of the *main* schema. */
                3739     if (mainSchema->includes == NULL) {
                3740         mainSchema->includes = xmlSchemaItemListCreate();
                3741         if (mainSchema->includes == NULL) {
                3742         xmlSchemaBucketFree(ret);
                3743         return(NULL);
                3744         }
                3745     }
ad7b9726c Alex*3746     if (xmlSchemaItemListAdd(mainSchema->includes, ret) < 0) {
                3747         xmlSchemaBucketFree(ret);
                3748         return(NULL);
                3749         }
9d9d4fcc3 Alex*3750     }
                3751     /*
                3752     * Add to list of all buckets; this is used for lookup
                3753     * during schema construction time only.
                3754     */
                3755     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
                3756     return(NULL);
                3757     return(ret);
                3758 }
                3759 
                3760 static int
                3761 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
                3762 {
                3763     if (*list == NULL) {
                3764     *list = xmlSchemaItemListCreate();
                3765     if (*list == NULL)
                3766         return(-1);
                3767     }
ad7b9726c Alex*3768     return(xmlSchemaItemListAddSize(*list, initialSize, item));
9d9d4fcc3 Alex*3769 }
                3770 
                3771 /**
                3772  * xmlSchemaFreeAnnot:
                3773  * @annot:  a schema type structure
                3774  *
                3775  * Deallocate a annotation structure
                3776  */
                3777 static void
                3778 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
                3779 {
                3780     if (annot == NULL)
                3781         return;
                3782     if (annot->next == NULL) {
                3783     xmlFree(annot);
                3784     } else {
                3785     xmlSchemaAnnotPtr prev;
                3786 
                3787     do {
                3788         prev = annot;
                3789         annot = annot->next;
                3790         xmlFree(prev);
                3791     } while (annot != NULL);
                3792     }
                3793 }
                3794 
                3795 /**
                3796  * xmlSchemaFreeNotation:
                3797  * @schema:  a schema notation structure
                3798  *
                3799  * Deallocate a Schema Notation structure.
                3800  */
                3801 static void
                3802 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
                3803 {
                3804     if (nota == NULL)
                3805         return;
                3806     xmlFree(nota);
                3807 }
                3808 
                3809 /**
                3810  * xmlSchemaFreeAttribute:
                3811  * @attr:  an attribute declaration
                3812  *
                3813  * Deallocates an attribute declaration structure.
                3814  */
                3815 static void
                3816 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
                3817 {
                3818     if (attr == NULL)
                3819         return;
                3820     if (attr->annot != NULL)
                3821     xmlSchemaFreeAnnot(attr->annot);
                3822     if (attr->defVal != NULL)
                3823     xmlSchemaFreeValue(attr->defVal);
                3824     xmlFree(attr);
                3825 }
                3826 
                3827 /**
                3828  * xmlSchemaFreeAttributeUse:
                3829  * @use:  an attribute use
                3830  *
                3831  * Deallocates an attribute use structure.
                3832  */
                3833 static void
                3834 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
                3835 {
                3836     if (use == NULL)
                3837         return;
                3838     if (use->annot != NULL)
                3839     xmlSchemaFreeAnnot(use->annot);
                3840     if (use->defVal != NULL)
                3841     xmlSchemaFreeValue(use->defVal);
                3842     xmlFree(use);
                3843 }
                3844 
                3845 /**
                3846  * xmlSchemaFreeAttributeUseProhib:
                3847  * @prohib:  an attribute use prohibition
                3848  *
                3849  * Deallocates an attribute use structure.
                3850  */
                3851 static void
                3852 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
                3853 {
                3854     if (prohib == NULL)
                3855         return;
                3856     xmlFree(prohib);
                3857 }
                3858 
                3859 /**
                3860  * xmlSchemaFreeWildcardNsSet:
                3861  * set:  a schema wildcard namespace
                3862  *
                3863  * Deallocates a list of wildcard constraint structures.
                3864  */
                3865 static void
                3866 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
                3867 {
                3868     xmlSchemaWildcardNsPtr next;
                3869 
                3870     while (set != NULL) {
                3871     next = set->next;
                3872     xmlFree(set);
                3873     set = next;
                3874     }
                3875 }
                3876 
                3877 /**
                3878  * xmlSchemaFreeWildcard:
                3879  * @wildcard:  a wildcard structure
                3880  *
                3881  * Deallocates a wildcard structure.
                3882  */
                3883 void
                3884 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
                3885 {
                3886     if (wildcard == NULL)
                3887         return;
                3888     if (wildcard->annot != NULL)
                3889         xmlSchemaFreeAnnot(wildcard->annot);
                3890     if (wildcard->nsSet != NULL)
                3891     xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
                3892     if (wildcard->negNsSet != NULL)
                3893     xmlFree(wildcard->negNsSet);
                3894     xmlFree(wildcard);
                3895 }
                3896 
                3897 /**
                3898  * xmlSchemaFreeAttributeGroup:
                3899  * @schema:  a schema attribute group structure
                3900  *
                3901  * Deallocate a Schema Attribute Group structure.
                3902  */
                3903 static void
                3904 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
                3905 {
                3906     if (attrGr == NULL)
                3907         return;
                3908     if (attrGr->annot != NULL)
                3909         xmlSchemaFreeAnnot(attrGr->annot);
                3910     if (attrGr->attrUses != NULL)
                3911     xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
                3912     xmlFree(attrGr);
                3913 }
                3914 
                3915 /**
                3916  * xmlSchemaFreeQNameRef:
                3917  * @item: a QName reference structure
                3918  *
                3919  * Deallocatea a QName reference structure.
                3920  */
                3921 static void
                3922 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
                3923 {
                3924     xmlFree(item);
                3925 }
                3926 
                3927 /**
                3928  * xmlSchemaFreeTypeLinkList:
                3929  * @alink: a type link
                3930  *
                3931  * Deallocate a list of types.
                3932  */
                3933 static void
                3934 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
                3935 {
                3936     xmlSchemaTypeLinkPtr next;
                3937 
                3938     while (link != NULL) {
                3939     next = link->next;
                3940     xmlFree(link);
                3941     link = next;
                3942     }
                3943 }
                3944 
                3945 static void
                3946 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
                3947 {
                3948     xmlSchemaIDCStateObjPtr next;
                3949     while (sto != NULL) {
                3950     next = sto->next;
                3951     if (sto->history != NULL)
                3952         xmlFree(sto->history);
                3953     if (sto->xpathCtxt != NULL)
                3954         xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
                3955     xmlFree(sto);
                3956     sto = next;
                3957     }
                3958 }
                3959 
                3960 /**
                3961  * xmlSchemaFreeIDC:
                3962  * @idc: a identity-constraint definition
                3963  *
                3964  * Deallocates an identity-constraint definition.
                3965  */
                3966 static void
                3967 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
                3968 {
                3969     xmlSchemaIDCSelectPtr cur, prev;
                3970 
                3971     if (idcDef == NULL)
                3972     return;
                3973     if (idcDef->annot != NULL)
                3974         xmlSchemaFreeAnnot(idcDef->annot);
                3975     /* Selector */
                3976     if (idcDef->selector != NULL) {
                3977     if (idcDef->selector->xpathComp != NULL)
                3978         xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
                3979     xmlFree(idcDef->selector);
                3980     }
                3981     /* Fields */
                3982     if (idcDef->fields != NULL) {
                3983     cur = idcDef->fields;
                3984     do {
                3985         prev = cur;
                3986         cur = cur->next;
                3987         if (prev->xpathComp != NULL)
                3988         xmlFreePattern((xmlPatternPtr) prev->xpathComp);
                3989         xmlFree(prev);
                3990     } while (cur != NULL);
                3991     }
                3992     xmlFree(idcDef);
                3993 }
                3994 
                3995 /**
                3996  * xmlSchemaFreeElement:
                3997  * @schema:  a schema element structure
                3998  *
                3999  * Deallocate a Schema Element structure.
                4000  */
                4001 static void
                4002 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
                4003 {
                4004     if (elem == NULL)
                4005         return;
                4006     if (elem->annot != NULL)
                4007         xmlSchemaFreeAnnot(elem->annot);
                4008     if (elem->contModel != NULL)
                4009         xmlRegFreeRegexp(elem->contModel);
                4010     if (elem->defVal != NULL)
                4011     xmlSchemaFreeValue(elem->defVal);
                4012     xmlFree(elem);
                4013 }
                4014 
                4015 /**
                4016  * xmlSchemaFreeFacet:
                4017  * @facet:  a schema facet structure
                4018  *
                4019  * Deallocate a Schema Facet structure.
                4020  */
                4021 void
                4022 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
                4023 {
                4024     if (facet == NULL)
                4025         return;
                4026     if (facet->val != NULL)
                4027         xmlSchemaFreeValue(facet->val);
                4028     if (facet->regexp != NULL)
                4029         xmlRegFreeRegexp(facet->regexp);
                4030     if (facet->annot != NULL)
                4031         xmlSchemaFreeAnnot(facet->annot);
                4032     xmlFree(facet);
                4033 }
                4034 
                4035 /**
                4036  * xmlSchemaFreeType:
                4037  * @type:  a schema type structure
                4038  *
                4039  * Deallocate a Schema Type structure.
                4040  */
                4041 void
                4042 xmlSchemaFreeType(xmlSchemaTypePtr type)
                4043 {
                4044     if (type == NULL)
                4045         return;
                4046     if (type->annot != NULL)
                4047         xmlSchemaFreeAnnot(type->annot);
                4048     if (type->facets != NULL) {
                4049         xmlSchemaFacetPtr facet, next;
                4050 
                4051         facet = type->facets;
                4052         while (facet != NULL) {
                4053             next = facet->next;
                4054             xmlSchemaFreeFacet(facet);
                4055             facet = next;
                4056         }
                4057     }
                4058     if (type->attrUses != NULL)
                4059     xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
                4060     if (type->memberTypes != NULL)
                4061     xmlSchemaFreeTypeLinkList(type->memberTypes);
                4062     if (type->facetSet != NULL) {
                4063     xmlSchemaFacetLinkPtr next, link;
                4064 
                4065     link = type->facetSet;
                4066     do {
                4067         next = link->next;
                4068         xmlFree(link);
                4069         link = next;
                4070     } while (link != NULL);
                4071     }
                4072     if (type->contModel != NULL)
                4073         xmlRegFreeRegexp(type->contModel);
                4074     xmlFree(type);
                4075 }
                4076 
                4077 /**
                4078  * xmlSchemaFreeModelGroupDef:
                4079  * @item:  a schema model group definition
                4080  *
                4081  * Deallocates a schema model group definition.
                4082  */
                4083 static void
                4084 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
                4085 {
                4086     if (item->annot != NULL)
                4087     xmlSchemaFreeAnnot(item->annot);
                4088     xmlFree(item);
                4089 }
                4090 
                4091 /**
                4092  * xmlSchemaFreeModelGroup:
                4093  * @item:  a schema model group
                4094  *
                4095  * Deallocates a schema model group structure.
                4096  */
                4097 static void
                4098 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
                4099 {
                4100     if (item->annot != NULL)
                4101     xmlSchemaFreeAnnot(item->annot);
                4102     xmlFree(item);
                4103 }
                4104 
                4105 static void
                4106 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
                4107 {
                4108     if ((list == NULL) || (list->nbItems == 0))
                4109     return;
                4110     {
                4111     xmlSchemaTreeItemPtr item;
                4112     xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
                4113     int i;
                4114 
                4115     for (i = 0; i < list->nbItems; i++) {
                4116         item = items[i];
                4117         if (item == NULL)
                4118         continue;
                4119         switch (item->type) {
                4120         case XML_SCHEMA_TYPE_SIMPLE:
                4121         case XML_SCHEMA_TYPE_COMPLEX:
                4122             xmlSchemaFreeType((xmlSchemaTypePtr) item);
                4123             break;
                4124         case XML_SCHEMA_TYPE_ATTRIBUTE:
                4125             xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
                4126             break;
                4127         case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                4128             xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
                4129             break;
                4130         case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
                4131             xmlSchemaFreeAttributeUseProhib(
                4132             (xmlSchemaAttributeUseProhibPtr) item);
                4133             break;
                4134         case XML_SCHEMA_TYPE_ELEMENT:
                4135             xmlSchemaFreeElement((xmlSchemaElementPtr) item);
                4136             break;
                4137         case XML_SCHEMA_TYPE_PARTICLE:
                4138             if (item->annot != NULL)
                4139             xmlSchemaFreeAnnot(item->annot);
                4140             xmlFree(item);
                4141             break;
                4142         case XML_SCHEMA_TYPE_SEQUENCE:
                4143         case XML_SCHEMA_TYPE_CHOICE:
                4144         case XML_SCHEMA_TYPE_ALL:
                4145             xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
                4146             break;
                4147         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                4148             xmlSchemaFreeAttributeGroup(
                4149             (xmlSchemaAttributeGroupPtr) item);
                4150             break;
                4151         case XML_SCHEMA_TYPE_GROUP:
                4152             xmlSchemaFreeModelGroupDef(
                4153             (xmlSchemaModelGroupDefPtr) item);
                4154             break;
                4155         case XML_SCHEMA_TYPE_ANY:
                4156         case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
                4157             xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
                4158             break;
                4159         case XML_SCHEMA_TYPE_IDC_KEY:
                4160         case XML_SCHEMA_TYPE_IDC_UNIQUE:
                4161         case XML_SCHEMA_TYPE_IDC_KEYREF:
                4162             xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
                4163             break;
                4164         case XML_SCHEMA_TYPE_NOTATION:
                4165             xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
                4166             break;
                4167         case XML_SCHEMA_EXTRA_QNAMEREF:
                4168             xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
                4169             break;
                4170         default: {
                4171             /* TODO: This should never be hit. */
                4172             xmlSchemaPSimpleInternalErr(NULL,
                4173             "Internal error: xmlSchemaComponentListFree, "
                4174             "unexpected component type '%s'\n",
                4175             (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
                4176              }
                4177             break;
                4178         }
                4179     }
                4180     list->nbItems = 0;
                4181     }
                4182 }
                4183 
                4184 /**
                4185  * xmlSchemaFree:
                4186  * @schema:  a schema structure
                4187  *
                4188  * Deallocate a Schema structure.
                4189  */
                4190 void
                4191 xmlSchemaFree(xmlSchemaPtr schema)
                4192 {
                4193     if (schema == NULL)
                4194         return;
                4195     /* @volatiles is not used anymore :-/ */
                4196     if (schema->volatiles != NULL)
                4197     TODO
                4198     /*
                4199     * Note that those slots are not responsible for freeing
                4200     * schema components anymore; this will now be done by
                4201     * the schema buckets.
                4202     */
                4203     if (schema->notaDecl != NULL)
                4204         xmlHashFree(schema->notaDecl, NULL);
                4205     if (schema->attrDecl != NULL)
                4206         xmlHashFree(schema->attrDecl, NULL);
                4207     if (schema->attrgrpDecl != NULL)
                4208         xmlHashFree(schema->attrgrpDecl, NULL);
                4209     if (schema->elemDecl != NULL)
                4210         xmlHashFree(schema->elemDecl, NULL);
                4211     if (schema->typeDecl != NULL)
                4212         xmlHashFree(schema->typeDecl, NULL);
                4213     if (schema->groupDecl != NULL)
                4214         xmlHashFree(schema->groupDecl, NULL);
                4215     if (schema->idcDef != NULL)
                4216         xmlHashFree(schema->idcDef, NULL);
                4217 
                4218     if (schema->schemasImports != NULL)
                4219     xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
                4220     if (schema->includes != NULL) {
                4221     xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
                4222     int i;
                4223     for (i = 0; i < list->nbItems; i++) {
                4224         xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
                4225     }
                4226     xmlSchemaItemListFree(list);
                4227     }
                4228     if (schema->annot != NULL)
                4229         xmlSchemaFreeAnnot(schema->annot);
                4230     /* Never free the doc here, since this will be done by the buckets. */
                4231 
                4232     xmlDictFree(schema->dict);
                4233     xmlFree(schema);
                4234 }
                4235 
                4236 /************************************************************************
                4237  *                                  *
                4238  *          Debug functions                 *
                4239  *                                  *
                4240  ************************************************************************/
                4241 
                4242 #ifdef LIBXML_OUTPUT_ENABLED
                4243 
                4244 static void
                4245 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
                4246 
                4247 /**
                4248  * xmlSchemaElementDump:
                4249  * @elem:  an element
                4250  * @output:  the file output
                4251  *
                4252  * Dump the element
                4253  */
                4254 static void
                4255 xmlSchemaElementDump(void *payload, void *data,
                4256                      const xmlChar * name ATTRIBUTE_UNUSED,
                4257              const xmlChar * namespace ATTRIBUTE_UNUSED,
                4258                      const xmlChar * context ATTRIBUTE_UNUSED)
                4259 {
                4260     xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
                4261     FILE *output = (FILE *) data;
                4262     if (elem == NULL)
                4263         return;
                4264 
                4265 
                4266     fprintf(output, "Element");
                4267     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
                4268     fprintf(output, " (global)");
                4269     fprintf(output, ": '%s' ", elem->name);
                4270     if (namespace != NULL)
                4271     fprintf(output, "ns '%s'", namespace);
                4272     fprintf(output, "\n");
                4273 #if 0
                4274     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
                4275     fprintf(output, "  min %d ", elem->minOccurs);
                4276         if (elem->maxOccurs >= UNBOUNDED)
                4277             fprintf(output, "max: unbounded\n");
                4278         else if (elem->maxOccurs != 1)
                4279             fprintf(output, "max: %d\n", elem->maxOccurs);
                4280         else
                4281             fprintf(output, "\n");
                4282     }
                4283 #endif
                4284     /*
                4285     * Misc other properties.
                4286     */
                4287     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
                4288     (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
                4289     (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
                4290     (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
                4291     fprintf(output, "  props: ");
                4292     if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
                4293         fprintf(output, "[fixed] ");
                4294     if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
                4295         fprintf(output, "[default] ");
                4296     if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
                4297         fprintf(output, "[abstract] ");
                4298     if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
                4299         fprintf(output, "[nillable] ");
                4300     fprintf(output, "\n");
                4301     }
                4302     /*
                4303     * Default/fixed value.
                4304     */
                4305     if (elem->value != NULL)
                4306     fprintf(output, "  value: '%s'\n", elem->value);
                4307     /*
                4308     * Type.
                4309     */
                4310     if (elem->namedType != NULL) {
                4311     fprintf(output, "  type: '%s' ", elem->namedType);
                4312     if (elem->namedTypeNs != NULL)
                4313         fprintf(output, "ns '%s'\n", elem->namedTypeNs);
                4314     else
                4315         fprintf(output, "\n");
                4316     } else if (elem->subtypes != NULL) {
                4317     /*
                4318     * Dump local types.
                4319     */
                4320     xmlSchemaTypeDump(elem->subtypes, output);
                4321     }
                4322     /*
                4323     * Substitution group.
                4324     */
                4325     if (elem->substGroup != NULL) {
                4326     fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
                4327     if (elem->substGroupNs != NULL)
                4328         fprintf(output, "ns '%s'\n", elem->substGroupNs);
                4329     else
                4330         fprintf(output, "\n");
                4331     }
                4332 }
                4333 
                4334 /**
                4335  * xmlSchemaAnnotDump:
                4336  * @output:  the file output
                4337  * @annot:  a annotation
                4338  *
                4339  * Dump the annotation
                4340  */
                4341 static void
                4342 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
                4343 {
                4344     xmlChar *content;
                4345 
                4346     if (annot == NULL)
                4347         return;
                4348 
                4349     content = xmlNodeGetContent(annot->content);
                4350     if (content != NULL) {
                4351         fprintf(output, "  Annot: %s\n", content);
                4352         xmlFree(content);
                4353     } else
                4354         fprintf(output, "  Annot: empty\n");
                4355 }
                4356 
                4357 /**
                4358  * xmlSchemaContentModelDump:
                4359  * @particle: the schema particle
                4360  * @output: the file output
                4361  * @depth: the depth used for indentation
                4362  *
                4363  * Dump a SchemaType structure
                4364  */
                4365 static void
                4366 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
                4367 {
                4368     xmlChar *str = NULL;
                4369     xmlSchemaTreeItemPtr term;
                4370     char shift[100];
                4371     int i;
                4372 
                4373     if (particle == NULL)
                4374     return;
                4375     for (i = 0;((i < depth) && (i < 25));i++)
                4376         shift[2 * i] = shift[2 * i + 1] = ' ';
                4377     shift[2 * i] = shift[2 * i + 1] = 0;
                4378     fprintf(output, "%s", shift);
                4379     if (particle->children == NULL) {
                4380     fprintf(output, "MISSING particle term\n");
                4381     return;
                4382     }
                4383     term = particle->children;
                4384     if (term == NULL) {
                4385     fprintf(output, "(NULL)");
                4386     } else {
                4387     switch (term->type) {
                4388         case XML_SCHEMA_TYPE_ELEMENT:
                4389         fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
                4390             ((xmlSchemaElementPtr)term)->targetNamespace,
                4391             ((xmlSchemaElementPtr)term)->name));
                4392         FREE_AND_NULL(str);
                4393         break;
                4394         case XML_SCHEMA_TYPE_SEQUENCE:
                4395         fprintf(output, "SEQUENCE");
                4396         break;
                4397         case XML_SCHEMA_TYPE_CHOICE:
                4398         fprintf(output, "CHOICE");
                4399         break;
                4400         case XML_SCHEMA_TYPE_ALL:
                4401         fprintf(output, "ALL");
                4402         break;
                4403         case XML_SCHEMA_TYPE_ANY:
                4404         fprintf(output, "ANY");
                4405         break;
                4406         default:
                4407         fprintf(output, "UNKNOWN\n");
                4408         return;
                4409     }
                4410     }
                4411     if (particle->minOccurs != 1)
                4412     fprintf(output, " min: %d", particle->minOccurs);
                4413     if (particle->maxOccurs >= UNBOUNDED)
                4414     fprintf(output, " max: unbounded");
                4415     else if (particle->maxOccurs != 1)
                4416     fprintf(output, " max: %d", particle->maxOccurs);
                4417     fprintf(output, "\n");
                4418     if (term &&
                4419     ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
                4420      (term->type == XML_SCHEMA_TYPE_CHOICE) ||
                4421      (term->type == XML_SCHEMA_TYPE_ALL)) &&
                4422      (term->children != NULL)) {
                4423     xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
                4424         output, depth +1);
                4425     }
                4426     if (particle->next != NULL)
                4427     xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
                4428         output, depth);
                4429 }
                4430 
                4431 /**
                4432  * xmlSchemaAttrUsesDump:
                4433  * @uses:  attribute uses list
                4434  * @output:  the file output
                4435  *
                4436  * Dumps a list of attribute use components.
                4437  */
                4438 static void
                4439 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
                4440 {
                4441     xmlSchemaAttributeUsePtr use;
                4442     xmlSchemaAttributeUseProhibPtr prohib;
                4443     xmlSchemaQNameRefPtr ref;
                4444     const xmlChar *name, *tns;
                4445     xmlChar *str = NULL;
                4446     int i;
                4447 
                4448     if ((uses == NULL) || (uses->nbItems == 0))
                4449         return;
                4450 
                4451     fprintf(output, "  attributes:\n");
                4452     for (i = 0; i < uses->nbItems; i++) {
                4453     use = uses->items[i];
                4454     if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
                4455         fprintf(output, "  [prohibition] ");
                4456         prohib = (xmlSchemaAttributeUseProhibPtr) use;
                4457         name = prohib->name;
                4458         tns = prohib->targetNamespace;
                4459     } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
                4460         fprintf(output, "  [reference] ");
                4461         ref = (xmlSchemaQNameRefPtr) use;
                4462         name = ref->name;
                4463         tns = ref->targetNamespace;
                4464     } else {
                4465         fprintf(output, "  [use] ");
                4466         name = WXS_ATTRUSE_DECL_NAME(use);
                4467         tns = WXS_ATTRUSE_DECL_TNS(use);
                4468     }
                4469     fprintf(output, "'%s'\n",
                4470         (const char *) xmlSchemaFormatQName(&str, tns, name));
                4471     FREE_AND_NULL(str);
                4472     }
                4473 }
                4474 
                4475 /**
                4476  * xmlSchemaTypeDump:
                4477  * @output:  the file output
                4478  * @type:  a type structure
                4479  *
                4480  * Dump a SchemaType structure
                4481  */
                4482 static void
                4483 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
                4484 {
                4485     if (type == NULL) {
                4486         fprintf(output, "Type: NULL\n");
                4487         return;
                4488     }
                4489     fprintf(output, "Type: ");
                4490     if (type->name != NULL)
                4491         fprintf(output, "'%s' ", type->name);
                4492     else
                4493         fprintf(output, "(no name) ");
                4494     if (type->targetNamespace != NULL)
                4495     fprintf(output, "ns '%s' ", type->targetNamespace);
                4496     switch (type->type) {
                4497         case XML_SCHEMA_TYPE_BASIC:
                4498             fprintf(output, "[basic] ");
                4499             break;
                4500         case XML_SCHEMA_TYPE_SIMPLE:
                4501             fprintf(output, "[simple] ");
                4502             break;
                4503         case XML_SCHEMA_TYPE_COMPLEX:
                4504             fprintf(output, "[complex] ");
                4505             break;
                4506         case XML_SCHEMA_TYPE_SEQUENCE:
                4507             fprintf(output, "[sequence] ");
                4508             break;
                4509         case XML_SCHEMA_TYPE_CHOICE:
                4510             fprintf(output, "[choice] ");
                4511             break;
                4512         case XML_SCHEMA_TYPE_ALL:
                4513             fprintf(output, "[all] ");
                4514             break;
                4515         case XML_SCHEMA_TYPE_UR:
                4516             fprintf(output, "[ur] ");
                4517             break;
                4518         case XML_SCHEMA_TYPE_RESTRICTION:
                4519             fprintf(output, "[restriction] ");
                4520             break;
                4521         case XML_SCHEMA_TYPE_EXTENSION:
                4522             fprintf(output, "[extension] ");
                4523             break;
                4524         default:
                4525             fprintf(output, "[unknown type %d] ", type->type);
                4526             break;
                4527     }
                4528     fprintf(output, "content: ");
                4529     switch (type->contentType) {
                4530         case XML_SCHEMA_CONTENT_UNKNOWN:
                4531             fprintf(output, "[unknown] ");
                4532             break;
                4533         case XML_SCHEMA_CONTENT_EMPTY:
                4534             fprintf(output, "[empty] ");
                4535             break;
                4536         case XML_SCHEMA_CONTENT_ELEMENTS:
                4537             fprintf(output, "[element] ");
                4538             break;
                4539         case XML_SCHEMA_CONTENT_MIXED:
                4540             fprintf(output, "[mixed] ");
                4541             break;
                4542         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
                4543     /* not used. */
                4544             break;
                4545         case XML_SCHEMA_CONTENT_BASIC:
                4546             fprintf(output, "[basic] ");
                4547             break;
                4548         case XML_SCHEMA_CONTENT_SIMPLE:
                4549             fprintf(output, "[simple] ");
                4550             break;
                4551         case XML_SCHEMA_CONTENT_ANY:
                4552             fprintf(output, "[any] ");
                4553             break;
                4554     }
                4555     fprintf(output, "\n");
                4556     if (type->base != NULL) {
                4557         fprintf(output, "  base type: '%s'", type->base);
                4558     if (type->baseNs != NULL)
                4559         fprintf(output, " ns '%s'\n", type->baseNs);
                4560     else
                4561         fprintf(output, "\n");
                4562     }
                4563     if (type->attrUses != NULL)
                4564     xmlSchemaAttrUsesDump(type->attrUses, output);
                4565     if (type->annot != NULL)
                4566         xmlSchemaAnnotDump(output, type->annot);
                4567 #ifdef DUMP_CONTENT_MODEL
                4568     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
                4569     (type->subtypes != NULL)) {
                4570     xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
                4571         output, 1);
                4572     }
                4573 #endif
                4574 }
                4575 
                4576 static void
                4577 xmlSchemaTypeDumpEntry(void *type, void *output,
                4578                        const xmlChar *name ATTRIBUTE_UNUSED)
                4579 {
                4580     xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
                4581 }
                4582 
                4583 /**
                4584  * xmlSchemaDump:
                4585  * @output:  the file output
                4586  * @schema:  a schema structure
                4587  *
                4588  * Dump a Schema structure.
                4589  */
                4590 void
                4591 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
                4592 {
                4593     if (output == NULL)
                4594         return;
                4595     if (schema == NULL) {
                4596         fprintf(output, "Schemas: NULL\n");
                4597         return;
                4598     }
                4599     fprintf(output, "Schemas: ");
                4600     if (schema->name != NULL)
                4601         fprintf(output, "%s, ", schema->name);
                4602     else
                4603         fprintf(output, "no name, ");
                4604     if (schema->targetNamespace != NULL)
                4605         fprintf(output, "%s", (const char *) schema->targetNamespace);
                4606     else
                4607         fprintf(output, "no target namespace");
                4608     fprintf(output, "\n");
                4609     if (schema->annot != NULL)
                4610         xmlSchemaAnnotDump(output, schema->annot);
                4611     xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
                4612     xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
                4613 }
                4614 
                4615 #ifdef DEBUG_IDC_NODE_TABLE
                4616 /**
                4617  * xmlSchemaDebugDumpIDCTable:
                4618  * @vctxt: the WXS validation context
                4619  *
                4620  * Displays the current IDC table for debug purposes.
                4621  */
                4622 static void
                4623 xmlSchemaDebugDumpIDCTable(FILE * output,
                4624                const xmlChar *namespaceName,
                4625                const xmlChar *localName,
                4626                xmlSchemaPSVIIDCBindingPtr bind)
                4627 {
                4628     xmlChar *str = NULL;
                4629     const xmlChar *value;
                4630     xmlSchemaPSVIIDCNodePtr tab;
                4631     xmlSchemaPSVIIDCKeyPtr key;
                4632     int i, j, res;
                4633 
                4634     fprintf(output, "IDC: TABLES on '%s'\n",
                4635     xmlSchemaFormatQName(&str, namespaceName, localName));
                4636     FREE_AND_NULL(str)
                4637 
                4638     if (bind == NULL)
                4639     return;
                4640     do {
                4641     fprintf(output, "IDC:   BINDING '%s' (%d)\n",
                4642         xmlSchemaGetComponentQName(&str,
                4643         bind->definition), bind->nbNodes);
                4644     FREE_AND_NULL(str)
                4645     for (i = 0; i < bind->nbNodes; i++) {
                4646         tab = bind->nodeTable[i];
                4647         fprintf(output, "         ( ");
                4648         for (j = 0; j < bind->definition->nbFields; j++) {
                4649         key = tab->keys[j];
                4650         if ((key != NULL) && (key->val != NULL)) {
                4651             res = xmlSchemaGetCanonValue(key->val, &value);
                4652             if (res >= 0)
                4653             fprintf(output, "'%s' ", value);
                4654             else
                4655             fprintf(output, "CANON-VALUE-FAILED ");
                4656             if (res == 0)
                4657             FREE_AND_NULL(value)
                4658         } else if (key != NULL)
                4659             fprintf(output, "(no val), ");
                4660         else
                4661             fprintf(output, "(key missing), ");
                4662         }
                4663         fprintf(output, ")\n");
                4664     }
                4665     if (bind->dupls && bind->dupls->nbItems) {
                4666         fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
                4667         for (i = 0; i < bind->dupls->nbItems; i++) {
                4668         tab = bind->dupls->items[i];
                4669         fprintf(output, "         ( ");
                4670         for (j = 0; j < bind->definition->nbFields; j++) {
                4671             key = tab->keys[j];
                4672             if ((key != NULL) && (key->val != NULL)) {
                4673             res = xmlSchemaGetCanonValue(key->val, &value);
                4674             if (res >= 0)
                4675                 fprintf(output, "'%s' ", value);
                4676             else
                4677                 fprintf(output, "CANON-VALUE-FAILED ");
                4678             if (res == 0)
                4679                 FREE_AND_NULL(value)
                4680             } else if (key != NULL)
                4681             fprintf(output, "(no val), ");
                4682             else
                4683                 fprintf(output, "(key missing), ");
                4684         }
                4685         fprintf(output, ")\n");
                4686         }
                4687     }
                4688     bind = bind->next;
                4689     } while (bind != NULL);
                4690 }
                4691 #endif /* DEBUG_IDC */
                4692 #endif /* LIBXML_OUTPUT_ENABLED */
                4693 
                4694 /************************************************************************
                4695  *                                  *
                4696  *          Utilities                   *
                4697  *                                  *
                4698  ************************************************************************/
                4699 
                4700 /**
                4701  * xmlSchemaGetPropNode:
                4702  * @node: the element node
                4703  * @name: the name of the attribute
                4704  *
                4705  * Seeks an attribute with a name of @name in
                4706  * no namespace.
                4707  *
                4708  * Returns the attribute or NULL if not present.
                4709  */
                4710 static xmlAttrPtr
                4711 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
                4712 {
                4713     xmlAttrPtr prop;
                4714 
                4715     if ((node == NULL) || (name == NULL))
                4716     return(NULL);
                4717     prop = node->properties;
                4718     while (prop != NULL) {
                4719         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
                4720         return(prop);
                4721     prop = prop->next;
                4722     }
                4723     return (NULL);
                4724 }
                4725 
                4726 /**
                4727  * xmlSchemaGetPropNodeNs:
                4728  * @node: the element node
                4729  * @uri: the uri
                4730  * @name: the name of the attribute
                4731  *
                4732  * Seeks an attribute with a local name of @name and
                4733  * a namespace URI of @uri.
                4734  *
                4735  * Returns the attribute or NULL if not present.
                4736  */
                4737 static xmlAttrPtr
                4738 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
                4739 {
                4740     xmlAttrPtr prop;
                4741 
                4742     if ((node == NULL) || (name == NULL))
                4743     return(NULL);
                4744     prop = node->properties;
                4745     while (prop != NULL) {
                4746     if ((prop->ns != NULL) &&
                4747         xmlStrEqual(prop->name, BAD_CAST name) &&
                4748         xmlStrEqual(prop->ns->href, BAD_CAST uri))
                4749         return(prop);
                4750     prop = prop->next;
                4751     }
                4752     return (NULL);
                4753 }
                4754 
                4755 static const xmlChar *
                4756 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
                4757 {
                4758     xmlChar *val;
                4759     const xmlChar *ret;
                4760 
                4761     val = xmlNodeGetContent(node);
                4762     if (val == NULL)
                4763     val = xmlStrdup((xmlChar *)"");
                4764     ret = xmlDictLookup(ctxt->dict, val, -1);
                4765     xmlFree(val);
ad7b9726c Alex*4766     if (ret == NULL)
                4767         xmlSchemaPErrMemory(ctxt, "getting node content", node);
9d9d4fcc3 Alex*4768     return(ret);
                4769 }
                4770 
                4771 static const xmlChar *
                4772 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
                4773 {
                4774     return((const xmlChar*) xmlNodeGetContent(node));
                4775 }
                4776 
                4777 /**
                4778  * xmlSchemaGetProp:
                4779  * @ctxt: the parser context
                4780  * @node: the node
                4781  * @name: the property name
                4782  *
                4783  * Read a attribute value and internalize the string
                4784  *
                4785  * Returns the string or NULL if not present.
                4786  */
                4787 static const xmlChar *
                4788 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                4789                  const char *name)
                4790 {
                4791     xmlChar *val;
                4792     const xmlChar *ret;
                4793 
                4794     val = xmlGetNoNsProp(node, BAD_CAST name);
                4795     if (val == NULL)
                4796         return(NULL);
                4797     ret = xmlDictLookup(ctxt->dict, val, -1);
                4798     xmlFree(val);
                4799     return(ret);
                4800 }
                4801 
                4802 /************************************************************************
                4803  *                                  *
                4804  *          Parsing functions               *
                4805  *                                  *
                4806  ************************************************************************/
                4807 
                4808 #define WXS_FIND_GLOBAL_ITEM(slot)          \
                4809     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
                4810     ret = xmlHashLookup(schema->slot, name); \
                4811     if (ret != NULL) goto exit; \
                4812     } \
                4813     if (xmlHashSize(schema->schemasImports) > 1) { \
                4814     xmlSchemaImportPtr import; \
                4815     if (nsName == NULL) \
                4816         import = xmlHashLookup(schema->schemasImports, \
                4817         XML_SCHEMAS_NO_NAMESPACE); \
                4818     else \
                4819         import = xmlHashLookup(schema->schemasImports, nsName); \
                4820     if (import == NULL) \
                4821         goto exit; \
                4822     ret = xmlHashLookup(import->schema->slot, name); \
                4823     }
                4824 
                4825 /**
                4826  * xmlSchemaGetElem:
                4827  * @schema:  the schema context
                4828  * @name:  the element name
                4829  * @ns:  the element namespace
                4830  *
                4831  * Lookup a global element declaration in the schema.
                4832  *
                4833  * Returns the element declaration or NULL if not found.
                4834  */
                4835 static xmlSchemaElementPtr
                4836 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
                4837                  const xmlChar * nsName)
                4838 {
                4839     xmlSchemaElementPtr ret = NULL;
                4840 
                4841     if ((name == NULL) || (schema == NULL))
                4842         return(NULL);
                4843     if (schema != NULL) {
                4844     WXS_FIND_GLOBAL_ITEM(elemDecl)
                4845     }
                4846 exit:
                4847 #ifdef DEBUG
                4848     if (ret == NULL) {
                4849         if (nsName == NULL)
                4850             fprintf(stderr, "Unable to lookup element decl. %s", name);
                4851         else
                4852             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
                4853                     nsName);
                4854     }
                4855 #endif
                4856     return (ret);
                4857 }
                4858 
                4859 /**
                4860  * xmlSchemaGetType:
                4861  * @schema:  the main schema
                4862  * @name:  the type's name
                4863  * nsName:  the type's namespace
                4864  *
                4865  * Lookup a type in the schemas or the predefined types
                4866  *
                4867  * Returns the group definition or NULL if not found.
                4868  */
                4869 static xmlSchemaTypePtr
                4870 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
                4871                  const xmlChar * nsName)
                4872 {
                4873     xmlSchemaTypePtr ret = NULL;
                4874 
                4875     if (name == NULL)
                4876         return (NULL);
                4877     /* First try the built-in types. */
                4878     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
                4879     ret = xmlSchemaGetPredefinedType(name, nsName);
                4880     if (ret != NULL)
                4881         goto exit;
                4882     /*
                4883     * Note that we try the parsed schemas as well here
                4884     * since one might have parsed the S4S, which contain more
                4885     * than the built-in types.
                4886     * TODO: Can we optimize this?
                4887     */
                4888     }
                4889     if (schema != NULL) {
                4890     WXS_FIND_GLOBAL_ITEM(typeDecl)
                4891     }
                4892 exit:
                4893 
                4894 #ifdef DEBUG
                4895     if (ret == NULL) {
                4896         if (nsName == NULL)
                4897             fprintf(stderr, "Unable to lookup type %s", name);
                4898         else
                4899             fprintf(stderr, "Unable to lookup type %s:%s", name,
                4900                     nsName);
                4901     }
                4902 #endif
                4903     return (ret);
                4904 }
                4905 
                4906 /**
                4907  * xmlSchemaGetAttributeDecl:
                4908  * @schema:  the context of the schema
                4909  * @name:  the name of the attribute
                4910  * @ns:  the target namespace of the attribute
                4911  *
                4912  * Lookup a an attribute in the schema or imported schemas
                4913  *
                4914  * Returns the attribute declaration or NULL if not found.
                4915  */
                4916 static xmlSchemaAttributePtr
                4917 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
                4918                  const xmlChar * nsName)
                4919 {
                4920     xmlSchemaAttributePtr ret = NULL;
                4921 
                4922     if ((name == NULL) || (schema == NULL))
                4923         return (NULL);
                4924     if (schema != NULL) {
                4925     WXS_FIND_GLOBAL_ITEM(attrDecl)
                4926     }
                4927 exit:
                4928 #ifdef DEBUG
                4929     if (ret == NULL) {
                4930         if (nsName == NULL)
                4931             fprintf(stderr, "Unable to lookup attribute %s", name);
                4932         else
                4933             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
                4934                     nsName);
                4935     }
                4936 #endif
                4937     return (ret);
                4938 }
                4939 
                4940 /**
                4941  * xmlSchemaGetAttributeGroup:
                4942  * @schema:  the context of the schema
                4943  * @name:  the name of the attribute group
                4944  * @ns:  the target namespace of the attribute group
                4945  *
                4946  * Lookup a an attribute group in the schema or imported schemas
                4947  *
                4948  * Returns the attribute group definition or NULL if not found.
                4949  */
                4950 static xmlSchemaAttributeGroupPtr
                4951 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
                4952                  const xmlChar * nsName)
                4953 {
                4954     xmlSchemaAttributeGroupPtr ret = NULL;
                4955 
                4956     if ((name == NULL) || (schema == NULL))
                4957         return (NULL);
                4958     if (schema != NULL) {
                4959     WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
                4960     }
                4961 exit:
                4962     /* TODO:
                4963     if ((ret != NULL) && (ret->redef != NULL)) {
                4964     * Return the last redefinition. *
                4965     ret = ret->redef;
                4966     }
                4967     */
                4968 #ifdef DEBUG
                4969     if (ret == NULL) {
                4970         if (nsName == NULL)
                4971             fprintf(stderr, "Unable to lookup attribute group %s", name);
                4972         else
                4973             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
                4974                     nsName);
                4975     }
                4976 #endif
                4977     return (ret);
                4978 }
                4979 
                4980 /**
                4981  * xmlSchemaGetGroup:
                4982  * @schema:  the context of the schema
                4983  * @name:  the name of the group
                4984  * @ns:  the target namespace of the group
                4985  *
                4986  * Lookup a group in the schema or imported schemas
                4987  *
                4988  * Returns the group definition or NULL if not found.
                4989  */
                4990 static xmlSchemaModelGroupDefPtr
                4991 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
                4992                  const xmlChar * nsName)
                4993 {
                4994     xmlSchemaModelGroupDefPtr ret = NULL;
                4995 
                4996     if ((name == NULL) || (schema == NULL))
                4997         return (NULL);
                4998     if (schema != NULL) {
                4999     WXS_FIND_GLOBAL_ITEM(groupDecl)
                5000     }
                5001 exit:
                5002 
                5003 #ifdef DEBUG
                5004     if (ret == NULL) {
                5005         if (nsName == NULL)
                5006             fprintf(stderr, "Unable to lookup group %s", name);
                5007         else
                5008             fprintf(stderr, "Unable to lookup group %s:%s", name,
                5009                     nsName);
                5010     }
                5011 #endif
                5012     return (ret);
                5013 }
                5014 
                5015 static xmlSchemaNotationPtr
                5016 xmlSchemaGetNotation(xmlSchemaPtr schema,
                5017              const xmlChar *name,
                5018              const xmlChar *nsName)
                5019 {
                5020     xmlSchemaNotationPtr ret = NULL;
                5021 
                5022     if ((name == NULL) || (schema == NULL))
                5023         return (NULL);
                5024     if (schema != NULL) {
                5025     WXS_FIND_GLOBAL_ITEM(notaDecl)
                5026     }
                5027 exit:
                5028     return (ret);
                5029 }
                5030 
                5031 static xmlSchemaIDCPtr
                5032 xmlSchemaGetIDC(xmlSchemaPtr schema,
                5033         const xmlChar *name,
                5034         const xmlChar *nsName)
                5035 {
                5036     xmlSchemaIDCPtr ret = NULL;
                5037 
                5038     if ((name == NULL) || (schema == NULL))
                5039         return (NULL);
                5040     if (schema != NULL) {
                5041     WXS_FIND_GLOBAL_ITEM(idcDef)
                5042     }
                5043 exit:
                5044     return (ret);
                5045 }
                5046 
                5047 /**
                5048  * xmlSchemaGetNamedComponent:
                5049  * @schema:  the schema
                5050  * @name:  the name of the group
                5051  * @ns:  the target namespace of the group
                5052  *
                5053  * Lookup a group in the schema or imported schemas
                5054  *
                5055  * Returns the group definition or NULL if not found.
                5056  */
                5057 static xmlSchemaBasicItemPtr
                5058 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
                5059                xmlSchemaTypeType itemType,
                5060                const xmlChar *name,
                5061                const xmlChar *targetNs)
                5062 {
                5063     switch (itemType) {
                5064     case XML_SCHEMA_TYPE_GROUP:
                5065         return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
                5066         name, targetNs));
                5067     case XML_SCHEMA_TYPE_ELEMENT:
                5068         return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
                5069         name, targetNs));
                5070     default:
                5071         TODO
                5072         return (NULL);
                5073     }
                5074 }
                5075 
                5076 /************************************************************************
                5077  *                                  *
                5078  *          Parsing functions               *
                5079  *                                  *
                5080  ************************************************************************/
                5081 
                5082 #define IS_BLANK_NODE(n)                        \
                5083     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
                5084 
                5085 /**
                5086  * xmlSchemaIsBlank:
                5087  * @str:  a string
                5088  * @len: the length of the string or -1
                5089  *
                5090  * Check if a string is ignorable
                5091  *
                5092  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
                5093  */
                5094 static int
                5095 xmlSchemaIsBlank(xmlChar * str, int len)
                5096 {
                5097     if (str == NULL)
                5098         return (1);
                5099     if (len < 0) {
                5100     while (*str != 0) {
                5101         if (!(IS_BLANK_CH(*str)))
                5102         return (0);
                5103         str++;
                5104     }
                5105     } else while ((*str != 0) && (len != 0)) {
                5106     if (!(IS_BLANK_CH(*str)))
                5107         return (0);
                5108     str++;
                5109     len--;
                5110     }
                5111 
                5112     return (1);
                5113 }
                5114 
                5115 #define WXS_COMP_NAME(c, t) ((t) (c))->name
                5116 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
                5117 /*
                5118 * xmlSchemaFindRedefCompInGraph:
                5119 * ATTENTION TODO: This uses pointer comp. for strings.
                5120 */
                5121 static xmlSchemaBasicItemPtr
                5122 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
                5123                   xmlSchemaTypeType type,
                5124                   const xmlChar *name,
                5125                   const xmlChar *nsName)
                5126 {
                5127     xmlSchemaBasicItemPtr ret;
                5128     int i;
                5129 
                5130     if ((bucket == NULL) || (name == NULL))
                5131     return(NULL);
                5132     if ((bucket->globals == NULL) ||
                5133     (bucket->globals->nbItems == 0))
                5134     goto subschemas;
                5135     /*
                5136     * Search in global components.
                5137     */
                5138     for (i = 0; i < bucket->globals->nbItems; i++) {
                5139     ret = bucket->globals->items[i];
                5140     if (ret->type == type) {
                5141         switch (type) {
                5142         case XML_SCHEMA_TYPE_COMPLEX:
                5143         case XML_SCHEMA_TYPE_SIMPLE:
                5144             if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
                5145             (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
                5146             nsName))
                5147             {
                5148             return(ret);
                5149             }
                5150             break;
                5151         case XML_SCHEMA_TYPE_GROUP:
                5152             if ((WXS_COMP_NAME(ret,
                5153                 xmlSchemaModelGroupDefPtr) == name) &&
                5154             (WXS_COMP_TNS(ret,
                5155                 xmlSchemaModelGroupDefPtr) == nsName))
                5156             {
                5157             return(ret);
                5158             }
                5159             break;
                5160         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                5161             if ((WXS_COMP_NAME(ret,
                5162                 xmlSchemaAttributeGroupPtr) == name) &&
                5163             (WXS_COMP_TNS(ret,
                5164                 xmlSchemaAttributeGroupPtr) == nsName))
                5165             {
                5166             return(ret);
                5167             }
                5168             break;
                5169         default:
                5170             /* Should not be hit. */
                5171             return(NULL);
                5172         }
                5173     }
                5174     }
                5175 subschemas:
                5176     /*
                5177     * Process imported/included schemas.
                5178     */
                5179     if (bucket->relations != NULL) {
                5180     xmlSchemaSchemaRelationPtr rel = bucket->relations;
                5181 
                5182     /*
                5183     * TODO: Marking the bucket will not avoid multiple searches
                5184     * in the same schema, but avoids at least circularity.
                5185     */
                5186     bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
                5187     do {
                5188         if ((rel->bucket != NULL) &&
                5189         ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
                5190         ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
                5191             type, name, nsName);
                5192         if (ret != NULL)
                5193             return(ret);
                5194         }
                5195         rel = rel->next;
                5196     } while (rel != NULL);
                5197      bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
                5198     }
                5199     return(NULL);
                5200 }
                5201 
                5202 /**
                5203  * xmlSchemaAddNotation:
                5204  * @ctxt:  a schema parser context
                5205  * @schema:  the schema being built
                5206  * @name:  the item name
                5207  *
                5208  * Add an XML schema annotation declaration
                5209  * *WARNING* this interface is highly subject to change
                5210  *
                5211  * Returns the new structure or NULL in case of error
                5212  */
                5213 static xmlSchemaNotationPtr
                5214 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                5215                      const xmlChar *name, const xmlChar *nsName,
                5216              xmlNodePtr node ATTRIBUTE_UNUSED)
                5217 {
                5218     xmlSchemaNotationPtr ret = NULL;
                5219 
                5220     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
                5221         return (NULL);
                5222 
                5223     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
                5224     if (ret == NULL) {
                5225         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
                5226         return (NULL);
                5227     }
                5228     memset(ret, 0, sizeof(xmlSchemaNotation));
                5229     ret->type = XML_SCHEMA_TYPE_NOTATION;
                5230     ret->name = name;
                5231     ret->targetNamespace = nsName;
                5232     /* TODO: do we need the node to be set?
                5233     * ret->node = node;*/
                5234     WXS_ADD_GLOBAL(ctxt, ret);
                5235     return (ret);
                5236 }
                5237 
                5238 /**
                5239  * xmlSchemaAddAttribute:
                5240  * @ctxt:  a schema parser context
                5241  * @schema:  the schema being built
                5242  * @name:  the item name
                5243  * @namespace:  the namespace
                5244  *
                5245  * Add an XML schema Attribute declaration
                5246  * *WARNING* this interface is highly subject to change
                5247  *
                5248  * Returns the new structure or NULL in case of error
                5249  */
                5250 static xmlSchemaAttributePtr
                5251 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                5252                       const xmlChar * name, const xmlChar * nsName,
                5253               xmlNodePtr node, int topLevel)
                5254 {
                5255     xmlSchemaAttributePtr ret = NULL;
                5256 
                5257     if ((ctxt == NULL) || (schema == NULL))
                5258         return (NULL);
                5259 
                5260     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
                5261     if (ret == NULL) {
                5262         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
                5263         return (NULL);
                5264     }
                5265     memset(ret, 0, sizeof(xmlSchemaAttribute));
                5266     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
                5267     ret->node = node;
                5268     ret->name = name;
                5269     ret->targetNamespace = nsName;
                5270 
                5271     if (topLevel)
                5272     WXS_ADD_GLOBAL(ctxt, ret);
                5273     else
                5274     WXS_ADD_LOCAL(ctxt, ret);
                5275     WXS_ADD_PENDING(ctxt, ret);
                5276     return (ret);
                5277 }
                5278 
                5279 /**
                5280  * xmlSchemaAddAttributeUse:
                5281  * @ctxt:  a schema parser context
                5282  * @schema:  the schema being built
                5283  * @name:  the item name
                5284  * @namespace:  the namespace
                5285  *
                5286  * Add an XML schema Attribute declaration
                5287  * *WARNING* this interface is highly subject to change
                5288  *
                5289  * Returns the new structure or NULL in case of error
                5290  */
                5291 static xmlSchemaAttributeUsePtr
                5292 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
                5293              xmlNodePtr node)
                5294 {
                5295     xmlSchemaAttributeUsePtr ret = NULL;
                5296 
                5297     if (pctxt == NULL)
                5298         return (NULL);
                5299 
                5300     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
                5301     if (ret == NULL) {
                5302         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
                5303         return (NULL);
                5304     }
                5305     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
                5306     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
                5307     ret->node = node;
                5308 
                5309     WXS_ADD_LOCAL(pctxt, ret);
                5310     return (ret);
                5311 }
                5312 
                5313 /*
                5314 * xmlSchemaAddRedef:
                5315 *
                5316 * Adds a redefinition information. This is used at a later stage to:
                5317 * resolve references to the redefined components and to check constraints.
                5318 */
                5319 static xmlSchemaRedefPtr
                5320 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
                5321           xmlSchemaBucketPtr targetBucket,
                5322           void *item,
                5323           const xmlChar *refName,
                5324           const xmlChar *refTargetNs)
                5325 {
                5326     xmlSchemaRedefPtr ret;
                5327 
                5328     ret = (xmlSchemaRedefPtr)
                5329     xmlMalloc(sizeof(xmlSchemaRedef));
                5330     if (ret == NULL) {
                5331     xmlSchemaPErrMemory(pctxt,
                5332         "allocating redefinition info", NULL);
                5333     return (NULL);
                5334     }
                5335     memset(ret, 0, sizeof(xmlSchemaRedef));
                5336     ret->item = item;
                5337     ret->targetBucket = targetBucket;
                5338     ret->refName = refName;
                5339     ret->refTargetNs = refTargetNs;
                5340     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
                5341     WXS_CONSTRUCTOR(pctxt)->redefs = ret;
                5342     else
                5343     WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
                5344     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
                5345 
                5346     return (ret);
                5347 }
                5348 
                5349 /**
                5350  * xmlSchemaAddAttributeGroupDefinition:
                5351  * @ctxt:  a schema parser context
                5352  * @schema:  the schema being built
                5353  * @name:  the item name
                5354  * @nsName:  the target namespace
                5355  * @node: the corresponding node
                5356  *
                5357  * Add an XML schema Attribute Group definition.
                5358  *
                5359  * Returns the new structure or NULL in case of error
                5360  */
                5361 static xmlSchemaAttributeGroupPtr
                5362 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
                5363                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
                5364                const xmlChar *name,
                5365                const xmlChar *nsName,
                5366                xmlNodePtr node)
                5367 {
                5368     xmlSchemaAttributeGroupPtr ret = NULL;
                5369 
                5370     if ((pctxt == NULL) || (name == NULL))
                5371         return (NULL);
                5372 
                5373     ret = (xmlSchemaAttributeGroupPtr)
                5374         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
                5375     if (ret == NULL) {
                5376     xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
                5377     return (NULL);
                5378     }
                5379     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
                5380     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
                5381     ret->name = name;
                5382     ret->targetNamespace = nsName;
                5383     ret->node = node;
                5384 
                5385     /* TODO: Remove the flag. */
                5386     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
                5387     if (pctxt->isRedefine) {
                5388     pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
                5389         ret, name, nsName);
                5390     if (pctxt->redef == NULL) {
                5391         xmlFree(ret);
                5392         return(NULL);
                5393     }
                5394     pctxt->redefCounter = 0;
                5395     }
                5396     WXS_ADD_GLOBAL(pctxt, ret);
                5397     WXS_ADD_PENDING(pctxt, ret);
                5398     return (ret);
                5399 }
                5400 
                5401 /**
                5402  * xmlSchemaAddElement:
                5403  * @ctxt:  a schema parser context
                5404  * @schema:  the schema being built
                5405  * @name:  the type name
                5406  * @namespace:  the type namespace
                5407  *
                5408  * Add an XML schema Element declaration
                5409  * *WARNING* this interface is highly subject to change
                5410  *
                5411  * Returns the new structure or NULL in case of error
                5412  */
                5413 static xmlSchemaElementPtr
                5414 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
                5415                     const xmlChar * name, const xmlChar * nsName,
                5416             xmlNodePtr node, int topLevel)
                5417 {
                5418     xmlSchemaElementPtr ret = NULL;
                5419 
                5420     if ((ctxt == NULL) || (name == NULL))
                5421         return (NULL);
                5422 
                5423     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
                5424     if (ret == NULL) {
                5425         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
                5426         return (NULL);
                5427     }
                5428     memset(ret, 0, sizeof(xmlSchemaElement));
                5429     ret->type = XML_SCHEMA_TYPE_ELEMENT;
                5430     ret->name = name;
                5431     ret->targetNamespace = nsName;
                5432     ret->node = node;
                5433 
                5434     if (topLevel)
                5435     WXS_ADD_GLOBAL(ctxt, ret);
                5436     else
                5437     WXS_ADD_LOCAL(ctxt, ret);
                5438     WXS_ADD_PENDING(ctxt, ret);
                5439     return (ret);
                5440 }
                5441 
                5442 /**
                5443  * xmlSchemaAddType:
                5444  * @ctxt:  a schema parser context
                5445  * @schema:  the schema being built
                5446  * @name:  the item name
                5447  * @namespace:  the namespace
                5448  *
                5449  * Add an XML schema item
                5450  * *WARNING* this interface is highly subject to change
                5451  *
                5452  * Returns the new structure or NULL in case of error
                5453  */
                5454 static xmlSchemaTypePtr
                5455 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                5456          xmlSchemaTypeType type,
                5457                  const xmlChar * name, const xmlChar * nsName,
                5458          xmlNodePtr node, int topLevel)
                5459 {
                5460     xmlSchemaTypePtr ret = NULL;
                5461 
                5462     if ((ctxt == NULL) || (schema == NULL))
                5463         return (NULL);
                5464 
                5465     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
                5466     if (ret == NULL) {
                5467         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
                5468         return (NULL);
                5469     }
                5470     memset(ret, 0, sizeof(xmlSchemaType));
                5471     ret->type = type;
                5472     ret->name = name;
                5473     ret->targetNamespace = nsName;
                5474     ret->node = node;
                5475     if (topLevel) {
                5476     if (ctxt->isRedefine) {
                5477         ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
                5478         ret, name, nsName);
                5479         if (ctxt->redef == NULL) {
                5480         xmlFree(ret);
                5481         return(NULL);
                5482         }
                5483         ctxt->redefCounter = 0;
                5484     }
                5485     WXS_ADD_GLOBAL(ctxt, ret);
                5486     } else
                5487     WXS_ADD_LOCAL(ctxt, ret);
                5488     WXS_ADD_PENDING(ctxt, ret);
                5489     return (ret);
                5490 }
                5491 
                5492 static xmlSchemaQNameRefPtr
                5493 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
                5494              xmlSchemaTypeType refType,
                5495              const xmlChar *refName,
                5496              const xmlChar *refNs)
                5497 {
                5498     xmlSchemaQNameRefPtr ret;
                5499 
                5500     ret = (xmlSchemaQNameRefPtr)
                5501     xmlMalloc(sizeof(xmlSchemaQNameRef));
                5502     if (ret == NULL) {
                5503     xmlSchemaPErrMemory(pctxt,
                5504         "allocating QName reference item", NULL);
                5505     return (NULL);
                5506     }
                5507     ret->node = NULL;
                5508     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
                5509     ret->name = refName;
                5510     ret->targetNamespace = refNs;
                5511     ret->item = NULL;
                5512     ret->itemType = refType;
                5513     /*
                5514     * Store the reference item in the schema.
                5515     */
                5516     WXS_ADD_LOCAL(pctxt, ret);
                5517     return (ret);
                5518 }
                5519 
                5520 static xmlSchemaAttributeUseProhibPtr
                5521 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
                5522 {
                5523     xmlSchemaAttributeUseProhibPtr ret;
                5524 
                5525     ret = (xmlSchemaAttributeUseProhibPtr)
                5526     xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
                5527     if (ret == NULL) {
                5528     xmlSchemaPErrMemory(pctxt,
                5529         "allocating attribute use prohibition", NULL);
                5530     return (NULL);
                5531     }
                5532     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
                5533     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
                5534     WXS_ADD_LOCAL(pctxt, ret);
                5535     return (ret);
                5536 }
                5537 
                5538 
                5539 /**
                5540  * xmlSchemaAddModelGroup:
                5541  * @ctxt:  a schema parser context
                5542  * @schema:  the schema being built
                5543  * @type: the "compositor" type of the model group
                5544  * @node: the node in the schema doc
                5545  *
                5546  * Adds a schema model group
                5547  * *WARNING* this interface is highly subject to change
                5548  *
                5549  * Returns the new structure or NULL in case of error
                5550  */
                5551 static xmlSchemaModelGroupPtr
                5552 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
                5553                xmlSchemaPtr schema,
                5554                xmlSchemaTypeType type,
                5555                xmlNodePtr node)
                5556 {
                5557     xmlSchemaModelGroupPtr ret = NULL;
                5558 
                5559     if ((ctxt == NULL) || (schema == NULL))
                5560         return (NULL);
                5561 
                5562     ret = (xmlSchemaModelGroupPtr)
                5563     xmlMalloc(sizeof(xmlSchemaModelGroup));
                5564     if (ret == NULL) {
                5565     xmlSchemaPErrMemory(ctxt, "allocating model group component",
                5566         NULL);
                5567     return (NULL);
                5568     }
                5569     memset(ret, 0, sizeof(xmlSchemaModelGroup));
                5570     ret->type = type;
                5571     ret->node = node;
                5572     WXS_ADD_LOCAL(ctxt, ret);
                5573     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
                5574     (type == XML_SCHEMA_TYPE_CHOICE))
                5575     WXS_ADD_PENDING(ctxt, ret);
                5576     return (ret);
                5577 }
                5578 
                5579 
                5580 /**
                5581  * xmlSchemaAddParticle:
                5582  * @ctxt:  a schema parser context
                5583  * @schema:  the schema being built
                5584  * @node: the corresponding node in the schema doc
                5585  * @min: the minOccurs
                5586  * @max: the maxOccurs
                5587  *
                5588  * Adds an XML schema particle component.
                5589  * *WARNING* this interface is highly subject to change
                5590  *
                5591  * Returns the new structure or NULL in case of error
                5592  */
                5593 static xmlSchemaParticlePtr
                5594 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
                5595              xmlNodePtr node, int min, int max)
                5596 {
                5597     xmlSchemaParticlePtr ret = NULL;
                5598     if (ctxt == NULL)
                5599         return (NULL);
                5600 
                5601 #ifdef DEBUG
                5602     fprintf(stderr, "Adding particle component\n");
                5603 #endif
                5604     ret = (xmlSchemaParticlePtr)
                5605     xmlMalloc(sizeof(xmlSchemaParticle));
                5606     if (ret == NULL) {
                5607     xmlSchemaPErrMemory(ctxt, "allocating particle component",
                5608         NULL);
                5609     return (NULL);
                5610     }
                5611     ret->type = XML_SCHEMA_TYPE_PARTICLE;
                5612     ret->annot = NULL;
                5613     ret->node = node;
                5614     ret->minOccurs = min;
                5615     ret->maxOccurs = max;
                5616     ret->next = NULL;
                5617     ret->children = NULL;
                5618 
                5619     WXS_ADD_LOCAL(ctxt, ret);
                5620     /*
                5621     * Note that addition to pending components will be done locally
                5622     * to the specific parsing function, since the most particles
                5623     * need not to be fixed up (i.e. the reference to be resolved).
                5624     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
                5625     */
                5626     return (ret);
                5627 }
                5628 
                5629 /**
                5630  * xmlSchemaAddModelGroupDefinition:
                5631  * @ctxt:  a schema validation context
                5632  * @schema:  the schema being built
                5633  * @name:  the group name
                5634  *
                5635  * Add an XML schema Group definition
                5636  *
                5637  * Returns the new structure or NULL in case of error
                5638  */
                5639 static xmlSchemaModelGroupDefPtr
                5640 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
                5641                  xmlSchemaPtr schema,
                5642                  const xmlChar *name,
                5643                  const xmlChar *nsName,
                5644                  xmlNodePtr node)
                5645 {
                5646     xmlSchemaModelGroupDefPtr ret = NULL;
                5647 
                5648     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
                5649         return (NULL);
                5650 
                5651     ret = (xmlSchemaModelGroupDefPtr)
                5652     xmlMalloc(sizeof(xmlSchemaModelGroupDef));
                5653     if (ret == NULL) {
                5654         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
                5655         return (NULL);
                5656     }
                5657     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
                5658     ret->name = name;
                5659     ret->type = XML_SCHEMA_TYPE_GROUP;
                5660     ret->node = node;
                5661     ret->targetNamespace = nsName;
                5662 
                5663     if (ctxt->isRedefine) {
                5664     ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
                5665         ret, name, nsName);
                5666     if (ctxt->redef == NULL) {
                5667         xmlFree(ret);
                5668         return(NULL);
                5669     }
                5670     ctxt->redefCounter = 0;
                5671     }
                5672     WXS_ADD_GLOBAL(ctxt, ret);
                5673     WXS_ADD_PENDING(ctxt, ret);
                5674     return (ret);
                5675 }
                5676 
                5677 /**
                5678  * xmlSchemaNewWildcardNs:
                5679  * @ctxt:  a schema validation context
                5680  *
                5681  * Creates a new wildcard namespace constraint.
                5682  *
                5683  * Returns the new structure or NULL in case of error
                5684  */
                5685 static xmlSchemaWildcardNsPtr
                5686 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
                5687 {
                5688     xmlSchemaWildcardNsPtr ret;
                5689 
                5690     ret = (xmlSchemaWildcardNsPtr)
                5691     xmlMalloc(sizeof(xmlSchemaWildcardNs));
                5692     if (ret == NULL) {
                5693     xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
                5694     return (NULL);
                5695     }
                5696     ret->value = NULL;
                5697     ret->next = NULL;
                5698     return (ret);
                5699 }
                5700 
                5701 static xmlSchemaIDCPtr
                5702 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                5703                   const xmlChar *name, const xmlChar *nsName,
                5704           int category, xmlNodePtr node)
                5705 {
                5706     xmlSchemaIDCPtr ret = NULL;
                5707 
                5708     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
                5709         return (NULL);
                5710 
                5711     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
                5712     if (ret == NULL) {
                5713         xmlSchemaPErrMemory(ctxt,
                5714         "allocating an identity-constraint definition", NULL);
                5715         return (NULL);
                5716     }
                5717     memset(ret, 0, sizeof(xmlSchemaIDC));
                5718     /* The target namespace of the parent element declaration. */
                5719     ret->targetNamespace = nsName;
                5720     ret->name = name;
                5721     ret->type = category;
                5722     ret->node = node;
                5723 
                5724     WXS_ADD_GLOBAL(ctxt, ret);
                5725     /*
                5726     * Only keyrefs need to be fixup up.
                5727     */
                5728     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
                5729     WXS_ADD_PENDING(ctxt, ret);
                5730     return (ret);
                5731 }
                5732 
                5733 /**
                5734  * xmlSchemaAddWildcard:
                5735  * @ctxt:  a schema validation context
                5736  * @schema: a schema
                5737  *
                5738  * Adds a wildcard.
                5739  * It corresponds to a xsd:anyAttribute and xsd:any.
                5740  *
                5741  * Returns the new structure or NULL in case of error
                5742  */
                5743 static xmlSchemaWildcardPtr
                5744 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                5745              xmlSchemaTypeType type, xmlNodePtr node)
                5746 {
                5747     xmlSchemaWildcardPtr ret = NULL;
                5748 
                5749     if ((ctxt == NULL) || (schema == NULL))
                5750         return (NULL);
                5751 
                5752     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
                5753     if (ret == NULL) {
                5754         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
                5755         return (NULL);
                5756     }
                5757     memset(ret, 0, sizeof(xmlSchemaWildcard));
                5758     ret->type = type;
                5759     ret->node = node;
                5760     WXS_ADD_LOCAL(ctxt, ret);
                5761     return (ret);
                5762 }
                5763 
                5764 static void
                5765 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
                5766 {
                5767     if (group == NULL)
                5768     return;
                5769     if (group->members != NULL)
                5770     xmlSchemaItemListFree(group->members);
                5771     xmlFree(group);
                5772 }
                5773 
                5774 static void
                5775 xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
                5776 {
                5777     xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
                5778 }
                5779 
                5780 static xmlSchemaSubstGroupPtr
                5781 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
                5782                xmlSchemaElementPtr head)
                5783 {
                5784     xmlSchemaSubstGroupPtr ret;
                5785 
                5786     /* Init subst group hash. */
                5787     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
                5788     WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
                5789     if (WXS_SUBST_GROUPS(pctxt) == NULL)
                5790         return(NULL);
                5791     }
                5792     /* Create a new substitution group. */
                5793     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
                5794     if (ret == NULL) {
                5795     xmlSchemaPErrMemory(NULL,
                5796         "allocating a substitution group container", NULL);
                5797     return(NULL);
                5798     }
                5799     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
                5800     ret->head = head;
                5801     /* Create list of members. */
                5802     ret->members = xmlSchemaItemListCreate();
                5803     if (ret->members == NULL) {
                5804     xmlSchemaSubstGroupFree(ret);
                5805     return(NULL);
                5806     }
                5807     /* Add subst group to hash. */
                5808     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
                5809     head->name, head->targetNamespace, ret) != 0) {
                5810     PERROR_INT("xmlSchemaSubstGroupAdd",
                5811         "failed to add a new substitution container");
                5812     xmlSchemaSubstGroupFree(ret);
                5813     return(NULL);
                5814     }
                5815     return(ret);
                5816 }
                5817 
                5818 static xmlSchemaSubstGroupPtr
                5819 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
                5820                xmlSchemaElementPtr head)
                5821 {
                5822     if (WXS_SUBST_GROUPS(pctxt) == NULL)
                5823     return(NULL);
                5824     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
                5825     head->name, head->targetNamespace));
                5826 
                5827 }
                5828 
                5829 /**
                5830  * xmlSchemaAddElementSubstitutionMember:
                5831  * @pctxt:  a schema parser context
                5832  * @head:  the head of the substitution group
                5833  * @member: the new member of the substitution group
                5834  *
                5835  * Allocate a new annotation structure.
                5836  *
                5837  * Returns the newly allocated structure or NULL in case or error
                5838  */
                5839 static int
                5840 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
                5841                       xmlSchemaElementPtr head,
                5842                       xmlSchemaElementPtr member)
                5843 {
                5844     xmlSchemaSubstGroupPtr substGroup = NULL;
                5845 
                5846     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
                5847     return (-1);
                5848 
                5849     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
                5850     if (substGroup == NULL)
                5851     substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
                5852     if (substGroup == NULL)
                5853     return(-1);
                5854     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
                5855     return(-1);
                5856     return(0);
                5857 }
                5858 
                5859 /************************************************************************
                5860  *                                  *
                5861  *      Utilities for parsing                   *
                5862  *                                  *
                5863  ************************************************************************/
                5864 
                5865 /**
                5866  * xmlSchemaPValAttrNodeQNameValue:
                5867  * @ctxt:  a schema parser context
                5868  * @schema: the schema context
                5869  * @ownerItem: the parent as a schema object
                5870  * @value:  the QName value
                5871  * @uri:  the resulting namespace URI if found
                5872  * @local: the resulting local part if found, the attribute value otherwise
                5873  *
                5874  * Extracts the local name and the URI of a QName value and validates it.
                5875  * This one is intended to be used on attribute values that
                5876  * should resolve to schema components.
                5877  *
                5878  * Returns 0, in case the QName is valid, a positive error code
                5879  * if not valid and -1 if an internal error occurs.
                5880  */
                5881 static int
                5882 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
                5883                        xmlSchemaPtr schema,
                5884                        xmlSchemaBasicItemPtr ownerItem,
                5885                        xmlAttrPtr attr,
                5886                        const xmlChar *value,
                5887                        const xmlChar **uri,
                5888                        const xmlChar **local)
                5889 {
                5890     const xmlChar *pref;
                5891     xmlNsPtr ns;
                5892     int len, ret;
                5893 
                5894     *uri = NULL;
                5895     *local = NULL;
                5896     ret = xmlValidateQName(value, 1);
                5897     if (ret > 0) {
                5898     xmlSchemaPSimpleTypeErr(ctxt,
                5899         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                5900         ownerItem, (xmlNodePtr) attr,
                5901         xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
                5902         NULL, value, NULL, NULL, NULL);
                5903     *local = value;
                5904     return (ctxt->err);
                5905     } else if (ret < 0)
                5906     return (-1);
                5907 
                5908     if (!strchr((char *) value, ':')) {
                5909     ns = xmlSearchNs(attr->doc, attr->parent, NULL);
a279c2783 Alex*5910     if (ns && ns->href && ns->href[0])
9d9d4fcc3 Alex*5911         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
                5912     else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
                5913         /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
                5914         * parser context. */
                5915         /*
                5916         * This one takes care of included schemas with no
                5917         * target namespace.
                5918         */
                5919         *uri = ctxt->targetNamespace;
                5920     }
                5921     *local = xmlDictLookup(ctxt->dict, value, -1);
                5922     return (0);
                5923     }
                5924     /*
                5925     * At this point xmlSplitQName3 has to return a local name.
                5926     */
                5927     *local = xmlSplitQName3(value, &len);
                5928     *local = xmlDictLookup(ctxt->dict, *local, -1);
                5929     pref = xmlDictLookup(ctxt->dict, value, len);
                5930     ns = xmlSearchNs(attr->doc, attr->parent, pref);
                5931     if (ns == NULL) {
                5932     xmlSchemaPSimpleTypeErr(ctxt,
                5933         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                5934         ownerItem, (xmlNodePtr) attr,
                5935         xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
                5936         "The value '%s' of simple type 'xs:QName' has no "
                5937         "corresponding namespace declaration in scope", value, NULL);
                5938     return (ctxt->err);
                5939     } else {
                5940         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
                5941     }
                5942     return (0);
                5943 }
                5944 
                5945 /**
                5946  * xmlSchemaPValAttrNodeQName:
                5947  * @ctxt:  a schema parser context
                5948  * @schema: the schema context
                5949  * @ownerItem: the owner as a schema object
                5950  * @attr:  the attribute node
                5951  * @uri:  the resulting namespace URI if found
                5952  * @local: the resulting local part if found, the attribute value otherwise
                5953  *
                5954  * Extracts and validates the QName of an attribute value.
                5955  * This one is intended to be used on attribute values that
                5956  * should resolve to schema components.
                5957  *
                5958  * Returns 0, in case the QName is valid, a positive error code
                5959  * if not valid and -1 if an internal error occurs.
                5960  */
                5961 static int
                5962 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
                5963                        xmlSchemaPtr schema,
                5964                        xmlSchemaBasicItemPtr ownerItem,
                5965                        xmlAttrPtr attr,
                5966                        const xmlChar **uri,
                5967                        const xmlChar **local)
                5968 {
                5969     const xmlChar *value;
                5970 
                5971     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                5972     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
                5973     ownerItem, attr, value, uri, local));
                5974 }
                5975 
                5976 /**
                5977  * xmlSchemaPValAttrQName:
                5978  * @ctxt:  a schema parser context
                5979  * @schema: the schema context
                5980  * @ownerItem: the owner as a schema object
                5981  * @ownerElem:  the parent node of the attribute
                5982  * @name:  the name of the attribute
                5983  * @uri:  the resulting namespace URI if found
                5984  * @local: the resulting local part if found, the attribute value otherwise
                5985  *
                5986  * Extracts and validates the QName of an attribute value.
                5987  *
                5988  * Returns 0, in case the QName is valid, a positive error code
                5989  * if not valid and -1 if an internal error occurs.
                5990  */
                5991 static int
                5992 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
                5993                    xmlSchemaPtr schema,
                5994                    xmlSchemaBasicItemPtr ownerItem,
                5995                    xmlNodePtr ownerElem,
                5996                    const char *name,
                5997                    const xmlChar **uri,
                5998                    const xmlChar **local)
                5999 {
                6000     xmlAttrPtr attr;
                6001 
                6002     attr = xmlSchemaGetPropNode(ownerElem, name);
                6003     if (attr == NULL) {
                6004     *local = NULL;
                6005     *uri = NULL;
                6006     return (0);
                6007     }
                6008     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
                6009     ownerItem, attr, uri, local));
                6010 }
                6011 
                6012 /**
                6013  * xmlSchemaPValAttrID:
                6014  * @ctxt:  a schema parser context
                6015  *
                6016  * Extracts and validates the ID of an attribute value.
                6017  *
                6018  * Returns 0, in case the ID is valid, a positive error code
                6019  * if not valid and -1 if an internal error occurs.
                6020  */
                6021 static int
                6022 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
                6023 {
                6024     int ret;
                6025     const xmlChar *value;
                6026 
                6027     if (attr == NULL)
                6028     return(0);
                6029     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
                6030     ret = xmlValidateNCName(value, 1);
                6031     if (ret == 0) {
                6032     /*
                6033     * NOTE: the IDness might have already be declared in the DTD
                6034     */
                6035     if (attr->atype != XML_ATTRIBUTE_ID) {
                6036         xmlIDPtr res;
                6037         xmlChar *strip;
                6038 
                6039         /*
                6040         * TODO: Use xmlSchemaStrip here; it's not exported at this
                6041         * moment.
                6042         */
                6043         strip = xmlSchemaCollapseString(value);
                6044         if (strip != NULL) {
                6045         xmlFree((xmlChar *) value);
                6046         value = strip;
                6047         }
                6048         res = xmlAddID(NULL, attr->doc, value, attr);
                6049         if (res == NULL) {
                6050         ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
                6051         xmlSchemaPSimpleTypeErr(ctxt,
                6052             XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6053             NULL, (xmlNodePtr) attr,
                6054             xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
                6055             NULL, NULL, "Duplicate value '%s' of simple "
                6056             "type 'xs:ID'", value, NULL);
                6057         } else
                6058         attr->atype = XML_ATTRIBUTE_ID;
                6059     }
                6060     } else if (ret > 0) {
                6061     ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
                6062     xmlSchemaPSimpleTypeErr(ctxt,
                6063         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6064         NULL, (xmlNodePtr) attr,
                6065         xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
                6066         NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
                6067         "not a valid 'xs:NCName'",
                6068         value, NULL);
                6069     }
                6070     if (value != NULL)
                6071     xmlFree((xmlChar *)value);
                6072 
                6073     return (ret);
                6074 }
                6075 
                6076 static int
                6077 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
                6078             xmlNodePtr ownerElem,
                6079             const xmlChar *name)
                6080 {
                6081     xmlAttrPtr attr;
                6082 
                6083     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
                6084     if (attr == NULL)
                6085     return(0);
                6086     return(xmlSchemaPValAttrNodeID(ctxt, attr));
                6087 
                6088 }
                6089 
                6090 /**
                6091  * xmlGetMaxOccurs:
                6092  * @ctxt:  a schema validation context
                6093  * @node:  a subtree containing XML Schema information
                6094  *
                6095  * Get the maxOccurs property
                6096  *
                6097  * Returns the default if not found, or the value
                6098  */
                6099 static int
                6100 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                6101         int min, int max, int def, const char *expected)
                6102 {
                6103     const xmlChar *val, *cur;
                6104     int ret = 0;
                6105     xmlAttrPtr attr;
                6106 
                6107     attr = xmlSchemaGetPropNode(node, "maxOccurs");
                6108     if (attr == NULL)
                6109     return (def);
                6110     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
ad7b9726c Alex*6111     if (val == NULL)
                6112         return (def);
9d9d4fcc3 Alex*6113 
                6114     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
                6115     if (max != UNBOUNDED) {
                6116         xmlSchemaPSimpleTypeErr(ctxt,
                6117         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6118         /* XML_SCHEMAP_INVALID_MINOCCURS, */
                6119         NULL, (xmlNodePtr) attr, NULL, expected,
                6120         val, NULL, NULL, NULL);
                6121         return (def);
                6122     } else
                6123         return (UNBOUNDED);  /* encoding it with -1 might be another option */
                6124     }
                6125 
                6126     cur = val;
                6127     while (IS_BLANK_CH(*cur))
                6128         cur++;
                6129     if (*cur == 0) {
                6130         xmlSchemaPSimpleTypeErr(ctxt,
                6131         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6132         /* XML_SCHEMAP_INVALID_MINOCCURS, */
                6133         NULL, (xmlNodePtr) attr, NULL, expected,
                6134         val, NULL, NULL, NULL);
                6135     return (def);
                6136     }
                6137     while ((*cur >= '0') && (*cur <= '9')) {
                6138         if (ret > INT_MAX / 10) {
                6139             ret = INT_MAX;
                6140         } else {
                6141             int digit = *cur - '0';
                6142             ret *= 10;
                6143             if (ret > INT_MAX - digit)
                6144                 ret = INT_MAX;
                6145             else
                6146                 ret += digit;
                6147         }
                6148         cur++;
                6149     }
                6150     while (IS_BLANK_CH(*cur))
                6151         cur++;
                6152     /*
                6153     * TODO: Restrict the maximal value to Integer.
                6154     */
                6155     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
                6156     xmlSchemaPSimpleTypeErr(ctxt,
                6157         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6158         /* XML_SCHEMAP_INVALID_MINOCCURS, */
                6159         NULL, (xmlNodePtr) attr, NULL, expected,
                6160         val, NULL, NULL, NULL);
                6161         return (def);
                6162     }
                6163     return (ret);
                6164 }
                6165 
                6166 /**
                6167  * xmlGetMinOccurs:
                6168  * @ctxt:  a schema validation context
                6169  * @node:  a subtree containing XML Schema information
                6170  *
                6171  * Get the minOccurs property
                6172  *
                6173  * Returns the default if not found, or the value
                6174  */
                6175 static int
                6176 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                6177         int min, int max, int def, const char *expected)
                6178 {
                6179     const xmlChar *val, *cur;
                6180     int ret = 0;
                6181     xmlAttrPtr attr;
                6182 
                6183     attr = xmlSchemaGetPropNode(node, "minOccurs");
                6184     if (attr == NULL)
                6185     return (def);
                6186     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
ad7b9726c Alex*6187     if (val == NULL)
                6188     return (def);
9d9d4fcc3 Alex*6189     cur = val;
                6190     while (IS_BLANK_CH(*cur))
                6191         cur++;
                6192     if (*cur == 0) {
                6193         xmlSchemaPSimpleTypeErr(ctxt,
                6194         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6195         /* XML_SCHEMAP_INVALID_MINOCCURS, */
                6196         NULL, (xmlNodePtr) attr, NULL, expected,
                6197         val, NULL, NULL, NULL);
                6198         return (def);
                6199     }
                6200     while ((*cur >= '0') && (*cur <= '9')) {
                6201         if (ret > INT_MAX / 10) {
                6202             ret = INT_MAX;
                6203         } else {
                6204             int digit = *cur - '0';
                6205             ret *= 10;
                6206             if (ret > INT_MAX - digit)
                6207                 ret = INT_MAX;
                6208             else
                6209                 ret += digit;
                6210         }
                6211         cur++;
                6212     }
                6213     while (IS_BLANK_CH(*cur))
                6214         cur++;
                6215     /*
                6216     * TODO: Restrict the maximal value to Integer.
                6217     */
                6218     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
                6219     xmlSchemaPSimpleTypeErr(ctxt,
                6220         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6221         /* XML_SCHEMAP_INVALID_MINOCCURS, */
                6222         NULL, (xmlNodePtr) attr, NULL, expected,
                6223         val, NULL, NULL, NULL);
                6224         return (def);
                6225     }
                6226     return (ret);
                6227 }
                6228 
                6229 /**
                6230  * xmlSchemaPGetBoolNodeValue:
                6231  * @ctxt:  a schema validation context
                6232  * @ownerItem:  the owner as a schema item
                6233  * @node: the node holding the value
                6234  *
                6235  * Converts a boolean string value into 1 or 0.
                6236  *
                6237  * Returns 0 or 1.
                6238  */
                6239 static int
                6240 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
                6241                xmlSchemaBasicItemPtr ownerItem,
                6242                xmlNodePtr node)
                6243 {
                6244     xmlChar *value = NULL;
                6245     int res = 0;
                6246 
                6247     value = xmlNodeGetContent(node);
                6248     /*
                6249     * 3.2.2.1 Lexical representation
                6250     * An instance of a datatype that is defined as `boolean`
                6251     * can have the following legal literals {true, false, 1, 0}.
                6252     */
                6253     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
                6254         res = 1;
                6255     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
                6256         res = 0;
                6257     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
                6258     res = 1;
                6259     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
                6260         res = 0;
                6261     else {
                6262         xmlSchemaPSimpleTypeErr(ctxt,
                6263         XML_SCHEMAP_INVALID_BOOLEAN,
                6264         ownerItem, node,
                6265         xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
                6266         NULL, BAD_CAST value,
                6267         NULL, NULL, NULL);
                6268     }
                6269     if (value != NULL)
                6270     xmlFree(value);
                6271     return (res);
                6272 }
                6273 
                6274 /**
                6275  * xmlGetBooleanProp:
                6276  * @ctxt:  a schema validation context
                6277  * @node:  a subtree containing XML Schema information
                6278  * @name:  the attribute name
                6279  * @def:  the default value
                6280  *
                6281  * Evaluate if a boolean property is set
                6282  *
                6283  * Returns the default if not found, 0 if found to be false,
                6284  * 1 if found to be true
                6285  */
                6286 static int
                6287 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
                6288           xmlNodePtr node,
                6289                   const char *name, int def)
                6290 {
                6291     const xmlChar *val;
                6292 
                6293     val = xmlSchemaGetProp(ctxt, node, name);
                6294     if (val == NULL)
                6295         return (def);
                6296     /*
                6297     * 3.2.2.1 Lexical representation
                6298     * An instance of a datatype that is defined as `boolean`
                6299     * can have the following legal literals {true, false, 1, 0}.
                6300     */
                6301     if (xmlStrEqual(val, BAD_CAST "true"))
                6302         def = 1;
                6303     else if (xmlStrEqual(val, BAD_CAST "false"))
                6304         def = 0;
                6305     else if (xmlStrEqual(val, BAD_CAST "1"))
                6306     def = 1;
                6307     else if (xmlStrEqual(val, BAD_CAST "0"))
                6308         def = 0;
                6309     else {
                6310         xmlSchemaPSimpleTypeErr(ctxt,
                6311         XML_SCHEMAP_INVALID_BOOLEAN,
                6312         NULL,
                6313         (xmlNodePtr) xmlSchemaGetPropNode(node, name),
                6314         xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
                6315         NULL, val, NULL, NULL, NULL);
                6316     }
                6317     return (def);
                6318 }
                6319 
                6320 /************************************************************************
                6321  *                                  *
                6322  *      Schema extraction from an Infoset           *
                6323  *                                  *
                6324  ************************************************************************/
                6325 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
                6326                                                  ctxt, xmlSchemaPtr schema,
                6327                                                  xmlNodePtr node,
                6328                          int topLevel);
                6329 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
                6330                                                   ctxt,
                6331                                                   xmlSchemaPtr schema,
                6332                                                   xmlNodePtr node,
                6333                           int topLevel);
                6334 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
                6335                                                   ctxt,
                6336                                                   xmlSchemaPtr schema,
                6337                                                   xmlNodePtr node,
                6338                           xmlSchemaTypeType parentType);
                6339 static xmlSchemaBasicItemPtr
                6340 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
                6341                  xmlSchemaPtr schema,
                6342                  xmlNodePtr node,
                6343                  xmlSchemaItemListPtr uses,
                6344                  int parentType);
                6345 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
                6346                                            xmlSchemaPtr schema,
                6347                                            xmlNodePtr node);
                6348 static xmlSchemaWildcardPtr
                6349 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
                6350                            xmlSchemaPtr schema, xmlNodePtr node);
                6351 
                6352 /**
                6353  * xmlSchemaPValAttrNodeValue:
                6354  *
                6355  * @pctxt:  a schema parser context
                6356  * @ownerItem: the schema object owner if existent
                6357  * @attr:  the schema attribute node being validated
                6358  * @value: the value
                6359  * @type: the built-in type to be validated against
                6360  *
                6361  * Validates a value against the given built-in type.
                6362  * This one is intended to be used internally for validation
                6363  * of schema attribute values during parsing of the schema.
                6364  *
                6365  * Returns 0 if the value is valid, a positive error code
                6366  * number otherwise and -1 in case of an internal or API error.
                6367  */
                6368 static int
                6369 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
                6370                xmlSchemaBasicItemPtr ownerItem,
                6371                xmlAttrPtr attr,
                6372                const xmlChar *value,
                6373                xmlSchemaTypePtr type)
                6374 {
                6375 
                6376     int ret = 0;
                6377 
                6378     /*
                6379     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
                6380     * one is really meant to be used internally, so better not.
                6381     */
                6382     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
                6383     return (-1);
                6384     if (type->type != XML_SCHEMA_TYPE_BASIC) {
                6385     PERROR_INT("xmlSchemaPValAttrNodeValue",
                6386         "the given type is not a built-in type");
                6387     return (-1);
                6388     }
                6389     switch (type->builtInType) {
                6390     case XML_SCHEMAS_NCNAME:
                6391     case XML_SCHEMAS_QNAME:
                6392     case XML_SCHEMAS_ANYURI:
                6393     case XML_SCHEMAS_TOKEN:
                6394     case XML_SCHEMAS_LANGUAGE:
                6395         ret = xmlSchemaValPredefTypeNode(type, value, NULL,
                6396         (xmlNodePtr) attr);
                6397         break;
                6398     default: {
                6399         PERROR_INT("xmlSchemaPValAttrNodeValue",
                6400         "validation using the given type is not supported while "
                6401         "parsing a schema");
                6402         return (-1);
                6403     }
                6404     }
                6405     /*
                6406     * TODO: Should we use the S4S error codes instead?
                6407     */
                6408     if (ret < 0) {
                6409     PERROR_INT("xmlSchemaPValAttrNodeValue",
                6410         "failed to validate a schema attribute value");
                6411     return (-1);
                6412     } else if (ret > 0) {
                6413     if (WXS_IS_LIST(type))
                6414         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
                6415     else
                6416         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
                6417     xmlSchemaPSimpleTypeErr(pctxt,
                6418         ret, ownerItem, (xmlNodePtr) attr,
                6419         type, NULL, value, NULL, NULL, NULL);
                6420     }
                6421     return (ret);
                6422 }
                6423 
                6424 /**
                6425  * xmlSchemaPValAttrNode:
                6426  *
                6427  * @ctxt:  a schema parser context
                6428  * @ownerItem: the schema object owner if existent
                6429  * @attr:  the schema attribute node being validated
                6430  * @type: the built-in type to be validated against
                6431  * @value: the resulting value if any
                6432  *
                6433  * Extracts and validates a value against the given built-in type.
                6434  * This one is intended to be used internally for validation
                6435  * of schema attribute values during parsing of the schema.
                6436  *
                6437  * Returns 0 if the value is valid, a positive error code
                6438  * number otherwise and -1 in case of an internal or API error.
                6439  */
                6440 static int
                6441 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
                6442                xmlSchemaBasicItemPtr ownerItem,
                6443                xmlAttrPtr attr,
                6444                xmlSchemaTypePtr type,
                6445                const xmlChar **value)
                6446 {
                6447     const xmlChar *val;
                6448 
                6449     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
                6450     return (-1);
                6451 
                6452     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                6453     if (value != NULL)
                6454     *value = val;
                6455 
                6456     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
                6457     val, type));
                6458 }
                6459 
                6460 /**
                6461  * xmlSchemaPValAttr:
                6462  *
                6463  * @ctxt:  a schema parser context
                6464  * @node: the element node of the attribute
                6465  * @ownerItem: the schema object owner if existent
                6466  * @ownerElem: the owner element node
                6467  * @name:  the name of the schema attribute node
                6468  * @type: the built-in type to be validated against
                6469  * @value: the resulting value if any
                6470  *
                6471  * Extracts and validates a value against the given built-in type.
                6472  * This one is intended to be used internally for validation
                6473  * of schema attribute values during parsing of the schema.
                6474  *
                6475  * Returns 0 if the value is valid, a positive error code
                6476  * number otherwise and -1 in case of an internal or API error.
                6477  */
                6478 static int
                6479 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
                6480                xmlSchemaBasicItemPtr ownerItem,
                6481                xmlNodePtr ownerElem,
                6482                const char *name,
                6483                xmlSchemaTypePtr type,
                6484                const xmlChar **value)
                6485 {
                6486     xmlAttrPtr attr;
                6487 
                6488     if ((ctxt == NULL) || (type == NULL)) {
                6489     if (value != NULL)
                6490         *value = NULL;
                6491     return (-1);
                6492     }
                6493     if (type->type != XML_SCHEMA_TYPE_BASIC) {
                6494     if (value != NULL)
                6495         *value = NULL;
                6496     xmlSchemaPErr(ctxt, ownerElem,
                6497         XML_SCHEMAP_INTERNAL,
                6498         "Internal error: xmlSchemaPValAttr, the given "
                6499         "type '%s' is not a built-in type.\n",
                6500         type->name, NULL);
                6501     return (-1);
                6502     }
                6503     attr = xmlSchemaGetPropNode(ownerElem, name);
                6504     if (attr == NULL) {
                6505     if (value != NULL)
                6506         *value = NULL;
                6507     return (0);
                6508     }
                6509     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
                6510     type, value));
                6511 }
                6512 
                6513 static int
                6514 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
                6515           xmlSchemaPtr schema ATTRIBUTE_UNUSED,
                6516           xmlNodePtr node,
                6517           xmlAttrPtr attr,
                6518           const xmlChar *namespaceName)
                6519 {
                6520     /* TODO: Pointer comparison instead? */
                6521     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
                6522     return (0);
                6523     if (xmlStrEqual(xmlSchemaNs, namespaceName))
                6524     return (0);
                6525     /*
                6526     * Check if the referenced namespace was <import>ed.
                6527     */
                6528     if (WXS_BUCKET(pctxt)->relations != NULL) {
                6529     xmlSchemaSchemaRelationPtr rel;
                6530 
                6531     rel = WXS_BUCKET(pctxt)->relations;
                6532     do {
                6533         if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
                6534         xmlStrEqual(namespaceName, rel->importNamespace))
                6535         return (0);
                6536         rel = rel->next;
                6537     } while (rel != NULL);
                6538     }
                6539     /*
                6540     * No matching <import>ed namespace found.
                6541     */
                6542     {
                6543     xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
                6544 
                6545     if (namespaceName == NULL)
                6546         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                6547         XML_SCHEMAP_SRC_RESOLVE, n, NULL,
                6548         "References from this schema to components in no "
                6549         "namespace are not allowed, since not indicated by an "
                6550         "import statement", NULL, NULL);
                6551     else
                6552         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                6553         XML_SCHEMAP_SRC_RESOLVE, n, NULL,
                6554         "References from this schema to components in the "
                6555         "namespace '%s' are not allowed, since not indicated by an "
                6556         "import statement", namespaceName, NULL);
                6557     }
                6558     return (XML_SCHEMAP_SRC_RESOLVE);
                6559 }
                6560 
                6561 /**
                6562  * xmlSchemaParseLocalAttributes:
                6563  * @ctxt:  a schema validation context
                6564  * @schema:  the schema being built
                6565  * @node:  a subtree containing XML Schema information
                6566  * @type:  the hosting type where the attributes will be anchored
                6567  *
                6568  * Parses attribute uses and attribute declarations and
                6569  * attribute group references.
                6570  */
                6571 static int
                6572 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                6573                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
                6574             int parentType, int *hasRefs)
                6575 {
                6576     void *item;
                6577 
                6578     while ((IS_SCHEMA((*child), "attribute")) ||
                6579            (IS_SCHEMA((*child), "attributeGroup"))) {
                6580         if (IS_SCHEMA((*child), "attribute")) {
                6581         item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
                6582         *list, parentType);
                6583         } else {
                6584             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
                6585         if ((item != NULL) && (hasRefs != NULL))
                6586         *hasRefs = 1;
                6587         }
                6588     if (item != NULL) {
                6589         if (*list == NULL) {
                6590         /* TODO: Customize grow factor. */
                6591         *list = xmlSchemaItemListCreate();
                6592         if (*list == NULL)
                6593             return(-1);
                6594         }
                6595         if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
                6596         return(-1);
                6597     }
                6598         *child = (*child)->next;
                6599     }
                6600     return (0);
                6601 }
                6602 
                6603 /**
                6604  * xmlSchemaParseAnnotation:
                6605  * @ctxt:  a schema validation context
                6606  * @schema:  the schema being built
                6607  * @node:  a subtree containing XML Schema information
                6608  *
                6609  * parse a XML schema Attribute declaration
                6610  * *WARNING* this interface is highly subject to change
                6611  *
                6612  * Returns -1 in case of error, 0 if the declaration is improper and
                6613  *         1 in case of success.
                6614  */
                6615 static xmlSchemaAnnotPtr
                6616 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
                6617 {
                6618     xmlSchemaAnnotPtr ret;
                6619     xmlNodePtr child = NULL;
                6620     xmlAttrPtr attr;
                6621     int barked = 0;
                6622 
                6623     /*
                6624     * INFO: S4S completed.
                6625     */
                6626     /*
                6627     * id = ID
                6628     * {any attributes with non-schema namespace . . .}>
                6629     * Content: (appinfo | documentation)*
                6630     */
                6631     if ((ctxt == NULL) || (node == NULL))
                6632         return (NULL);
                6633     if (needed)
                6634     ret = xmlSchemaNewAnnot(ctxt, node);
                6635     else
                6636     ret = NULL;
                6637     attr = node->properties;
                6638     while (attr != NULL) {
                6639     if (((attr->ns == NULL) &&
                6640         (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
                6641         ((attr->ns != NULL) &&
                6642         xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
                6643 
                6644         xmlSchemaPIllegalAttrErr(ctxt,
                6645         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                6646     }
                6647     attr = attr->next;
                6648     }
                6649     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                6650     /*
                6651     * And now for the children...
                6652     */
                6653     child = node->children;
                6654     while (child != NULL) {
                6655     if (IS_SCHEMA(child, "appinfo")) {
                6656         /* TODO: make available the content of "appinfo". */
                6657         /*
                6658         * source = anyURI
                6659         * {any attributes with non-schema namespace . . .}>
                6660         * Content: ({any})*
                6661         */
                6662         attr = child->properties;
                6663         while (attr != NULL) {
                6664         if (((attr->ns == NULL) &&
                6665              (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
                6666              ((attr->ns != NULL) &&
                6667               xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
                6668 
                6669             xmlSchemaPIllegalAttrErr(ctxt,
                6670             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                6671         }
                6672         attr = attr->next;
                6673         }
                6674         xmlSchemaPValAttr(ctxt, NULL, child, "source",
                6675         xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
                6676         child = child->next;
                6677     } else if (IS_SCHEMA(child, "documentation")) {
                6678         /* TODO: make available the content of "documentation". */
                6679         /*
                6680         * source = anyURI
                6681         * {any attributes with non-schema namespace . . .}>
                6682         * Content: ({any})*
                6683         */
                6684         attr = child->properties;
                6685         while (attr != NULL) {
                6686         if (attr->ns == NULL) {
                6687             if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
                6688             xmlSchemaPIllegalAttrErr(ctxt,
                6689                 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                6690             }
                6691         } else {
                6692             if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
                6693             (xmlStrEqual(attr->name, BAD_CAST "lang") &&
                6694             (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
                6695 
                6696             xmlSchemaPIllegalAttrErr(ctxt,
                6697                 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                6698             }
                6699         }
                6700         attr = attr->next;
                6701         }
                6702         /*
                6703         * Attribute "xml:lang".
                6704         */
                6705         attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
                6706         if (attr != NULL)
                6707         xmlSchemaPValAttrNode(ctxt, NULL, attr,
                6708         xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
                6709         child = child->next;
                6710     } else {
                6711         if (!barked)
                6712         xmlSchemaPContentErr(ctxt,
                6713             XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                6714             NULL, node, child, NULL, "(appinfo | documentation)*");
                6715         barked = 1;
                6716         child = child->next;
                6717     }
                6718     }
                6719 
                6720     return (ret);
                6721 }
                6722 
                6723 /**
                6724  * xmlSchemaParseFacet:
                6725  * @ctxt:  a schema validation context
                6726  * @schema:  the schema being built
                6727  * @node:  a subtree containing XML Schema information
                6728  *
                6729  * parse a XML schema Facet declaration
                6730  * *WARNING* this interface is highly subject to change
                6731  *
                6732  * Returns the new type structure or NULL in case of error
                6733  */
                6734 static xmlSchemaFacetPtr
                6735 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                6736                     xmlNodePtr node)
                6737 {
                6738     xmlSchemaFacetPtr facet;
                6739     xmlNodePtr child = NULL;
                6740     const xmlChar *value;
                6741 
                6742     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                6743         return (NULL);
                6744 
                6745     facet = xmlSchemaNewFacet();
                6746     if (facet == NULL) {
                6747         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
                6748         return (NULL);
                6749     }
                6750     facet->node = node;
                6751     value = xmlSchemaGetProp(ctxt, node, "value");
                6752     if (value == NULL) {
                6753         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
                6754                        "Facet %s has no value\n", node->name, NULL);
                6755         xmlSchemaFreeFacet(facet);
                6756         return (NULL);
                6757     }
                6758     if (IS_SCHEMA(node, "minInclusive")) {
                6759         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
                6760     } else if (IS_SCHEMA(node, "minExclusive")) {
                6761         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
                6762     } else if (IS_SCHEMA(node, "maxInclusive")) {
                6763         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
                6764     } else if (IS_SCHEMA(node, "maxExclusive")) {
                6765         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
                6766     } else if (IS_SCHEMA(node, "totalDigits")) {
                6767         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
                6768     } else if (IS_SCHEMA(node, "fractionDigits")) {
                6769         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
                6770     } else if (IS_SCHEMA(node, "pattern")) {
                6771         facet->type = XML_SCHEMA_FACET_PATTERN;
                6772     } else if (IS_SCHEMA(node, "enumeration")) {
                6773         facet->type = XML_SCHEMA_FACET_ENUMERATION;
                6774     } else if (IS_SCHEMA(node, "whiteSpace")) {
                6775         facet->type = XML_SCHEMA_FACET_WHITESPACE;
                6776     } else if (IS_SCHEMA(node, "length")) {
                6777         facet->type = XML_SCHEMA_FACET_LENGTH;
                6778     } else if (IS_SCHEMA(node, "maxLength")) {
                6779         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
                6780     } else if (IS_SCHEMA(node, "minLength")) {
                6781         facet->type = XML_SCHEMA_FACET_MINLENGTH;
                6782     } else {
                6783         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
                6784                        "Unknown facet type %s\n", node->name, NULL);
                6785         xmlSchemaFreeFacet(facet);
                6786         return (NULL);
                6787     }
                6788     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                6789     facet->value = value;
                6790     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
                6791     (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
                6792     const xmlChar *fixed;
                6793 
                6794     fixed = xmlSchemaGetProp(ctxt, node, "fixed");
                6795     if (fixed != NULL) {
                6796         if (xmlStrEqual(fixed, BAD_CAST "true"))
                6797         facet->fixed = 1;
                6798     }
                6799     }
                6800     child = node->children;
                6801 
                6802     if (IS_SCHEMA(child, "annotation")) {
                6803         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                6804         child = child->next;
                6805     }
                6806     if (child != NULL) {
                6807         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
                6808                        "Facet %s has unexpected child content\n",
                6809                        node->name, NULL);
                6810     }
                6811     return (facet);
                6812 }
                6813 
                6814 /**
                6815  * xmlSchemaParseWildcardNs:
                6816  * @ctxt:  a schema parser context
                6817  * @wildc:  the wildcard, already created
                6818  * @node:  a subtree containing XML Schema information
                6819  *
                6820  * Parses the attribute "processContents" and "namespace"
                6821  * of a xsd:anyAttribute and xsd:any.
                6822  * *WARNING* this interface is highly subject to change
                6823  *
                6824  * Returns 0 if everything goes fine, a positive error code
                6825  * if something is not valid and -1 if an internal error occurs.
                6826  */
                6827 static int
                6828 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
                6829              xmlSchemaPtr schema ATTRIBUTE_UNUSED,
                6830              xmlSchemaWildcardPtr wildc,
                6831              xmlNodePtr node)
                6832 {
                6833     const xmlChar *pc, *ns, *dictnsItem;
                6834     int ret = 0;
                6835     xmlChar *nsItem;
                6836     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
                6837     xmlAttrPtr attr;
                6838 
                6839     pc = xmlSchemaGetProp(ctxt, node, "processContents");
                6840     if ((pc == NULL)
                6841         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
                6842         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
                6843     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
                6844         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
                6845     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
                6846         wildc->processContents = XML_SCHEMAS_ANY_LAX;
                6847     } else {
                6848         xmlSchemaPSimpleTypeErr(ctxt,
                6849         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                6850         NULL, node,
                6851         NULL, "(strict | skip | lax)", pc,
                6852         NULL, NULL, NULL);
                6853         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
                6854     ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
                6855     }
                6856     /*
                6857      * Build the namespace constraints.
                6858      */
                6859     attr = xmlSchemaGetPropNode(node, "namespace");
                6860     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
ad7b9726c Alex*6861     if (ns == NULL)
                6862         return (-1);
9d9d4fcc3 Alex*6863     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
                6864     wildc->any = 1;
                6865     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
                6866     wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
                6867     if (wildc->negNsSet == NULL) {
                6868         return (-1);
                6869     }
                6870     wildc->negNsSet->value = ctxt->targetNamespace;
                6871     } else {
                6872     const xmlChar *end, *cur;
                6873 
                6874     cur = ns;
                6875     do {
                6876         while (IS_BLANK_CH(*cur))
                6877         cur++;
                6878         end = cur;
                6879         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                6880         end++;
                6881         if (end == cur)
                6882         break;
                6883         nsItem = xmlStrndup(cur, end - cur);
                6884         if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
                6885             (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
                6886         xmlSchemaPSimpleTypeErr(ctxt,
                6887             XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
                6888             NULL, (xmlNodePtr) attr,
                6889             NULL,
                6890             "((##any | ##other) | List of (xs:anyURI | "
                6891             "(##targetNamespace | ##local)))",
                6892             nsItem, NULL, NULL, NULL);
                6893         ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
                6894         } else {
                6895         if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
                6896             dictnsItem = ctxt->targetNamespace;
                6897         } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
                6898             dictnsItem = NULL;
                6899         } else {
                6900             /*
                6901             * Validate the item (anyURI).
                6902             */
                6903             xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
                6904             nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
                6905             dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
                6906         }
                6907         /*
                6908         * Avoid duplicate namespaces.
                6909         */
                6910         tmp = wildc->nsSet;
                6911         while (tmp != NULL) {
                6912             if (dictnsItem == tmp->value)
                6913             break;
                6914             tmp = tmp->next;
                6915         }
                6916         if (tmp == NULL) {
                6917             tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
                6918             if (tmp == NULL) {
                6919             xmlFree(nsItem);
                6920             return (-1);
                6921             }
                6922             tmp->value = dictnsItem;
                6923             tmp->next = NULL;
                6924             if (wildc->nsSet == NULL)
                6925             wildc->nsSet = tmp;
                6926             else if (lastNs != NULL)
                6927             lastNs->next = tmp;
                6928             lastNs = tmp;
                6929         }
                6930 
                6931         }
                6932         xmlFree(nsItem);
                6933         cur = end;
                6934     } while (*cur != 0);
                6935     }
                6936     return (ret);
                6937 }
                6938 
                6939 static int
                6940 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
                6941                  xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
                6942                  xmlNodePtr node,
                6943                  int minOccurs,
                6944                  int maxOccurs) {
                6945 
                6946     if ((maxOccurs == 0) && ( minOccurs == 0))
                6947     return (0);
                6948     if (maxOccurs != UNBOUNDED) {
                6949     /*
                6950     * TODO: Maybe we should better not create the particle,
                6951     * if min/max is invalid, since it could confuse the build of the
                6952     * content model.
                6953     */
                6954     /*
                6955     * 3.9.6 Schema Component Constraint: Particle Correct
                6956     *
                6957     */
                6958     if (maxOccurs < 1) {
                6959         /*
                6960         * 2.2 {max occurs} must be greater than or equal to 1.
                6961         */
                6962         xmlSchemaPCustomAttrErr(ctxt,
                6963         XML_SCHEMAP_P_PROPS_CORRECT_2_2,
                6964         NULL, NULL,
                6965         xmlSchemaGetPropNode(node, "maxOccurs"),
                6966         "The value must be greater than or equal to 1");
                6967         return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
                6968     } else if (minOccurs > maxOccurs) {
                6969         /*
                6970         * 2.1 {min occurs} must not be greater than {max occurs}.
                6971         */
                6972         xmlSchemaPCustomAttrErr(ctxt,
                6973         XML_SCHEMAP_P_PROPS_CORRECT_2_1,
                6974         NULL, NULL,
                6975         xmlSchemaGetPropNode(node, "minOccurs"),
                6976         "The value must not be greater than the value of 'maxOccurs'");
                6977         return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
                6978     }
                6979     }
                6980     return (0);
                6981 }
                6982 
                6983 /**
                6984  * xmlSchemaParseAny:
                6985  * @ctxt:  a schema validation context
                6986  * @schema:  the schema being built
                6987  * @node:  a subtree containing XML Schema information
                6988  *
                6989  * Parsea a XML schema <any> element. A particle and wildcard
                6990  * will be created (except if minOccurs==maxOccurs==0, in this case
                6991  * nothing will be created).
                6992  * *WARNING* this interface is highly subject to change
                6993  *
                6994  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
                6995  */
                6996 static xmlSchemaParticlePtr
                6997 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                6998                   xmlNodePtr node)
                6999 {
                7000     xmlSchemaParticlePtr particle;
                7001     xmlNodePtr child = NULL;
                7002     xmlSchemaWildcardPtr wild;
                7003     int min, max;
                7004     xmlAttrPtr attr;
                7005     xmlSchemaAnnotPtr annot = NULL;
                7006 
                7007     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                7008         return (NULL);
                7009     /*
                7010     * Check for illegal attributes.
                7011     */
                7012     attr = node->properties;
                7013     while (attr != NULL) {
                7014     if (attr->ns == NULL) {
                7015         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                7016         (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
                7017         (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
                7018             (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
                7019         (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
                7020         xmlSchemaPIllegalAttrErr(ctxt,
                7021             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7022         }
                7023     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                7024         xmlSchemaPIllegalAttrErr(ctxt,
                7025         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7026     }
                7027     attr = attr->next;
                7028     }
                7029     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                7030     /*
                7031     * minOccurs/maxOccurs.
                7032     */
                7033     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
                7034     "(xs:nonNegativeInteger | unbounded)");
                7035     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
                7036     "xs:nonNegativeInteger");
                7037     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
                7038     /*
                7039     * Create & parse the wildcard.
                7040     */
                7041     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
                7042     if (wild == NULL)
                7043     return (NULL);
                7044     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
                7045     /*
                7046     * And now for the children...
                7047     */
                7048     child = node->children;
                7049     if (IS_SCHEMA(child, "annotation")) {
                7050         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                7051         child = child->next;
                7052     }
                7053     if (child != NULL) {
                7054     xmlSchemaPContentErr(ctxt,
                7055         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7056         NULL, node, child,
                7057         NULL, "(annotation?)");
                7058     }
                7059     /*
                7060     * No component if minOccurs==maxOccurs==0.
                7061     */
                7062     if ((min == 0) && (max == 0)) {
                7063     /* Don't free the wildcard, since it's already on the list. */
                7064     return (NULL);
                7065     }
                7066     /*
                7067     * Create the particle.
                7068     */
                7069     particle = xmlSchemaAddParticle(ctxt, node, min, max);
                7070     if (particle == NULL)
                7071         return (NULL);
                7072     particle->annot = annot;
                7073     particle->children = (xmlSchemaTreeItemPtr) wild;
                7074 
                7075     return (particle);
                7076 }
                7077 
                7078 /**
                7079  * xmlSchemaParseNotation:
                7080  * @ctxt:  a schema validation context
                7081  * @schema:  the schema being built
                7082  * @node:  a subtree containing XML Schema information
                7083  *
                7084  * parse a XML schema Notation declaration
                7085  *
                7086  * Returns the new structure or NULL in case of error
                7087  */
                7088 static xmlSchemaNotationPtr
                7089 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                7090                        xmlNodePtr node)
                7091 {
                7092     const xmlChar *name;
                7093     xmlSchemaNotationPtr ret;
                7094     xmlNodePtr child = NULL;
                7095 
                7096     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                7097         return (NULL);
                7098     name = xmlSchemaGetProp(ctxt, node, "name");
                7099     if (name == NULL) {
                7100         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
                7101                        "Notation has no name\n", NULL, NULL);
                7102         return (NULL);
                7103     }
                7104     ret = xmlSchemaAddNotation(ctxt, schema, name,
                7105     ctxt->targetNamespace, node);
                7106     if (ret == NULL)
                7107         return (NULL);
                7108     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                7109 
                7110     child = node->children;
                7111     if (IS_SCHEMA(child, "annotation")) {
                7112         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                7113         child = child->next;
                7114     }
                7115     if (child != NULL) {
                7116     xmlSchemaPContentErr(ctxt,
                7117         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7118         NULL, node, child,
                7119         NULL, "(annotation?)");
                7120     }
                7121 
                7122     return (ret);
                7123 }
                7124 
                7125 /**
                7126  * xmlSchemaParseAnyAttribute:
                7127  * @ctxt:  a schema validation context
                7128  * @schema:  the schema being built
                7129  * @node:  a subtree containing XML Schema information
                7130  *
                7131  * parse a XML schema AnyAttribute declaration
                7132  * *WARNING* this interface is highly subject to change
                7133  *
                7134  * Returns a wildcard or NULL.
                7135  */
                7136 static xmlSchemaWildcardPtr
                7137 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
                7138                            xmlSchemaPtr schema, xmlNodePtr node)
                7139 {
                7140     xmlSchemaWildcardPtr ret;
                7141     xmlNodePtr child = NULL;
                7142     xmlAttrPtr attr;
                7143 
                7144     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                7145         return (NULL);
                7146 
                7147     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
                7148     node);
                7149     if (ret == NULL) {
                7150         return (NULL);
                7151     }
                7152     /*
                7153     * Check for illegal attributes.
                7154     */
                7155     attr = node->properties;
                7156     while (attr != NULL) {
                7157     if (attr->ns == NULL) {
                7158         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                7159             (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
                7160         (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
                7161         xmlSchemaPIllegalAttrErr(ctxt,
                7162             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7163         }
                7164     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                7165         xmlSchemaPIllegalAttrErr(ctxt,
                7166         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7167     }
                7168     attr = attr->next;
                7169     }
                7170     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                7171     /*
                7172     * Parse the namespace list.
                7173     */
                7174     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
                7175     return (NULL);
                7176     /*
                7177     * And now for the children...
                7178     */
                7179     child = node->children;
                7180     if (IS_SCHEMA(child, "annotation")) {
                7181         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                7182         child = child->next;
                7183     }
                7184     if (child != NULL) {
                7185     xmlSchemaPContentErr(ctxt,
                7186         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7187         NULL, node, child,
                7188         NULL, "(annotation?)");
                7189     }
                7190 
                7191     return (ret);
                7192 }
                7193 
                7194 
                7195 /**
                7196  * xmlSchemaParseAttribute:
                7197  * @ctxt:  a schema validation context
                7198  * @schema:  the schema being built
                7199  * @node:  a subtree containing XML Schema information
                7200  *
                7201  * parse a XML schema Attribute declaration
                7202  * *WARNING* this interface is highly subject to change
                7203  *
                7204  * Returns the attribute declaration.
                7205  */
                7206 static xmlSchemaBasicItemPtr
                7207 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
                7208                  xmlSchemaPtr schema,
                7209                  xmlNodePtr node,
                7210                  xmlSchemaItemListPtr uses,
                7211                  int parentType)
                7212 {
                7213     const xmlChar *attrValue, *name = NULL, *ns = NULL;
                7214     xmlSchemaAttributeUsePtr use = NULL;
                7215     xmlNodePtr child = NULL;
                7216     xmlAttrPtr attr;
                7217     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
                7218     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
                7219     int nberrors, hasForm = 0, defValueType = 0;
                7220 
                7221 #define WXS_ATTR_DEF_VAL_DEFAULT 1
                7222 #define WXS_ATTR_DEF_VAL_FIXED 2
                7223 
                7224     /*
                7225      * 3.2.3 Constraints on XML Representations of Attribute Declarations
                7226      */
                7227 
                7228     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
                7229         return (NULL);
                7230     attr = xmlSchemaGetPropNode(node, "ref");
                7231     if (attr != NULL) {
                7232     if (xmlSchemaPValAttrNodeQName(pctxt, schema,
                7233         NULL, attr, &tmpNs, &tmpName) != 0) {
                7234         return (NULL);
                7235     }
                7236     if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
                7237         return(NULL);
                7238     isRef = 1;
                7239     }
                7240     nberrors = pctxt->nberrors;
                7241     /*
                7242     * Check for illegal attributes.
                7243     */
                7244     attr = node->properties;
                7245     while (attr != NULL) {
                7246     if (attr->ns == NULL) {
                7247         if (isRef) {
                7248         if (xmlStrEqual(attr->name, BAD_CAST "id")) {
                7249             xmlSchemaPValAttrNodeID(pctxt, attr);
                7250             goto attr_next;
                7251         } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
                7252             goto attr_next;
                7253         }
                7254         } else {
                7255         if (xmlStrEqual(attr->name, BAD_CAST "name")) {
                7256             goto attr_next;
                7257         } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
                7258             xmlSchemaPValAttrNodeID(pctxt, attr);
                7259             goto attr_next;
                7260         } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
                7261             xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
                7262             attr, &tmpNs, &tmpName);
                7263             goto attr_next;
                7264         } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
                7265             /*
                7266             * Evaluate the target namespace
                7267             */
                7268             hasForm = 1;
                7269             attrValue = xmlSchemaGetNodeContent(pctxt,
                7270             (xmlNodePtr) attr);
                7271             if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
                7272             ns = pctxt->targetNamespace;
                7273             } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
                7274             {
                7275             xmlSchemaPSimpleTypeErr(pctxt,
                7276                 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                7277                 NULL, (xmlNodePtr) attr,
                7278                 NULL, "(qualified | unqualified)",
                7279                 attrValue, NULL, NULL, NULL);
                7280             }
                7281             goto attr_next;
                7282         }
                7283         }
                7284         if (xmlStrEqual(attr->name, BAD_CAST "use")) {
                7285 
                7286         attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
                7287         /* TODO: Maybe we need to normalize the value beforehand. */
                7288         if (xmlStrEqual(attrValue, BAD_CAST "optional"))
                7289             occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
                7290         else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
                7291             occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
                7292         else if (xmlStrEqual(attrValue, BAD_CAST "required"))
                7293             occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
                7294         else {
                7295             xmlSchemaPSimpleTypeErr(pctxt,
                7296             XML_SCHEMAP_INVALID_ATTR_USE,
                7297             NULL, (xmlNodePtr) attr,
                7298             NULL, "(optional | prohibited | required)",
                7299             attrValue, NULL, NULL, NULL);
                7300         }
                7301         goto attr_next;
                7302         } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
                7303         /*
                7304         * 3.2.3 : 1
                7305         * default and fixed must not both be present.
                7306         */
                7307         if (defValue) {
                7308             xmlSchemaPMutualExclAttrErr(pctxt,
                7309             XML_SCHEMAP_SRC_ATTRIBUTE_1,
                7310             NULL, attr, "default", "fixed");
                7311         } else {
                7312             defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
                7313             defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
                7314         }
                7315         goto attr_next;
                7316         } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
                7317         /*
                7318         * 3.2.3 : 1
                7319         * default and fixed must not both be present.
                7320         */
                7321         if (defValue) {
                7322             xmlSchemaPMutualExclAttrErr(pctxt,
                7323             XML_SCHEMAP_SRC_ATTRIBUTE_1,
                7324             NULL, attr, "default", "fixed");
                7325         } else {
                7326             defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
                7327             defValueType = WXS_ATTR_DEF_VAL_FIXED;
                7328         }
                7329         goto attr_next;
                7330         }
                7331     } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
                7332         goto attr_next;
                7333 
                7334     xmlSchemaPIllegalAttrErr(pctxt,
                7335         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7336 
                7337 attr_next:
                7338     attr = attr->next;
                7339     }
                7340     /*
                7341     * 3.2.3 : 2
                7342     * If default and use are both present, use must have
                7343     * the actual value optional.
                7344     */
                7345     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
                7346     (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
                7347     xmlSchemaPSimpleTypeErr(pctxt,
                7348         XML_SCHEMAP_SRC_ATTRIBUTE_2,
                7349         NULL, node, NULL,
                7350         "(optional | prohibited | required)", NULL,
                7351         "The value of the attribute 'use' must be 'optional' "
                7352         "if the attribute 'default' is present",
                7353         NULL, NULL);
                7354     }
                7355     /*
                7356     * We want correct attributes.
                7357     */
                7358     if (nberrors != pctxt->nberrors)
                7359     return(NULL);
                7360     if (! isRef) {
                7361     xmlSchemaAttributePtr attrDecl;
                7362 
                7363     /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
                7364     if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
                7365         ns = pctxt->targetNamespace;
                7366     /*
                7367     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
                7368     * TODO: Move this to the component layer.
                7369     */
                7370     if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
                7371         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                7372         XML_SCHEMAP_NO_XSI,
                7373         node, NULL,
                7374         "The target namespace must not match '%s'",
                7375         xmlSchemaInstanceNs, NULL);
                7376     }
                7377     attr = xmlSchemaGetPropNode(node, "name");
                7378     if (attr == NULL) {
                7379         xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
                7380         NULL, node, "name", NULL);
                7381         return (NULL);
                7382     }
                7383     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
                7384         xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
                7385         return (NULL);
                7386     }
                7387     /*
                7388     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
                7389     * TODO: Move this to the component layer.
                7390     */
                7391     if (xmlStrEqual(name, BAD_CAST "xmlns")) {
                7392         xmlSchemaPSimpleTypeErr(pctxt,
                7393         XML_SCHEMAP_NO_XMLNS,
                7394         NULL, (xmlNodePtr) attr,
                7395         xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
                7396         "The value of the attribute must not match 'xmlns'",
                7397         NULL, NULL);
                7398         return (NULL);
                7399     }
                7400     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
                7401         goto check_children;
                7402     /*
                7403     * Create the attribute use component.
                7404     */
                7405     use = xmlSchemaAddAttributeUse(pctxt, node);
                7406     if (use == NULL)
                7407         return(NULL);
                7408     use->occurs = occurs;
                7409     /*
                7410     * Create the attribute declaration.
                7411     */
                7412     attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
                7413     if (attrDecl == NULL)
                7414         return (NULL);
                7415     if (tmpName != NULL) {
                7416         attrDecl->typeName = tmpName;
                7417         attrDecl->typeNs = tmpNs;
                7418     }
                7419     use->attrDecl = attrDecl;
                7420     /*
                7421     * Value constraint.
                7422     */
                7423     if (defValue != NULL) {
                7424         attrDecl->defValue = defValue;
                7425         if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
                7426         attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
                7427     }
                7428     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
                7429     xmlSchemaQNameRefPtr ref;
                7430 
                7431     /*
                7432     * Create the attribute use component.
                7433     */
                7434     use = xmlSchemaAddAttributeUse(pctxt, node);
                7435     if (use == NULL)
                7436         return(NULL);
                7437     /*
                7438     * We need to resolve the reference at later stage.
                7439     */
                7440     WXS_ADD_PENDING(pctxt, use);
                7441     use->occurs = occurs;
                7442     /*
                7443     * Create a QName reference to the attribute declaration.
                7444     */
                7445     ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
                7446         tmpName, tmpNs);
                7447     if (ref == NULL)
                7448         return(NULL);
                7449     /*
                7450     * Assign the reference. This will be substituted for the
                7451     * referenced attribute declaration when the QName is resolved.
                7452     */
                7453     use->attrDecl = WXS_ATTR_CAST ref;
                7454     /*
                7455     * Value constraint.
                7456     */
                7457     if (defValue != NULL)
                7458         use->defValue = defValue;
                7459     if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
                7460         use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
                7461     }
                7462 
                7463 check_children:
                7464     /*
                7465     * And now for the children...
                7466     */
                7467     child = node->children;
                7468     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
                7469     xmlSchemaAttributeUseProhibPtr prohib;
                7470 
                7471     if (IS_SCHEMA(child, "annotation")) {
                7472         xmlSchemaParseAnnotation(pctxt, child, 0);
                7473         child = child->next;
                7474     }
                7475     if (child != NULL) {
                7476         xmlSchemaPContentErr(pctxt,
                7477         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7478         NULL, node, child, NULL,
                7479         "(annotation?)");
                7480     }
                7481     /*
                7482     * Check for pointlessness of attribute prohibitions.
                7483     */
                7484     if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
                7485         xmlSchemaCustomWarning(ACTXT_CAST pctxt,
                7486         XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
                7487         node, NULL,
                7488         "Skipping attribute use prohibition, since it is "
                7489         "pointless inside an <attributeGroup>",
                7490         NULL, NULL, NULL);
                7491         return(NULL);
                7492     } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
                7493         xmlSchemaCustomWarning(ACTXT_CAST pctxt,
                7494         XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
                7495         node, NULL,
                7496         "Skipping attribute use prohibition, since it is "
                7497         "pointless when extending a type",
                7498         NULL, NULL, NULL);
                7499         return(NULL);
                7500     }
                7501     if (! isRef) {
                7502         tmpName = name;
                7503         tmpNs = ns;
                7504     }
                7505     /*
                7506     * Check for duplicate attribute prohibitions.
                7507     */
                7508     if (uses) {
                7509         int i;
                7510 
                7511         for (i = 0; i < uses->nbItems; i++) {
                7512         use = uses->items[i];
                7513         if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
                7514             (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
                7515             (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
                7516         {
                7517             xmlChar *str = NULL;
                7518 
                7519             xmlSchemaCustomWarning(ACTXT_CAST pctxt,
                7520             XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
                7521             node, NULL,
                7522             "Skipping duplicate attribute use prohibition '%s'",
                7523             xmlSchemaFormatQName(&str, tmpNs, tmpName),
                7524             NULL, NULL);
                7525             FREE_AND_NULL(str)
                7526             return(NULL);
                7527         }
                7528         }
                7529     }
                7530     /*
                7531     * Create the attribute prohibition helper component.
                7532     */
                7533     prohib = xmlSchemaAddAttributeUseProhib(pctxt);
                7534     if (prohib == NULL)
                7535         return(NULL);
                7536     prohib->node = node;
                7537     prohib->name = tmpName;
                7538     prohib->targetNamespace = tmpNs;
                7539     if (isRef) {
                7540         /*
                7541         * We need at least to resolve to the attribute declaration.
                7542         */
                7543         WXS_ADD_PENDING(pctxt, prohib);
                7544     }
                7545     return(WXS_BASIC_CAST prohib);
                7546     } else {
                7547     if (IS_SCHEMA(child, "annotation")) {
                7548         /*
                7549         * TODO: Should this go into the attr decl?
                7550         */
                7551         use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
                7552         child = child->next;
                7553     }
                7554     if (isRef) {
                7555         if (child != NULL) {
                7556         if (IS_SCHEMA(child, "simpleType"))
                7557             /*
                7558             * 3.2.3 : 3.2
                7559             * If ref is present, then all of <simpleType>,
                7560             * form and type must be absent.
                7561             */
                7562             xmlSchemaPContentErr(pctxt,
                7563             XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
                7564             NULL, node, child, NULL,
                7565             "(annotation?)");
                7566         else
                7567             xmlSchemaPContentErr(pctxt,
                7568             XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7569             NULL, node, child, NULL,
                7570             "(annotation?)");
                7571         }
                7572     } else {
                7573         if (IS_SCHEMA(child, "simpleType")) {
                7574         if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
                7575             /*
                7576             * 3.2.3 : 4
                7577             * type and <simpleType> must not both be present.
                7578             */
                7579             xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
                7580             NULL, node, child,
                7581             "The attribute 'type' and the <simpleType> child "
                7582             "are mutually exclusive", NULL);
                7583         } else
                7584             WXS_ATTRUSE_TYPEDEF(use) =
                7585             xmlSchemaParseSimpleType(pctxt, schema, child, 0);
                7586         child = child->next;
                7587         }
                7588         if (child != NULL)
                7589         xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7590         NULL, node, child, NULL,
                7591         "(annotation?, simpleType?)");
                7592     }
                7593     }
                7594     return (WXS_BASIC_CAST use);
                7595 }
                7596 
                7597 
                7598 static xmlSchemaAttributePtr
                7599 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
                7600                   xmlSchemaPtr schema,
                7601                   xmlNodePtr node)
                7602 {
                7603     const xmlChar *attrValue;
                7604     xmlSchemaAttributePtr ret;
                7605     xmlNodePtr child = NULL;
                7606     xmlAttrPtr attr;
                7607 
                7608     /*
                7609      * Note that the w3c spec assumes the schema to be validated with schema
                7610      * for schemas beforehand.
                7611      *
                7612      * 3.2.3 Constraints on XML Representations of Attribute Declarations
                7613      */
                7614     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
                7615         return (NULL);
                7616     /*
                7617     * 3.2.3 : 3.1
                7618     * One of ref or name must be present, but not both
                7619     */
                7620     attr = xmlSchemaGetPropNode(node, "name");
                7621     if (attr == NULL) {
                7622     xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
                7623         NULL, node, "name", NULL);
                7624     return (NULL);
                7625     }
                7626     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
                7627     xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
                7628     return (NULL);
                7629     }
                7630     /*
                7631     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
                7632     * TODO: Move this to the component layer.
                7633     */
                7634     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
                7635     xmlSchemaPSimpleTypeErr(pctxt,
                7636         XML_SCHEMAP_NO_XMLNS,
                7637         NULL, (xmlNodePtr) attr,
                7638         xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
                7639         "The value of the attribute must not match 'xmlns'",
                7640         NULL, NULL);
                7641     return (NULL);
                7642     }
                7643     /*
                7644     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
                7645     * TODO: Move this to the component layer.
                7646     *       Or better leave it here and add it to the component layer
                7647     *       if we have a schema construction API.
                7648     */
                7649     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
                7650     xmlSchemaCustomErr(ACTXT_CAST pctxt,
                7651         XML_SCHEMAP_NO_XSI, node, NULL,
                7652         "The target namespace must not match '%s'",
                7653         xmlSchemaInstanceNs, NULL);
                7654     }
                7655 
                7656     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
                7657     pctxt->targetNamespace, node, 1);
                7658     if (ret == NULL)
                7659     return (NULL);
                7660     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
                7661 
                7662     /*
                7663     * Check for illegal attributes.
                7664     */
                7665     attr = node->properties;
                7666     while (attr != NULL) {
                7667     if (attr->ns == NULL) {
                7668         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                7669         (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
                7670         (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
                7671         (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
                7672         (!xmlStrEqual(attr->name, BAD_CAST "type")))
                7673         {
                7674         xmlSchemaPIllegalAttrErr(pctxt,
                7675             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7676         }
                7677     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                7678         xmlSchemaPIllegalAttrErr(pctxt,
                7679         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7680     }
                7681     attr = attr->next;
                7682     }
                7683     xmlSchemaPValAttrQName(pctxt, schema, NULL,
                7684     node, "type", &ret->typeNs, &ret->typeName);
                7685 
                7686     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
                7687     /*
                7688     * Attribute "fixed".
                7689     */
                7690     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
                7691     if (ret->defValue != NULL)
                7692     ret->flags |= XML_SCHEMAS_ATTR_FIXED;
                7693     /*
                7694     * Attribute "default".
                7695     */
                7696     attr = xmlSchemaGetPropNode(node, "default");
                7697     if (attr != NULL) {
                7698     /*
                7699     * 3.2.3 : 1
                7700     * default and fixed must not both be present.
                7701     */
                7702     if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
                7703         xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
                7704         WXS_BASIC_CAST ret, attr, "default", "fixed");
                7705     } else
                7706         ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
                7707     }
                7708     /*
                7709     * And now for the children...
                7710     */
                7711     child = node->children;
                7712     if (IS_SCHEMA(child, "annotation")) {
                7713         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
                7714         child = child->next;
                7715     }
                7716     if (IS_SCHEMA(child, "simpleType")) {
                7717     if (ret->typeName != NULL) {
                7718         /*
                7719         * 3.2.3 : 4
                7720         * type and <simpleType> must not both be present.
                7721         */
                7722         xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
                7723         NULL, node, child,
                7724         "The attribute 'type' and the <simpleType> child "
                7725         "are mutually exclusive", NULL);
                7726     } else
                7727         ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
                7728     child = child->next;
                7729     }
                7730     if (child != NULL)
                7731     xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7732         NULL, node, child, NULL,
                7733         "(annotation?, simpleType?)");
                7734 
                7735     return (ret);
                7736 }
                7737 
                7738 /**
                7739  * xmlSchemaParseAttributeGroupRef:
                7740  * @ctxt:  a schema validation context
                7741  * @schema:  the schema being built
                7742  * @node:  a subtree containing XML Schema information
                7743  *
                7744  * Parse an attribute group definition reference.
                7745  * Note that a reference to an attribute group does not
                7746  * correspond to any component at all.
                7747  * *WARNING* this interface is highly subject to change
                7748  *
                7749  * Returns the attribute group or NULL in case of error.
                7750  */
                7751 static xmlSchemaQNameRefPtr
                7752 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
                7753                 xmlSchemaPtr schema,
                7754                 xmlNodePtr node)
                7755 {
                7756     xmlSchemaQNameRefPtr ret;
                7757     xmlNodePtr child = NULL;
                7758     xmlAttrPtr attr;
                7759     const xmlChar *refNs = NULL, *ref = NULL;
                7760 
                7761     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
                7762         return (NULL);
                7763 
                7764     attr = xmlSchemaGetPropNode(node, "ref");
                7765     if (attr == NULL) {
                7766     xmlSchemaPMissingAttrErr(pctxt,
                7767         XML_SCHEMAP_S4S_ATTR_MISSING,
                7768         NULL, node, "ref", NULL);
                7769     return (NULL);
                7770     }
                7771     xmlSchemaPValAttrNodeQName(pctxt, schema,
                7772     NULL, attr, &refNs, &ref);
                7773     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
                7774     return(NULL);
                7775 
                7776     /*
                7777     * Check for illegal attributes.
                7778     */
                7779     attr = node->properties;
                7780     while (attr != NULL) {
                7781     if (attr->ns == NULL) {
                7782         if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
                7783         (!xmlStrEqual(attr->name, BAD_CAST "id")))
                7784         {
                7785         xmlSchemaPIllegalAttrErr(pctxt,
                7786             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7787         }
                7788     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                7789         xmlSchemaPIllegalAttrErr(pctxt,
                7790         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7791     }
                7792     attr = attr->next;
                7793     }
                7794     /* Attribute ID */
                7795     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
                7796 
                7797     /*
                7798     * And now for the children...
                7799     */
                7800     child = node->children;
                7801     if (IS_SCHEMA(child, "annotation")) {
                7802     /*
                7803     * TODO: We do not have a place to store the annotation, do we?
                7804     */
                7805         xmlSchemaParseAnnotation(pctxt, child, 0);
                7806         child = child->next;
                7807     }
                7808     if (child != NULL) {
                7809     xmlSchemaPContentErr(pctxt,
                7810         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7811         NULL, node, child, NULL,
                7812         "(annotation?)");
                7813     }
                7814 
                7815     /*
                7816     * Handle attribute group redefinitions.
                7817     */
                7818     if (pctxt->isRedefine && pctxt->redef &&
                7819     (pctxt->redef->item->type ==
                7820         XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
                7821     (ref == pctxt->redef->refName) &&
                7822     (refNs == pctxt->redef->refTargetNs))
                7823     {
                7824     /*
                7825     * SPEC src-redefine:
                7826     * (7.1) "If it has an <attributeGroup> among its contents
                7827     * the `actual value` of whose ref [attribute] is the same
                7828     * as the `actual value` of its own name attribute plus
                7829     * target namespace, then it must have exactly one such group."
                7830     */
                7831     if (pctxt->redefCounter != 0) {
                7832         xmlChar *str = NULL;
                7833 
                7834         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                7835         XML_SCHEMAP_SRC_REDEFINE, node, NULL,
                7836         "The redefining attribute group definition "
                7837         "'%s' must not contain more than one "
                7838         "reference to the redefined definition",
                7839         xmlSchemaFormatQName(&str, refNs, ref), NULL);
                7840         FREE_AND_NULL(str);
                7841         return(NULL);
                7842     }
                7843     pctxt->redefCounter++;
                7844     /*
                7845     * URGENT TODO: How to ensure that the reference will not be
                7846     * handled by the normal component resolution mechanism?
                7847     */
                7848     ret = xmlSchemaNewQNameRef(pctxt,
                7849         XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
                7850     if (ret == NULL)
                7851         return(NULL);
                7852     ret->node = node;
                7853     pctxt->redef->reference = WXS_BASIC_CAST ret;
                7854     } else {
                7855     /*
                7856     * Create a QName-reference helper component. We will substitute this
                7857     * component for the attribute uses of the referenced attribute group
                7858     * definition.
                7859     */
                7860     ret = xmlSchemaNewQNameRef(pctxt,
                7861         XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
                7862     if (ret == NULL)
                7863         return(NULL);
                7864     ret->node = node;
                7865     /* Add to pending items, to be able to resolve the reference. */
                7866     WXS_ADD_PENDING(pctxt, ret);
                7867     }
                7868     return (ret);
                7869 }
                7870 
                7871 /**
                7872  * xmlSchemaParseAttributeGroupDefinition:
                7873  * @pctxt:  a schema validation context
                7874  * @schema:  the schema being built
                7875  * @node:  a subtree containing XML Schema information
                7876  *
                7877  * parse a XML schema Attribute Group declaration
                7878  * *WARNING* this interface is highly subject to change
                7879  *
                7880  * Returns the attribute group definition or NULL in case of error.
                7881  */
                7882 static xmlSchemaAttributeGroupPtr
                7883 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
                7884                        xmlSchemaPtr schema,
                7885                        xmlNodePtr node)
                7886 {
                7887     const xmlChar *name;
                7888     xmlSchemaAttributeGroupPtr ret;
                7889     xmlNodePtr child = NULL;
                7890     xmlAttrPtr attr;
                7891     int hasRefs = 0;
                7892 
                7893     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
                7894         return (NULL);
                7895 
                7896     attr = xmlSchemaGetPropNode(node, "name");
                7897     if (attr == NULL) {
                7898     xmlSchemaPMissingAttrErr(pctxt,
                7899         XML_SCHEMAP_S4S_ATTR_MISSING,
                7900         NULL, node, "name", NULL);
                7901     return (NULL);
                7902     }
                7903     /*
                7904     * The name is crucial, exit if invalid.
                7905     */
                7906     if (xmlSchemaPValAttrNode(pctxt,
                7907     NULL, attr,
                7908     xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
                7909     return (NULL);
                7910     }
                7911     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
                7912     name, pctxt->targetNamespace, node);
                7913     if (ret == NULL)
                7914     return (NULL);
                7915     /*
                7916     * Check for illegal attributes.
                7917     */
                7918     attr = node->properties;
                7919     while (attr != NULL) {
                7920     if (attr->ns == NULL) {
                7921         if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
                7922         (!xmlStrEqual(attr->name, BAD_CAST "id")))
                7923         {
                7924         xmlSchemaPIllegalAttrErr(pctxt,
                7925             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7926         }
                7927     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                7928         xmlSchemaPIllegalAttrErr(pctxt,
                7929         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                7930     }
                7931     attr = attr->next;
                7932     }
                7933     /* Attribute ID */
                7934     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
                7935     /*
                7936     * And now for the children...
                7937     */
                7938     child = node->children;
                7939     if (IS_SCHEMA(child, "annotation")) {
                7940         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
                7941         child = child->next;
                7942     }
                7943     /*
                7944     * Parse contained attribute decls/refs.
                7945     */
                7946     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
                7947     (xmlSchemaItemListPtr *) &(ret->attrUses),
                7948     XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
                7949     return(NULL);
                7950     if (hasRefs)
                7951     ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
                7952     /*
                7953     * Parse the attribute wildcard.
                7954     */
                7955     if (IS_SCHEMA(child, "anyAttribute")) {
                7956     ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
                7957         schema, child);
                7958     child = child->next;
                7959     }
                7960     if (child != NULL) {
                7961     xmlSchemaPContentErr(pctxt,
                7962         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                7963         NULL, node, child, NULL,
                7964         "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
                7965     }
                7966     return (ret);
                7967 }
                7968 
                7969 /**
                7970  * xmlSchemaPValAttrFormDefault:
                7971  * @value:  the value
                7972  * @flags: the flags to be modified
                7973  * @flagQualified: the specific flag for "qualified"
                7974  *
                7975  * Returns 0 if the value is valid, 1 otherwise.
                7976  */
                7977 static int
                7978 xmlSchemaPValAttrFormDefault(const xmlChar *value,
                7979                  int *flags,
                7980                  int flagQualified)
                7981 {
                7982     if (xmlStrEqual(value, BAD_CAST "qualified")) {
                7983     if  ((*flags & flagQualified) == 0)
                7984         *flags |= flagQualified;
                7985     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
                7986     return (1);
                7987 
                7988     return (0);
                7989 }
                7990 
                7991 /**
                7992  * xmlSchemaPValAttrBlockFinal:
                7993  * @value:  the value
                7994  * @flags: the flags to be modified
                7995  * @flagAll: the specific flag for "#all"
                7996  * @flagExtension: the specific flag for "extension"
                7997  * @flagRestriction: the specific flag for "restriction"
                7998  * @flagSubstitution: the specific flag for "substitution"
                7999  * @flagList: the specific flag for "list"
                8000  * @flagUnion: the specific flag for "union"
                8001  *
                8002  * Validates the value of the attribute "final" and "block". The value
                8003  * is converted into the specified flag values and returned in @flags.
                8004  *
                8005  * Returns 0 if the value is valid, 1 otherwise.
                8006  */
                8007 
                8008 static int
                8009 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
                8010                 int *flags,
                8011                 int flagAll,
                8012                 int flagExtension,
                8013                 int flagRestriction,
                8014                 int flagSubstitution,
                8015                 int flagList,
                8016                 int flagUnion)
                8017 {
                8018     int ret = 0;
                8019 
                8020     /*
                8021     * TODO: This does not check for duplicate entries.
                8022     */
                8023     if ((flags == NULL) || (value == NULL))
                8024     return (-1);
                8025     if (value[0] == 0)
                8026     return (0);
                8027     if (xmlStrEqual(value, BAD_CAST "#all")) {
                8028     if (flagAll != -1)
                8029         *flags |= flagAll;
                8030     else {
                8031         if (flagExtension != -1)
                8032         *flags |= flagExtension;
                8033         if (flagRestriction != -1)
                8034         *flags |= flagRestriction;
                8035         if (flagSubstitution != -1)
                8036         *flags |= flagSubstitution;
                8037         if (flagList != -1)
                8038         *flags |= flagList;
                8039         if (flagUnion != -1)
                8040         *flags |= flagUnion;
                8041     }
                8042     } else {
                8043     const xmlChar *end, *cur = value;
                8044     xmlChar *item;
                8045 
                8046     do {
                8047         while (IS_BLANK_CH(*cur))
                8048         cur++;
                8049         end = cur;
                8050         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                8051         end++;
                8052         if (end == cur)
                8053         break;
                8054         item = xmlStrndup(cur, end - cur);
                8055         if (xmlStrEqual(item, BAD_CAST "extension")) {
                8056         if (flagExtension != -1) {
                8057             if ((*flags & flagExtension) == 0)
                8058             *flags |= flagExtension;
                8059         } else
                8060             ret = 1;
                8061         } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
                8062         if (flagRestriction != -1) {
                8063             if ((*flags & flagRestriction) == 0)
                8064             *flags |= flagRestriction;
                8065         } else
                8066             ret = 1;
                8067         } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
                8068         if (flagSubstitution != -1) {
                8069             if ((*flags & flagSubstitution) == 0)
                8070             *flags |= flagSubstitution;
                8071         } else
                8072             ret = 1;
                8073         } else if (xmlStrEqual(item, BAD_CAST "list")) {
                8074         if (flagList != -1) {
                8075             if ((*flags & flagList) == 0)
                8076             *flags |= flagList;
                8077         } else
                8078             ret = 1;
                8079         } else if (xmlStrEqual(item, BAD_CAST "union")) {
                8080         if (flagUnion != -1) {
                8081             if ((*flags & flagUnion) == 0)
                8082             *flags |= flagUnion;
                8083         } else
                8084             ret = 1;
                8085         } else
                8086         ret = 1;
                8087         if (item != NULL)
                8088         xmlFree(item);
                8089         cur = end;
                8090     } while ((ret == 0) && (*cur != 0));
                8091     }
                8092 
                8093     return (ret);
                8094 }
                8095 
                8096 static int
                8097 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
                8098                  xmlSchemaIDCPtr idc,
                8099                  xmlSchemaIDCSelectPtr selector,
                8100                  xmlAttrPtr attr,
                8101                  int isField)
                8102 {
                8103     xmlNodePtr node;
                8104 
                8105     /*
                8106     * c-selector-xpath:
                8107     * Schema Component Constraint: Selector Value OK
                8108     *
                8109     * TODO: 1 The {selector} must be a valid XPath expression, as defined
                8110     * in [XPath].
                8111     */
                8112     if (selector == NULL) {
                8113     xmlSchemaPErr(ctxt, idc->node,
                8114         XML_SCHEMAP_INTERNAL,
                8115         "Internal error: xmlSchemaCheckCSelectorXPath, "
                8116         "the selector is not specified.\n", NULL, NULL);
                8117     return (-1);
                8118     }
                8119     if (attr == NULL)
                8120     node = idc->node;
                8121     else
                8122     node = (xmlNodePtr) attr;
                8123     if (selector->xpath == NULL) {
                8124     xmlSchemaPCustomErr(ctxt,
                8125         /* TODO: Adjust error code. */
                8126         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                8127         NULL, node,
                8128         "The XPath expression of the selector is not valid", NULL);
                8129     return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
                8130     } else {
                8131     const xmlChar **nsArray = NULL;
                8132     xmlNsPtr *nsList = NULL;
                8133     /*
                8134     * Compile the XPath expression.
                8135     */
                8136     /*
                8137     * TODO: We need the array of in-scope namespaces for compilation.
                8138     * TODO: Call xmlPatterncompile with different options for selector/
                8139     * field.
                8140     */
                8141     if (attr == NULL)
                8142         nsList = NULL;
                8143     else
                8144         nsList = xmlGetNsList(attr->doc, attr->parent);
                8145     /*
                8146     * Build an array of prefixes and namespaces.
                8147     */
                8148     if (nsList != NULL) {
                8149         int i, count = 0;
                8150 
                8151         for (i = 0; nsList[i] != NULL; i++)
                8152         count++;
                8153 
                8154         nsArray = (const xmlChar **) xmlMalloc(
                8155         (count * 2 + 1) * sizeof(const xmlChar *));
                8156         if (nsArray == NULL) {
                8157         xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
                8158             NULL);
                8159         xmlFree(nsList);
                8160         return (-1);
                8161         }
                8162         for (i = 0; i < count; i++) {
                8163         nsArray[2 * i] = nsList[i]->href;
                8164         nsArray[2 * i + 1] = nsList[i]->prefix;
                8165         }
                8166         nsArray[count * 2] = NULL;
                8167         xmlFree(nsList);
                8168     }
                8169     /*
                8170     * TODO: Differentiate between "selector" and "field".
                8171     */
                8172     if (isField)
                8173         selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
                8174         NULL, XML_PATTERN_XSFIELD, nsArray);
                8175     else
                8176         selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
                8177         NULL, XML_PATTERN_XSSEL, nsArray);
                8178     if (nsArray != NULL)
                8179         xmlFree((xmlChar **) nsArray);
                8180 
                8181     if (selector->xpathComp == NULL) {
                8182         xmlSchemaPCustomErr(ctxt,
                8183         /* TODO: Adjust error code? */
                8184         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                8185         NULL, node,
                8186         "The XPath expression '%s' could not be "
                8187         "compiled", selector->xpath);
                8188         return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
                8189     }
                8190     }
                8191     return (0);
                8192 }
                8193 
                8194 #define ADD_ANNOTATION(annot)   \
                8195     xmlSchemaAnnotPtr cur = item->annot; \
                8196     if (item->annot == NULL) {  \
                8197     item->annot = annot;    \
                8198     return (annot);         \
                8199     }                           \
                8200     cur = item->annot;          \
                8201     if (cur->next != NULL) {    \
                8202     cur = cur->next;    \
                8203     }                           \
                8204     cur->next = annot;
                8205 
                8206 /**
                8207  * xmlSchemaAssignAnnotation:
                8208  * @item: the schema component
                8209  * @annot: the annotation
                8210  *
                8211  * Adds the annotation to the given schema component.
                8212  *
                8213  * Returns the given annotation.
                8214  */
                8215 static xmlSchemaAnnotPtr
                8216 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
                8217                xmlSchemaAnnotPtr annot)
                8218 {
                8219     if ((annItem == NULL) || (annot == NULL))
                8220     return (NULL);
                8221     switch (annItem->type) {
                8222     case XML_SCHEMA_TYPE_ELEMENT: {
                8223         xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
                8224         ADD_ANNOTATION(annot)
                8225         }
                8226         break;
                8227     case XML_SCHEMA_TYPE_ATTRIBUTE: {
                8228         xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
                8229         ADD_ANNOTATION(annot)
                8230         }
                8231         break;
                8232     case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
                8233     case XML_SCHEMA_TYPE_ANY: {
                8234         xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
                8235         ADD_ANNOTATION(annot)
                8236         }
                8237         break;
                8238     case XML_SCHEMA_TYPE_PARTICLE:
                8239     case XML_SCHEMA_TYPE_IDC_KEY:
                8240     case XML_SCHEMA_TYPE_IDC_KEYREF:
                8241     case XML_SCHEMA_TYPE_IDC_UNIQUE: {
                8242         xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
                8243         ADD_ANNOTATION(annot)
                8244         }
                8245         break;
                8246     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
                8247         xmlSchemaAttributeGroupPtr item =
                8248             (xmlSchemaAttributeGroupPtr) annItem;
                8249         ADD_ANNOTATION(annot)
                8250         }
                8251         break;
                8252     case XML_SCHEMA_TYPE_NOTATION: {
                8253         xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
                8254         ADD_ANNOTATION(annot)
                8255         }
                8256         break;
                8257     case XML_SCHEMA_FACET_MININCLUSIVE:
                8258     case XML_SCHEMA_FACET_MINEXCLUSIVE:
                8259     case XML_SCHEMA_FACET_MAXINCLUSIVE:
                8260     case XML_SCHEMA_FACET_MAXEXCLUSIVE:
                8261     case XML_SCHEMA_FACET_TOTALDIGITS:
                8262     case XML_SCHEMA_FACET_FRACTIONDIGITS:
                8263     case XML_SCHEMA_FACET_PATTERN:
                8264     case XML_SCHEMA_FACET_ENUMERATION:
                8265     case XML_SCHEMA_FACET_WHITESPACE:
                8266     case XML_SCHEMA_FACET_LENGTH:
                8267     case XML_SCHEMA_FACET_MAXLENGTH:
                8268     case XML_SCHEMA_FACET_MINLENGTH: {
                8269         xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
                8270         ADD_ANNOTATION(annot)
                8271         }
                8272         break;
                8273     case XML_SCHEMA_TYPE_SIMPLE:
                8274     case XML_SCHEMA_TYPE_COMPLEX: {
                8275         xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
                8276         ADD_ANNOTATION(annot)
                8277         }
                8278         break;
                8279     case XML_SCHEMA_TYPE_GROUP: {
                8280         xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
                8281         ADD_ANNOTATION(annot)
                8282         }
                8283         break;
                8284     case XML_SCHEMA_TYPE_SEQUENCE:
                8285     case XML_SCHEMA_TYPE_CHOICE:
                8286     case XML_SCHEMA_TYPE_ALL: {
                8287         xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
                8288         ADD_ANNOTATION(annot)
                8289         }
                8290         break;
                8291     default:
                8292          xmlSchemaPCustomErr(NULL,
                8293         XML_SCHEMAP_INTERNAL,
                8294         NULL, NULL,
                8295         "Internal error: xmlSchemaAddAnnotation, "
                8296         "The item is not a annotated schema component", NULL);
                8297          break;
                8298     }
                8299     return (annot);
                8300 }
                8301 
                8302 /**
                8303  * xmlSchemaParseIDCSelectorAndField:
                8304  * @ctxt:  a schema validation context
                8305  * @schema:  the schema being built
                8306  * @node:  a subtree containing XML Schema information
                8307  *
                8308  * Parses a XML Schema identity-constraint definition's
                8309  * <selector> and <field> elements.
                8310  *
                8311  * Returns the parsed identity-constraint definition.
                8312  */
                8313 static xmlSchemaIDCSelectPtr
                8314 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
                8315               xmlSchemaIDCPtr idc,
                8316               xmlNodePtr node,
                8317               int isField)
                8318 {
                8319     xmlSchemaIDCSelectPtr item;
                8320     xmlNodePtr child = NULL;
                8321     xmlAttrPtr attr;
                8322 
                8323     /*
                8324     * Check for illegal attributes.
                8325     */
                8326     attr = node->properties;
                8327     while (attr != NULL) {
                8328     if (attr->ns == NULL) {
                8329         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                8330         (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
                8331         xmlSchemaPIllegalAttrErr(ctxt,
                8332             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8333         }
                8334     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                8335         xmlSchemaPIllegalAttrErr(ctxt,
                8336         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8337     }
                8338     attr = attr->next;
                8339     }
                8340     /*
                8341     * Create the item.
                8342     */
                8343     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
                8344     if (item == NULL) {
                8345         xmlSchemaPErrMemory(ctxt,
                8346         "allocating a 'selector' of an identity-constraint definition",
                8347         NULL);
                8348         return (NULL);
                8349     }
                8350     memset(item, 0, sizeof(xmlSchemaIDCSelect));
                8351     /*
                8352     * Attribute "xpath" (mandatory).
                8353     */
                8354     attr = xmlSchemaGetPropNode(node, "xpath");
                8355     if (attr == NULL) {
                8356     xmlSchemaPMissingAttrErr(ctxt,
                8357         XML_SCHEMAP_S4S_ATTR_MISSING,
                8358         NULL, node,
                8359         "name", NULL);
                8360     } else {
                8361     item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                8362     /*
                8363     * URGENT TODO: "field"s have an other syntax than "selector"s.
                8364     */
                8365 
                8366     if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
                8367         isField) == -1) {
                8368         xmlSchemaPErr(ctxt,
                8369         (xmlNodePtr) attr,
                8370         XML_SCHEMAP_INTERNAL,
                8371         "Internal error: xmlSchemaParseIDCSelectorAndField, "
                8372         "validating the XPath expression of a IDC selector.\n",
                8373         NULL, NULL);
                8374     }
                8375 
                8376     }
                8377     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                8378     /*
                8379     * And now for the children...
                8380     */
                8381     child = node->children;
                8382     if (IS_SCHEMA(child, "annotation")) {
                8383     /*
                8384     * Add the annotation to the parent IDC.
                8385     */
                8386     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
                8387         xmlSchemaParseAnnotation(ctxt, child, 1));
                8388     child = child->next;
                8389     }
                8390     if (child != NULL) {
                8391     xmlSchemaPContentErr(ctxt,
                8392         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                8393         NULL, node, child,
                8394         NULL, "(annotation?)");
                8395     }
                8396 
                8397     return (item);
                8398 }
                8399 
                8400 /**
                8401  * xmlSchemaParseIDC:
                8402  * @ctxt:  a schema validation context
                8403  * @schema:  the schema being built
                8404  * @node:  a subtree containing XML Schema information
                8405  *
                8406  * Parses a XML Schema identity-constraint definition.
                8407  *
                8408  * Returns the parsed identity-constraint definition.
                8409  */
                8410 static xmlSchemaIDCPtr
                8411 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
                8412           xmlSchemaPtr schema,
                8413           xmlNodePtr node,
                8414           xmlSchemaTypeType idcCategory,
                8415           const xmlChar *targetNamespace)
                8416 {
                8417     xmlSchemaIDCPtr item = NULL;
                8418     xmlNodePtr child = NULL;
                8419     xmlAttrPtr attr;
                8420     const xmlChar *name = NULL;
                8421     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
                8422 
                8423     /*
                8424     * Check for illegal attributes.
                8425     */
                8426     attr = node->properties;
                8427     while (attr != NULL) {
                8428     if (attr->ns == NULL) {
                8429         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                8430         (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
                8431         ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
                8432          (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
                8433         xmlSchemaPIllegalAttrErr(ctxt,
                8434             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8435         }
                8436     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                8437         xmlSchemaPIllegalAttrErr(ctxt,
                8438         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8439     }
                8440     attr = attr->next;
                8441     }
                8442     /*
                8443     * Attribute "name" (mandatory).
                8444     */
                8445     attr = xmlSchemaGetPropNode(node, "name");
                8446     if (attr == NULL) {
                8447     xmlSchemaPMissingAttrErr(ctxt,
                8448         XML_SCHEMAP_S4S_ATTR_MISSING,
                8449         NULL, node,
                8450         "name", NULL);
                8451     return (NULL);
                8452     } else if (xmlSchemaPValAttrNode(ctxt,
                8453     NULL, attr,
                8454     xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
                8455     return (NULL);
                8456     }
                8457     /* Create the component. */
                8458     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
                8459     idcCategory, node);
                8460     if (item == NULL)
                8461     return(NULL);
                8462 
                8463     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                8464     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
                8465     /*
                8466     * Attribute "refer" (mandatory).
                8467     */
                8468     attr = xmlSchemaGetPropNode(node, "refer");
                8469     if (attr == NULL) {
                8470         xmlSchemaPMissingAttrErr(ctxt,
                8471         XML_SCHEMAP_S4S_ATTR_MISSING,
                8472         NULL, node,
                8473         "refer", NULL);
                8474     } else {
                8475         /*
                8476         * Create a reference item.
                8477         */
                8478         item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
                8479         NULL, NULL);
                8480         if (item->ref == NULL)
                8481         return (NULL);
                8482         xmlSchemaPValAttrNodeQName(ctxt, schema,
                8483         NULL, attr,
                8484         &(item->ref->targetNamespace),
                8485         &(item->ref->name));
                8486         xmlSchemaCheckReference(ctxt, schema, node, attr,
                8487         item->ref->targetNamespace);
                8488     }
                8489     }
                8490     /*
                8491     * And now for the children...
                8492     */
                8493     child = node->children;
                8494     if (IS_SCHEMA(child, "annotation")) {
                8495     item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                8496     child = child->next;
                8497     }
                8498     if (child == NULL) {
                8499     xmlSchemaPContentErr(ctxt,
                8500         XML_SCHEMAP_S4S_ELEM_MISSING,
                8501         NULL, node, child,
                8502         "A child element is missing",
                8503         "(annotation?, (selector, field+))");
                8504     }
                8505     /*
                8506     * Child element <selector>.
                8507     */
                8508     if (IS_SCHEMA(child, "selector")) {
                8509     item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
                8510         item, child, 0);
                8511     child = child->next;
                8512     /*
                8513     * Child elements <field>.
                8514     */
                8515     if (IS_SCHEMA(child, "field")) {
                8516         do {
                8517         field = xmlSchemaParseIDCSelectorAndField(ctxt,
                8518             item, child, 1);
                8519         if (field != NULL) {
                8520             field->index = item->nbFields;
                8521             item->nbFields++;
                8522             if (lastField != NULL)
                8523             lastField->next = field;
                8524             else
                8525             item->fields = field;
                8526             lastField = field;
                8527         }
                8528         child = child->next;
                8529         } while (IS_SCHEMA(child, "field"));
                8530     } else {
                8531         xmlSchemaPContentErr(ctxt,
                8532         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                8533         NULL, node, child,
                8534         NULL, "(annotation?, (selector, field+))");
                8535     }
                8536     }
                8537     if (child != NULL) {
                8538     xmlSchemaPContentErr(ctxt,
                8539         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                8540         NULL, node, child,
                8541         NULL, "(annotation?, (selector, field+))");
                8542     }
                8543 
                8544     return (item);
                8545 }
                8546 
                8547 /**
                8548  * xmlSchemaParseElement:
                8549  * @ctxt:  a schema validation context
                8550  * @schema:  the schema being built
                8551  * @node:  a subtree containing XML Schema information
                8552  * @topLevel: indicates if this is global declaration
                8553  *
                8554  * Parses a XML schema element declaration.
                8555  * *WARNING* this interface is highly subject to change
                8556  *
                8557  * Returns the element declaration or a particle; NULL in case
                8558  * of an error or if the particle has minOccurs==maxOccurs==0.
                8559  */
                8560 static xmlSchemaBasicItemPtr
                8561 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                8562                       xmlNodePtr node, int *isElemRef, int topLevel)
                8563 {
                8564     xmlSchemaElementPtr decl = NULL;
                8565     xmlSchemaParticlePtr particle = NULL;
                8566     xmlSchemaAnnotPtr annot = NULL;
                8567     xmlNodePtr child = NULL;
                8568     xmlAttrPtr attr, nameAttr;
                8569     int min, max, isRef = 0;
                8570     xmlChar *des = NULL;
                8571 
                8572     /* 3.3.3 Constraints on XML Representations of Element Declarations */
                8573     /* TODO: Complete implementation of 3.3.6 */
                8574 
                8575     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                8576         return (NULL);
                8577 
                8578     if (isElemRef != NULL)
                8579     *isElemRef = 0;
                8580     /*
                8581     * If we get a "ref" attribute on a local <element> we will assume it's
                8582     * a reference - even if there's a "name" attribute; this seems to be more
                8583     * robust.
                8584     */
                8585     nameAttr = xmlSchemaGetPropNode(node, "name");
                8586     attr = xmlSchemaGetPropNode(node, "ref");
                8587     if ((topLevel) || (attr == NULL)) {
                8588     if (nameAttr == NULL) {
                8589         xmlSchemaPMissingAttrErr(ctxt,
                8590         XML_SCHEMAP_S4S_ATTR_MISSING,
                8591         NULL, node, "name", NULL);
                8592         return (NULL);
                8593     }
                8594     } else
                8595     isRef = 1;
                8596 
                8597     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                8598     child = node->children;
                8599     if (IS_SCHEMA(child, "annotation")) {
                8600     annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                8601     child = child->next;
                8602     }
                8603     /*
                8604     * Skip particle part if a global declaration.
                8605     */
                8606     if (topLevel)
                8607     goto declaration_part;
                8608     /*
                8609     * The particle part ==================================================
                8610     */
                8611     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
                8612     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
                8613     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
                8614     particle = xmlSchemaAddParticle(ctxt, node, min, max);
                8615     if (particle == NULL)
                8616     goto return_null;
                8617 
                8618     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
                8619 
                8620     if (isRef) {
                8621     const xmlChar *refNs = NULL, *ref = NULL;
                8622     xmlSchemaQNameRefPtr refer = NULL;
                8623     /*
                8624     * The reference part =============================================
                8625     */
                8626     if (isElemRef != NULL)
                8627         *isElemRef = 1;
                8628 
                8629     xmlSchemaPValAttrNodeQName(ctxt, schema,
                8630         NULL, attr, &refNs, &ref);
                8631     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
                8632     /*
                8633     * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
                8634     */
                8635     if (nameAttr != NULL) {
                8636         xmlSchemaPMutualExclAttrErr(ctxt,
                8637         XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
                8638     }
                8639     /*
                8640     * Check for illegal attributes.
                8641     */
                8642     attr = node->properties;
                8643     while (attr != NULL) {
                8644         if (attr->ns == NULL) {
                8645         if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
                8646             xmlStrEqual(attr->name, BAD_CAST "name") ||
                8647             xmlStrEqual(attr->name, BAD_CAST "id") ||
                8648             xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
                8649             xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
                8650         {
                8651             attr = attr->next;
                8652             continue;
                8653         } else {
                8654             /* SPEC (3.3.3 : 2.2) */
                8655             xmlSchemaPCustomAttrErr(ctxt,
                8656             XML_SCHEMAP_SRC_ELEMENT_2_2,
                8657             NULL, NULL, attr,
                8658             "Only the attributes 'minOccurs', 'maxOccurs' and "
                8659             "'id' are allowed in addition to 'ref'");
                8660             break;
                8661         }
                8662         } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                8663         xmlSchemaPIllegalAttrErr(ctxt,
                8664             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8665         }
                8666         attr = attr->next;
                8667     }
                8668     /*
                8669     * No children except <annotation> expected.
                8670     */
                8671     if (child != NULL) {
                8672         xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                8673         NULL, node, child, NULL, "(annotation?)");
                8674     }
                8675     if ((min == 0) && (max == 0))
                8676         goto return_null;
                8677     /*
                8678     * Create the reference item and attach it to the particle.
                8679     */
                8680     refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
                8681         ref, refNs);
                8682     if (refer == NULL)
                8683         goto return_null;
                8684     particle->children = (xmlSchemaTreeItemPtr) refer;
                8685     particle->annot = annot;
                8686     /*
                8687     * Add the particle to pending components, since the reference
                8688     * need to be resolved.
                8689     */
                8690     WXS_ADD_PENDING(ctxt, particle);
                8691     return ((xmlSchemaBasicItemPtr) particle);
                8692     }
                8693     /*
                8694     * The declaration part ===============================================
                8695     */
                8696 declaration_part:
                8697     {
                8698     const xmlChar *ns = NULL, *fixed, *name, *attrValue;
                8699     xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
                8700 
                8701     if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
                8702         xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
                8703         goto return_null;
                8704     /*
                8705     * Evaluate the target namespace.
                8706     */
                8707     if (topLevel) {
                8708         ns = ctxt->targetNamespace;
                8709     } else {
                8710         attr = xmlSchemaGetPropNode(node, "form");
                8711         if (attr != NULL) {
                8712         attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                8713         if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
                8714             ns = ctxt->targetNamespace;
                8715         } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
                8716             xmlSchemaPSimpleTypeErr(ctxt,
                8717             XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                8718             NULL, (xmlNodePtr) attr,
                8719             NULL, "(qualified | unqualified)",
                8720             attrValue, NULL, NULL, NULL);
                8721         }
                8722         } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
                8723         ns = ctxt->targetNamespace;
                8724     }
                8725     decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
                8726     if (decl == NULL) {
                8727         goto return_null;
                8728     }
                8729     /*
                8730     * Check for illegal attributes.
                8731     */
                8732     attr = node->properties;
                8733     while (attr != NULL) {
                8734         if (attr->ns == NULL) {
                8735         if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
                8736             (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
                8737             (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                8738             (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
                8739             (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
                8740             (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
                8741             (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
                8742         {
                8743             if (topLevel == 0) {
                8744             if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
                8745                 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
                8746                 (!xmlStrEqual(attr->name, BAD_CAST "form")))
                8747             {
                8748                 xmlSchemaPIllegalAttrErr(ctxt,
                8749                 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8750             }
                8751             } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
                8752             (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
                8753             (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
                8754 
                8755             xmlSchemaPIllegalAttrErr(ctxt,
                8756                 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8757             }
                8758         }
                8759         } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                8760 
                8761         xmlSchemaPIllegalAttrErr(ctxt,
                8762             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8763         }
                8764         attr = attr->next;
                8765     }
                8766     /*
                8767     * Extract/validate attributes.
                8768     */
                8769     if (topLevel) {
                8770         /*
                8771         * Process top attributes of global element declarations here.
                8772         */
                8773         decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
                8774         decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
                8775         xmlSchemaPValAttrQName(ctxt, schema,
                8776         NULL, node, "substitutionGroup",
                8777         &(decl->substGroupNs), &(decl->substGroup));
                8778         if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
                8779         decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
                8780         /*
                8781         * Attribute "final".
                8782         */
                8783         attr = xmlSchemaGetPropNode(node, "final");
                8784         if (attr == NULL) {
                8785         if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
                8786             decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
                8787         if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
                8788             decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
                8789         } else {
                8790         attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                8791         if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
                8792             -1,
                8793             XML_SCHEMAS_ELEM_FINAL_EXTENSION,
                8794             XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
                8795             xmlSchemaPSimpleTypeErr(ctxt,
                8796             XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                8797             NULL, (xmlNodePtr) attr,
                8798             NULL, "(#all | List of (extension | restriction))",
                8799             attrValue, NULL, NULL, NULL);
                8800         }
                8801         }
                8802     }
                8803     /*
                8804     * Attribute "block".
                8805     */
                8806     attr = xmlSchemaGetPropNode(node, "block");
                8807     if (attr == NULL) {
                8808         /*
                8809         * Apply default "block" values.
                8810         */
                8811         if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
                8812         decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
                8813         if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
                8814         decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
                8815         if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
                8816         decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
                8817     } else {
                8818         attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                8819         if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
                8820         -1,
                8821         XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
                8822         XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
                8823         XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
                8824         xmlSchemaPSimpleTypeErr(ctxt,
                8825             XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                8826             NULL, (xmlNodePtr) attr,
                8827             NULL, "(#all | List of (extension | "
                8828             "restriction | substitution))", attrValue,
                8829             NULL, NULL, NULL);
                8830         }
                8831     }
                8832     if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
                8833         decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
                8834 
                8835     attr = xmlSchemaGetPropNode(node, "type");
                8836     if (attr != NULL) {
                8837         xmlSchemaPValAttrNodeQName(ctxt, schema,
                8838         NULL, attr,
                8839         &(decl->namedTypeNs), &(decl->namedType));
                8840         xmlSchemaCheckReference(ctxt, schema, node,
                8841         attr, decl->namedTypeNs);
                8842     }
                8843     decl->value = xmlSchemaGetProp(ctxt, node, "default");
                8844     attr = xmlSchemaGetPropNode(node, "fixed");
                8845     if (attr != NULL) {
                8846         fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                8847         if (decl->value != NULL) {
                8848         /*
                8849         * 3.3.3 : 1
                8850         * default and fixed must not both be present.
                8851         */
                8852         xmlSchemaPMutualExclAttrErr(ctxt,
                8853             XML_SCHEMAP_SRC_ELEMENT_1,
                8854             NULL, attr, "default", "fixed");
                8855         } else {
                8856         decl->flags |= XML_SCHEMAS_ELEM_FIXED;
                8857         decl->value = fixed;
                8858         }
                8859     }
                8860     /*
                8861     * And now for the children...
                8862     */
                8863     if (IS_SCHEMA(child, "complexType")) {
                8864         /*
                8865         * 3.3.3 : 3
                8866         * "type" and either <simpleType> or <complexType> are mutually
                8867         * exclusive
                8868         */
                8869         if (decl->namedType != NULL) {
                8870         xmlSchemaPContentErr(ctxt,
                8871             XML_SCHEMAP_SRC_ELEMENT_3,
                8872             NULL, node, child,
                8873             "The attribute 'type' and the <complexType> child are "
                8874             "mutually exclusive", NULL);
                8875         } else
                8876         WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
                8877         child = child->next;
                8878     } else if (IS_SCHEMA(child, "simpleType")) {
                8879         /*
                8880         * 3.3.3 : 3
                8881         * "type" and either <simpleType> or <complexType> are
                8882         * mutually exclusive
                8883         */
                8884         if (decl->namedType != NULL) {
                8885         xmlSchemaPContentErr(ctxt,
                8886             XML_SCHEMAP_SRC_ELEMENT_3,
                8887             NULL, node, child,
                8888             "The attribute 'type' and the <simpleType> child are "
                8889             "mutually exclusive", NULL);
                8890         } else
                8891         WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
                8892         child = child->next;
                8893     }
                8894     while ((IS_SCHEMA(child, "unique")) ||
                8895         (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
                8896         if (IS_SCHEMA(child, "unique")) {
                8897         curIDC = xmlSchemaParseIDC(ctxt, schema, child,
                8898             XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
                8899         } else if (IS_SCHEMA(child, "key")) {
                8900         curIDC = xmlSchemaParseIDC(ctxt, schema, child,
                8901             XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
                8902         } else if (IS_SCHEMA(child, "keyref")) {
                8903         curIDC = xmlSchemaParseIDC(ctxt, schema, child,
                8904             XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
                8905         }
                8906         if (lastIDC != NULL)
                8907         lastIDC->next = curIDC;
                8908         else
                8909         decl->idcs = (void *) curIDC;
                8910         lastIDC = curIDC;
                8911         child = child->next;
                8912     }
                8913     if (child != NULL) {
                8914         xmlSchemaPContentErr(ctxt,
                8915         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                8916         NULL, node, child,
                8917         NULL, "(annotation?, ((simpleType | complexType)?, "
                8918         "(unique | key | keyref)*))");
                8919     }
                8920     decl->annot = annot;
                8921     }
                8922     /*
                8923     * NOTE: Element Declaration Representation OK 4. will be checked at a
                8924     * different layer.
                8925     */
                8926     FREE_AND_NULL(des)
                8927     if (topLevel)
                8928     return ((xmlSchemaBasicItemPtr) decl);
                8929     else {
                8930     particle->children = (xmlSchemaTreeItemPtr) decl;
                8931     return ((xmlSchemaBasicItemPtr) particle);
                8932     }
                8933 
                8934 return_null:
                8935     FREE_AND_NULL(des);
                8936     if (annot != NULL) {
                8937     if (particle != NULL)
                8938         particle->annot = NULL;
                8939     if (decl != NULL)
                8940         decl->annot = NULL;
                8941     xmlSchemaFreeAnnot(annot);
                8942     }
                8943     return (NULL);
                8944 }
                8945 
                8946 /**
                8947  * xmlSchemaParseUnion:
                8948  * @ctxt:  a schema validation context
                8949  * @schema:  the schema being built
                8950  * @node:  a subtree containing XML Schema information
                8951  *
                8952  * parse a XML schema Union definition
                8953  * *WARNING* this interface is highly subject to change
                8954  *
                8955  * Returns -1 in case of internal error, 0 in case of success and a positive
                8956  * error code otherwise.
                8957  */
                8958 static int
                8959 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                8960                     xmlNodePtr node)
                8961 {
                8962     xmlSchemaTypePtr type;
                8963     xmlNodePtr child = NULL;
                8964     xmlAttrPtr attr;
                8965     const xmlChar *cur = NULL;
                8966 
                8967     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                8968         return (-1);
                8969     /* Not a component, don't create it. */
                8970     type = ctxt->ctxtType;
                8971     /*
                8972     * Mark the simple type as being of variety "union".
                8973     */
                8974     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
                8975     /*
                8976     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
                8977     * then the `simple ur-type definition`."
                8978     */
                8979     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
                8980     /*
                8981     * Check for illegal attributes.
                8982     */
                8983     attr = node->properties;
                8984     while (attr != NULL) {
                8985     if (attr->ns == NULL) {
                8986         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                8987         (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
                8988         xmlSchemaPIllegalAttrErr(ctxt,
                8989             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8990         }
                8991     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                8992         xmlSchemaPIllegalAttrErr(ctxt,
                8993         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                8994     }
                8995     attr = attr->next;
                8996     }
                8997     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                8998     /*
                8999     * Attribute "memberTypes". This is a list of QNames.
                9000     * TODO: Check the value to contain anything.
                9001     */
                9002     attr = xmlSchemaGetPropNode(node, "memberTypes");
                9003     if (attr != NULL) {
                9004     const xmlChar *end;
                9005     xmlChar *tmp;
                9006     const xmlChar *localName, *nsName;
                9007     xmlSchemaTypeLinkPtr link, lastLink = NULL;
                9008     xmlSchemaQNameRefPtr ref;
                9009 
                9010     cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
ad7b9726c Alex*9011         if (cur == NULL)
                9012             return (-1);
9d9d4fcc3 Alex*9013     type->base = cur;
                9014     do {
                9015         while (IS_BLANK_CH(*cur))
                9016         cur++;
                9017         end = cur;
                9018         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                9019         end++;
                9020         if (end == cur)
                9021         break;
                9022         tmp = xmlStrndup(cur, end - cur);
ad7b9726c Alex*9023             if (tmp == NULL) {
                9024                 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
                9025                     "duplicating type name", NULL);
                9026                 return (-1);
                9027             }
9d9d4fcc3 Alex*9028         if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
                9029         NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
                9030         /*
                9031         * Create the member type link.
                9032         */
                9033         link = (xmlSchemaTypeLinkPtr)
                9034             xmlMalloc(sizeof(xmlSchemaTypeLink));
                9035         if (link == NULL) {
                9036             xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
                9037             "allocating a type link", NULL);
ad7b9726c Alex*9038                 FREE_AND_NULL(tmp)
9d9d4fcc3 Alex*9039             return (-1);
                9040         }
                9041         link->type = NULL;
                9042         link->next = NULL;
                9043         if (lastLink == NULL)
                9044             type->memberTypes = link;
                9045         else
                9046             lastLink->next = link;
                9047         lastLink = link;
                9048         /*
                9049         * Create a reference item.
                9050         */
                9051         ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
                9052             localName, nsName);
                9053         if (ref == NULL) {
                9054             FREE_AND_NULL(tmp)
                9055             return (-1);
                9056         }
                9057         /*
                9058         * Assign the reference to the link, it will be resolved
                9059         * later during fixup of the union simple type.
                9060         */
                9061         link->type = (xmlSchemaTypePtr) ref;
                9062         }
                9063         FREE_AND_NULL(tmp)
                9064         cur = end;
                9065     } while (*cur != 0);
                9066 
                9067     }
                9068     /*
                9069     * And now for the children...
                9070     */
                9071     child = node->children;
                9072     if (IS_SCHEMA(child, "annotation")) {
                9073     /*
                9074     * Add the annotation to the simple type ancestor.
                9075     */
                9076     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
                9077         xmlSchemaParseAnnotation(ctxt, child, 1));
                9078         child = child->next;
                9079     }
                9080     if (IS_SCHEMA(child, "simpleType")) {
                9081     xmlSchemaTypePtr subtype, last = NULL;
                9082 
                9083     /*
                9084     * Anchor the member types in the "subtypes" field of the
                9085     * simple type.
                9086     */
                9087     while (IS_SCHEMA(child, "simpleType")) {
                9088         subtype = (xmlSchemaTypePtr)
                9089         xmlSchemaParseSimpleType(ctxt, schema, child, 0);
                9090         if (subtype != NULL) {
                9091         if (last == NULL) {
                9092             type->subtypes = subtype;
                9093             last = subtype;
                9094         } else {
                9095             last->next = subtype;
                9096             last = subtype;
                9097         }
                9098         last->next = NULL;
                9099         }
                9100         child = child->next;
                9101     }
                9102     }
                9103     if (child != NULL) {
                9104     xmlSchemaPContentErr(ctxt,
                9105         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                9106         NULL, node, child, NULL, "(annotation?, simpleType*)");
                9107     }
                9108     if ((attr == NULL) && (type->subtypes == NULL)) {
                9109      /*
                9110     * src-union-memberTypes-or-simpleTypes
                9111     * Either the memberTypes [attribute] of the <union> element must
                9112     * be non-empty or there must be at least one simpleType [child].
                9113     */
                9114     xmlSchemaPCustomErr(ctxt,
                9115         XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
                9116         NULL, node,
                9117         "Either the attribute 'memberTypes' or "
                9118         "at least one <simpleType> child must be present", NULL);
                9119     }
                9120     return (0);
                9121 }
                9122 
                9123 /**
                9124  * xmlSchemaParseList:
                9125  * @ctxt:  a schema validation context
                9126  * @schema:  the schema being built
                9127  * @node:  a subtree containing XML Schema information
                9128  *
                9129  * parse a XML schema List definition
                9130  * *WARNING* this interface is highly subject to change
                9131  *
                9132  * Returns -1 in case of error, 0 if the declaration is improper and
                9133  *         1 in case of success.
                9134  */
                9135 static xmlSchemaTypePtr
                9136 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                9137                    xmlNodePtr node)
                9138 {
                9139     xmlSchemaTypePtr type;
                9140     xmlNodePtr child = NULL;
                9141     xmlAttrPtr attr;
                9142 
                9143     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                9144         return (NULL);
                9145     /* Not a component, don't create it. */
                9146     type = ctxt->ctxtType;
                9147     /*
                9148     * Mark the type as being of variety "list".
                9149     */
                9150     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
                9151     /*
                9152     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
                9153     * then the `simple ur-type definition`."
                9154     */
                9155     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
                9156     /*
                9157     * Check for illegal attributes.
                9158     */
                9159     attr = node->properties;
                9160     while (attr != NULL) {
                9161     if (attr->ns == NULL) {
                9162         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                9163         (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
                9164         xmlSchemaPIllegalAttrErr(ctxt,
                9165             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9166         }
                9167     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                9168         xmlSchemaPIllegalAttrErr(ctxt,
                9169         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9170     }
                9171     attr = attr->next;
                9172     }
                9173 
                9174     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                9175 
                9176     /*
                9177     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
                9178     * fields for holding the reference to the itemType.
                9179     *
                9180     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
                9181     * the "ref" fields.
                9182     */
                9183     xmlSchemaPValAttrQName(ctxt, schema, NULL,
                9184     node, "itemType", &(type->baseNs), &(type->base));
                9185     /*
                9186     * And now for the children...
                9187     */
                9188     child = node->children;
                9189     if (IS_SCHEMA(child, "annotation")) {
                9190     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
                9191         xmlSchemaParseAnnotation(ctxt, child, 1));
                9192         child = child->next;
                9193     }
                9194     if (IS_SCHEMA(child, "simpleType")) {
                9195     /*
                9196     * src-list-itemType-or-simpleType
                9197     * Either the itemType [attribute] or the <simpleType> [child] of
                9198     * the <list> element must be present, but not both.
                9199     */
                9200     if (type->base != NULL) {
                9201         xmlSchemaPCustomErr(ctxt,
                9202         XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
                9203         NULL, node,
                9204         "The attribute 'itemType' and the <simpleType> child "
                9205         "are mutually exclusive", NULL);
                9206     } else {
                9207         type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
                9208     }
                9209         child = child->next;
                9210     } else if (type->base == NULL) {
                9211     xmlSchemaPCustomErr(ctxt,
                9212         XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
                9213         NULL, node,
                9214         "Either the attribute 'itemType' or the <simpleType> child "
                9215         "must be present", NULL);
                9216     }
                9217     if (child != NULL) {
                9218     xmlSchemaPContentErr(ctxt,
                9219         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                9220         NULL, node, child, NULL, "(annotation?, simpleType?)");
                9221     }
                9222     if ((type->base == NULL) &&
                9223     (type->subtypes == NULL) &&
                9224     (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
                9225     xmlSchemaPCustomErr(ctxt,
                9226         XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
                9227         NULL, node,
                9228         "Either the attribute 'itemType' or the <simpleType> child "
                9229         "must be present", NULL);
                9230     }
                9231     return (NULL);
                9232 }
                9233 
                9234 /**
                9235  * xmlSchemaParseSimpleType:
                9236  * @ctxt:  a schema validation context
                9237  * @schema:  the schema being built
                9238  * @node:  a subtree containing XML Schema information
                9239  *
                9240  * parse a XML schema Simple Type definition
                9241  * *WARNING* this interface is highly subject to change
                9242  *
                9243  * Returns -1 in case of error, 0 if the declaration is improper and
                9244  * 1 in case of success.
                9245  */
                9246 static xmlSchemaTypePtr
                9247 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                9248                          xmlNodePtr node, int topLevel)
                9249 {
                9250     xmlSchemaTypePtr type, oldCtxtType;
                9251     xmlNodePtr child = NULL;
                9252     const xmlChar *attrValue = NULL;
                9253     xmlAttrPtr attr;
                9254     int hasRestriction = 0;
                9255 
                9256     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                9257         return (NULL);
                9258 
                9259     if (topLevel) {
                9260     attr = xmlSchemaGetPropNode(node, "name");
                9261     if (attr == NULL) {
                9262         xmlSchemaPMissingAttrErr(ctxt,
                9263         XML_SCHEMAP_S4S_ATTR_MISSING,
                9264         NULL, node,
                9265         "name", NULL);
                9266         return (NULL);
                9267     } else {
                9268         if (xmlSchemaPValAttrNode(ctxt,
                9269         NULL, attr,
                9270         xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
                9271         return (NULL);
                9272         /*
                9273         * Skip built-in types.
                9274         */
                9275         if (ctxt->isS4S) {
                9276         xmlSchemaTypePtr biType;
                9277 
                9278         if (ctxt->isRedefine) {
                9279             /*
                9280             * REDEFINE: Disallow redefinition of built-in-types.
                9281             * TODO: It seems that the spec does not say anything
                9282             * about this case.
                9283             */
                9284             xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
                9285             NULL, node,
                9286             "Redefinition of built-in simple types is not "
                9287             "supported", NULL);
                9288             return(NULL);
                9289         }
                9290         biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
                9291         if (biType != NULL)
                9292             return (biType);
                9293         }
                9294     }
                9295     }
                9296     /*
                9297     * TargetNamespace:
                9298     * SPEC "The `actual value` of the targetNamespace [attribute]
                9299     * of the <schema> ancestor element information item if present,
                9300     * otherwise `absent`.
                9301     */
                9302     if (topLevel == 0) {
                9303 #ifdef ENABLE_NAMED_LOCALS
                9304         char buf[40];
                9305 #endif
                9306     /*
                9307     * Parse as local simple type definition.
                9308     */
                9309 #ifdef ENABLE_NAMED_LOCALS
                9310         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
                9311     type = xmlSchemaAddType(ctxt, schema,
                9312         XML_SCHEMA_TYPE_SIMPLE,
                9313         xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
                9314         ctxt->targetNamespace, node, 0);
                9315 #else
                9316     type = xmlSchemaAddType(ctxt, schema,
                9317         XML_SCHEMA_TYPE_SIMPLE,
                9318         NULL, ctxt->targetNamespace, node, 0);
                9319 #endif
                9320     if (type == NULL)
                9321         return (NULL);
                9322     type->type = XML_SCHEMA_TYPE_SIMPLE;
                9323     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
                9324     /*
                9325     * Check for illegal attributes.
                9326     */
                9327     attr = node->properties;
                9328     while (attr != NULL) {
                9329         if (attr->ns == NULL) {
                9330         if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
                9331             xmlSchemaPIllegalAttrErr(ctxt,
                9332             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9333         }
                9334         } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                9335             xmlSchemaPIllegalAttrErr(ctxt,
                9336             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9337         }
                9338         attr = attr->next;
                9339     }
                9340     } else {
                9341     /*
                9342     * Parse as global simple type definition.
                9343     *
                9344     * Note that attrValue is the value of the attribute "name" here.
                9345     */
                9346     type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
                9347         attrValue, ctxt->targetNamespace, node, 1);
                9348     if (type == NULL)
                9349         return (NULL);
                9350     type->type = XML_SCHEMA_TYPE_SIMPLE;
                9351     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
                9352     type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
                9353     /*
                9354     * Check for illegal attributes.
                9355     */
                9356     attr = node->properties;
                9357     while (attr != NULL) {
                9358         if (attr->ns == NULL) {
                9359         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                9360             (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
                9361             (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
                9362             xmlSchemaPIllegalAttrErr(ctxt,
                9363             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9364         }
                9365         } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                9366         xmlSchemaPIllegalAttrErr(ctxt,
                9367             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9368         }
                9369         attr = attr->next;
                9370     }
                9371     /*
                9372     * Attribute "final".
                9373     */
                9374     attr = xmlSchemaGetPropNode(node, "final");
                9375     if (attr == NULL) {
                9376         if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
                9377         type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
                9378         if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
                9379         type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
                9380         if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
                9381         type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
                9382     } else {
                9383         attrValue = xmlSchemaGetProp(ctxt, node, "final");
                9384         if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
                9385         -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
                9386         XML_SCHEMAS_TYPE_FINAL_LIST,
                9387         XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
                9388 
                9389         xmlSchemaPSimpleTypeErr(ctxt,
                9390             XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                9391             WXS_BASIC_CAST type, (xmlNodePtr) attr,
                9392             NULL, "(#all | List of (list | union | restriction)",
                9393             attrValue, NULL, NULL, NULL);
                9394         }
                9395     }
                9396     }
                9397     type->targetNamespace = ctxt->targetNamespace;
                9398     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                9399     /*
                9400     * And now for the children...
                9401     */
                9402     oldCtxtType = ctxt->ctxtType;
                9403 
                9404     ctxt->ctxtType = type;
                9405 
                9406     child = node->children;
                9407     if (IS_SCHEMA(child, "annotation")) {
                9408         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                9409         child = child->next;
                9410     }
                9411     if (child == NULL) {
                9412     xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
                9413         NULL, node, child, NULL,
                9414         "(annotation?, (restriction | list | union))");
                9415     } else if (IS_SCHEMA(child, "restriction")) {
                9416         xmlSchemaParseRestriction(ctxt, schema, child,
                9417         XML_SCHEMA_TYPE_SIMPLE);
                9418     hasRestriction = 1;
                9419         child = child->next;
                9420     } else if (IS_SCHEMA(child, "list")) {
                9421         xmlSchemaParseList(ctxt, schema, child);
                9422         child = child->next;
                9423     } else if (IS_SCHEMA(child, "union")) {
                9424         xmlSchemaParseUnion(ctxt, schema, child);
                9425         child = child->next;
                9426     }
                9427     if (child != NULL) {
                9428     xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                9429         NULL, node, child, NULL,
                9430         "(annotation?, (restriction | list | union))");
                9431     }
                9432     /*
                9433     * REDEFINE: SPEC src-redefine (5)
                9434     * "Within the [children], each <simpleType> must have a
                9435     * <restriction> among its [children] ... the `actual value` of whose
                9436     * base [attribute] must be the same as the `actual value` of its own
                9437     * name attribute plus target namespace;"
                9438     */
                9439     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
                9440     xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
                9441         NULL, node, "This is a redefinition, thus the "
                9442         "<simpleType> must have a <restriction> child", NULL);
                9443     }
                9444 
                9445     ctxt->ctxtType = oldCtxtType;
                9446     return (type);
                9447 }
                9448 
                9449 /**
                9450  * xmlSchemaParseModelGroupDefRef:
                9451  * @ctxt:  the parser context
                9452  * @schema: the schema being built
                9453  * @node:  the node
                9454  *
                9455  * Parses a reference to a model group definition.
                9456  *
                9457  * We will return a particle component with a qname-component or
                9458  * NULL in case of an error.
                9459  */
                9460 static xmlSchemaTreeItemPtr
                9461 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
                9462                    xmlSchemaPtr schema,
                9463                    xmlNodePtr node)
                9464 {
                9465     xmlSchemaParticlePtr item;
                9466     xmlNodePtr child = NULL;
                9467     xmlAttrPtr attr;
                9468     const xmlChar *ref = NULL, *refNs = NULL;
                9469     int min, max;
                9470 
                9471     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                9472         return (NULL);
                9473 
                9474     attr = xmlSchemaGetPropNode(node, "ref");
                9475     if (attr == NULL) {
                9476     xmlSchemaPMissingAttrErr(ctxt,
                9477         XML_SCHEMAP_S4S_ATTR_MISSING,
                9478         NULL, node, "ref", NULL);
                9479     return (NULL);
                9480     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
                9481     attr, &refNs, &ref) != 0) {
                9482     return (NULL);
                9483     }
                9484     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
                9485     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
                9486     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
                9487     "(xs:nonNegativeInteger | unbounded)");
                9488     /*
                9489     * Check for illegal attributes.
                9490     */
                9491     attr = node->properties;
                9492     while (attr != NULL) {
                9493     if (attr->ns == NULL) {
                9494         if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
                9495         (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                9496         (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
                9497         (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
                9498         xmlSchemaPIllegalAttrErr(ctxt,
                9499             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9500         }
                9501     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                9502         xmlSchemaPIllegalAttrErr(ctxt,
                9503         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9504     }
                9505     attr = attr->next;
                9506     }
                9507     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                9508     item = xmlSchemaAddParticle(ctxt, node, min, max);
                9509     if (item == NULL)
                9510     return (NULL);
                9511     /*
                9512     * Create a qname-reference and set as the term; it will be substituted
                9513     * for the model group after the reference has been resolved.
                9514     */
                9515     item->children = (xmlSchemaTreeItemPtr)
                9516     xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
                9517     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
                9518     /*
                9519     * And now for the children...
                9520     */
                9521     child = node->children;
                9522     /* TODO: Is annotation even allowed for a model group reference? */
                9523     if (IS_SCHEMA(child, "annotation")) {
                9524     /*
                9525     * TODO: What to do exactly with the annotation?
                9526     */
                9527     item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                9528     child = child->next;
                9529     }
                9530     if (child != NULL) {
                9531     xmlSchemaPContentErr(ctxt,
                9532         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                9533         NULL, node, child, NULL,
                9534         "(annotation?)");
                9535     }
                9536     /*
                9537     * Corresponds to no component at all if minOccurs==maxOccurs==0.
                9538     */
                9539     if ((min == 0) && (max == 0))
                9540     return (NULL);
                9541 
                9542     return ((xmlSchemaTreeItemPtr) item);
                9543 }
                9544 
                9545 /**
                9546  * xmlSchemaParseModelGroupDefinition:
                9547  * @ctxt:  a schema validation context
                9548  * @schema:  the schema being built
                9549  * @node:  a subtree containing XML Schema information
                9550  *
                9551  * Parses a XML schema model group definition.
                9552  *
                9553  * Note that the constraint src-redefine (6.2) can't be applied until
                9554  * references have been resolved. So we will do this at the
                9555  * component fixup level.
                9556  *
                9557  * *WARNING* this interface is highly subject to change
                9558  *
                9559  * Returns -1 in case of error, 0 if the declaration is improper and
                9560  *         1 in case of success.
                9561  */
                9562 static xmlSchemaModelGroupDefPtr
                9563 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
                9564                    xmlSchemaPtr schema,
                9565                    xmlNodePtr node)
                9566 {
                9567     xmlSchemaModelGroupDefPtr item;
                9568     xmlNodePtr child = NULL;
                9569     xmlAttrPtr attr;
                9570     const xmlChar *name;
                9571 
                9572     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                9573         return (NULL);
                9574 
                9575     attr = xmlSchemaGetPropNode(node, "name");
                9576     if (attr == NULL) {
                9577     xmlSchemaPMissingAttrErr(ctxt,
                9578         XML_SCHEMAP_S4S_ATTR_MISSING,
                9579         NULL, node,
                9580         "name", NULL);
                9581     return (NULL);
                9582     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
                9583     xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
                9584     return (NULL);
                9585     }
                9586     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
                9587     ctxt->targetNamespace, node);
                9588     if (item == NULL)
                9589     return (NULL);
                9590     /*
                9591     * Check for illegal attributes.
                9592     */
                9593     attr = node->properties;
                9594     while (attr != NULL) {
                9595     if (attr->ns == NULL) {
                9596         if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
                9597         (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
                9598         xmlSchemaPIllegalAttrErr(ctxt,
                9599             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9600         }
                9601     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                9602         xmlSchemaPIllegalAttrErr(ctxt,
                9603         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                9604     }
                9605     attr = attr->next;
                9606     }
                9607     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                9608     /*
                9609     * And now for the children...
                9610     */
                9611     child = node->children;
                9612     if (IS_SCHEMA(child, "annotation")) {
                9613     item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                9614     child = child->next;
                9615     }
                9616     if (IS_SCHEMA(child, "all")) {
                9617     item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
                9618         XML_SCHEMA_TYPE_ALL, 0);
                9619     child = child->next;
                9620     } else if (IS_SCHEMA(child, "choice")) {
                9621     item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
                9622         XML_SCHEMA_TYPE_CHOICE, 0);
                9623     child = child->next;
                9624     } else if (IS_SCHEMA(child, "sequence")) {
                9625     item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
                9626         XML_SCHEMA_TYPE_SEQUENCE, 0);
                9627     child = child->next;
                9628     }
                9629 
                9630 
                9631 
                9632     if (child != NULL) {
                9633     xmlSchemaPContentErr(ctxt,
                9634         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                9635         NULL, node, child, NULL,
                9636         "(annotation?, (all | choice | sequence)?)");
                9637     }
                9638     return (item);
                9639 }
                9640 
                9641 /**
                9642  * xmlSchemaCleanupDoc:
                9643  * @ctxt:  a schema validation context
                9644  * @node:  the root of the document.
                9645  *
                9646  * removes unwanted nodes in a schemas document tree
                9647  */
                9648 static void
                9649 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
                9650 {
                9651     xmlNodePtr delete, cur;
                9652 
                9653     if ((ctxt == NULL) || (root == NULL)) return;
                9654 
                9655     /*
                9656      * Remove all the blank text nodes
                9657      */
                9658     delete = NULL;
                9659     cur = root;
                9660     while (cur != NULL) {
                9661         if (delete != NULL) {
                9662             xmlUnlinkNode(delete);
                9663             xmlFreeNode(delete);
                9664             delete = NULL;
                9665         }
                9666         if (cur->type == XML_TEXT_NODE) {
                9667             if (IS_BLANK_NODE(cur)) {
                9668                 if (xmlNodeGetSpacePreserve(cur) != 1) {
                9669                     delete = cur;
                9670                 }
                9671             }
                9672         } else if ((cur->type != XML_ELEMENT_NODE) &&
                9673                    (cur->type != XML_CDATA_SECTION_NODE)) {
                9674             delete = cur;
                9675             goto skip_children;
                9676         }
                9677 
                9678         /*
                9679          * Skip to next node
                9680          */
                9681         if (cur->children != NULL) {
                9682             if ((cur->children->type != XML_ENTITY_DECL) &&
                9683                 (cur->children->type != XML_ENTITY_REF_NODE) &&
                9684                 (cur->children->type != XML_ENTITY_NODE)) {
                9685                 cur = cur->children;
                9686                 continue;
                9687             }
                9688         }
                9689       skip_children:
                9690         if (cur->next != NULL) {
                9691             cur = cur->next;
                9692             continue;
                9693         }
                9694 
                9695         do {
                9696             cur = cur->parent;
                9697             if (cur == NULL)
                9698                 break;
                9699             if (cur == root) {
                9700                 cur = NULL;
                9701                 break;
                9702             }
                9703             if (cur->next != NULL) {
                9704                 cur = cur->next;
                9705                 break;
                9706             }
                9707         } while (cur != NULL);
                9708     }
                9709     if (delete != NULL) {
                9710         xmlUnlinkNode(delete);
                9711         xmlFreeNode(delete);
                9712         delete = NULL;
                9713     }
                9714 }
                9715 
                9716 
                9717 static void
                9718 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
                9719 {
                9720     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
                9721     schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
                9722 
                9723     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
                9724     schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
                9725 
                9726     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
                9727     schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
                9728     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
                9729     schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
                9730     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
                9731     schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
                9732     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
                9733     schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
                9734 
                9735     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
                9736     schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
                9737     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
                9738     schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
                9739     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
                9740     schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
                9741 }
                9742 
                9743 static int
                9744 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
                9745                  xmlSchemaPtr schema,
                9746                  xmlNodePtr node)
                9747 {
                9748     xmlAttrPtr attr;
                9749     const xmlChar *val;
                9750     int res = 0, oldErrs = ctxt->nberrors;
                9751 
                9752     /*
                9753     * Those flags should be moved to the parser context flags,
                9754     * since they are not visible at the component level. I.e.
                9755     * they are used if processing schema *documents* only.
                9756     */
                9757     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                9758     HFAILURE;
                9759 
                9760     /*
                9761     * Since the version is of type xs:token, we won't bother to
                9762     * check it.
                9763     */
                9764     /* REMOVED:
                9765     attr = xmlSchemaGetPropNode(node, "version");
                9766     if (attr != NULL) {
                9767     res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
                9768         xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
                9769     HFAILURE;
                9770     }
                9771     */
                9772     attr = xmlSchemaGetPropNode(node, "targetNamespace");
                9773     if (attr != NULL) {
                9774     res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
                9775         xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
                9776     HFAILURE;
                9777     if (res != 0) {
                9778         ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
                9779         goto exit;
                9780     }
                9781     }
                9782     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
                9783     if (attr != NULL) {
                9784     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                9785     res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
                9786         XML_SCHEMAS_QUALIF_ELEM);
                9787     HFAILURE;
                9788     if (res != 0) {
                9789         xmlSchemaPSimpleTypeErr(ctxt,
                9790         XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
                9791         NULL, (xmlNodePtr) attr, NULL,
                9792         "(qualified | unqualified)", val, NULL, NULL, NULL);
                9793     }
                9794     }
                9795     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
                9796     if (attr != NULL) {
                9797     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                9798     res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
                9799         XML_SCHEMAS_QUALIF_ATTR);
                9800     HFAILURE;
                9801     if (res != 0) {
                9802         xmlSchemaPSimpleTypeErr(ctxt,
                9803         XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
                9804         NULL, (xmlNodePtr) attr, NULL,
                9805         "(qualified | unqualified)", val, NULL, NULL, NULL);
                9806     }
                9807     }
                9808     attr = xmlSchemaGetPropNode(node, "finalDefault");
                9809     if (attr != NULL) {
                9810     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                9811     res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
                9812         XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
                9813         XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
                9814         -1,
                9815         XML_SCHEMAS_FINAL_DEFAULT_LIST,
                9816         XML_SCHEMAS_FINAL_DEFAULT_UNION);
                9817     HFAILURE;
                9818     if (res != 0) {
                9819         xmlSchemaPSimpleTypeErr(ctxt,
                9820         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                9821         NULL, (xmlNodePtr) attr, NULL,
                9822         "(#all | List of (extension | restriction | list | union))",
                9823         val, NULL, NULL, NULL);
                9824     }
                9825     }
                9826     attr = xmlSchemaGetPropNode(node, "blockDefault");
                9827     if (attr != NULL) {
                9828     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
                9829     res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
                9830         XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
                9831         XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
                9832         XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
                9833     HFAILURE;
                9834     if (res != 0) {
                9835         xmlSchemaPSimpleTypeErr(ctxt,
                9836         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                9837         NULL, (xmlNodePtr) attr, NULL,
                9838         "(#all | List of (extension | restriction | substitution))",
                9839         val, NULL, NULL, NULL);
                9840     }
                9841     }
                9842 
                9843 exit:
                9844     if (oldErrs != ctxt->nberrors)
                9845     res = ctxt->err;
                9846     return(res);
                9847 exit_failure:
                9848     return(-1);
                9849 }
                9850 
                9851 /**
                9852  * xmlSchemaParseSchemaTopLevel:
                9853  * @ctxt:  a schema validation context
                9854  * @schema:  the schemas
                9855  * @nodes:  the list of top level nodes
                9856  *
                9857  * Returns the internal XML Schema structure built from the resource or
                9858  *         NULL in case of error
                9859  */
                9860 static int
                9861 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
                9862                              xmlSchemaPtr schema, xmlNodePtr nodes)
                9863 {
                9864     xmlNodePtr child;
                9865     xmlSchemaAnnotPtr annot;
                9866     int res = 0, oldErrs, tmpOldErrs;
                9867 
                9868     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
                9869         return(-1);
                9870 
                9871     oldErrs = ctxt->nberrors;
                9872     child = nodes;
                9873     while ((IS_SCHEMA(child, "include")) ||
                9874        (IS_SCHEMA(child, "import")) ||
                9875        (IS_SCHEMA(child, "redefine")) ||
                9876        (IS_SCHEMA(child, "annotation"))) {
                9877     if (IS_SCHEMA(child, "annotation")) {
                9878         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                9879         if (schema->annot == NULL)
                9880         schema->annot = annot;
                9881         else
                9882         xmlSchemaFreeAnnot(annot);
                9883     } else if (IS_SCHEMA(child, "import")) {
                9884         tmpOldErrs = ctxt->nberrors;
                9885         res = xmlSchemaParseImport(ctxt, schema, child);
                9886         HFAILURE;
                9887         HSTOP(ctxt);
                9888         if (tmpOldErrs != ctxt->nberrors)
                9889         goto exit;
                9890     } else if (IS_SCHEMA(child, "include")) {
                9891         tmpOldErrs = ctxt->nberrors;
                9892         res = xmlSchemaParseInclude(ctxt, schema, child);
                9893         HFAILURE;
                9894         HSTOP(ctxt);
                9895         if (tmpOldErrs != ctxt->nberrors)
                9896         goto exit;
                9897     } else if (IS_SCHEMA(child, "redefine")) {
                9898         tmpOldErrs = ctxt->nberrors;
                9899         res = xmlSchemaParseRedefine(ctxt, schema, child);
                9900         HFAILURE;
                9901         HSTOP(ctxt);
                9902         if (tmpOldErrs != ctxt->nberrors)
                9903         goto exit;
                9904     }
                9905     child = child->next;
                9906     }
                9907     /*
                9908     * URGENT TODO: Change the functions to return int results.
                9909     * We need especially to catch internal errors.
                9910     */
                9911     while (child != NULL) {
                9912     if (IS_SCHEMA(child, "complexType")) {
                9913         xmlSchemaParseComplexType(ctxt, schema, child, 1);
                9914         child = child->next;
                9915     } else if (IS_SCHEMA(child, "simpleType")) {
                9916         xmlSchemaParseSimpleType(ctxt, schema, child, 1);
                9917         child = child->next;
                9918     } else if (IS_SCHEMA(child, "element")) {
                9919         xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
                9920         child = child->next;
                9921     } else if (IS_SCHEMA(child, "attribute")) {
                9922         xmlSchemaParseGlobalAttribute(ctxt, schema, child);
                9923         child = child->next;
                9924     } else if (IS_SCHEMA(child, "attributeGroup")) {
                9925         xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
                9926         child = child->next;
                9927     } else if (IS_SCHEMA(child, "group")) {
                9928         xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
                9929         child = child->next;
                9930     } else if (IS_SCHEMA(child, "notation")) {
                9931         xmlSchemaParseNotation(ctxt, schema, child);
                9932         child = child->next;
                9933     } else {
                9934         xmlSchemaPContentErr(ctxt,
                9935         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                9936         NULL, child->parent, child,
                9937         NULL, "((include | import | redefine | annotation)*, "
                9938         "(((simpleType | complexType | group | attributeGroup) "
                9939         "| element | attribute | notation), annotation*)*)");
                9940         child = child->next;
                9941     }
                9942     while (IS_SCHEMA(child, "annotation")) {
                9943         /*
                9944         * TODO: We should add all annotations.
                9945         */
                9946         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                9947         if (schema->annot == NULL)
                9948         schema->annot = annot;
                9949         else
                9950         xmlSchemaFreeAnnot(annot);
                9951         child = child->next;
                9952     }
                9953     }
                9954 exit:
                9955     ctxt->ctxtType = NULL;
                9956     if (oldErrs != ctxt->nberrors)
                9957     res = ctxt->err;
                9958     return(res);
                9959 exit_failure:
                9960     return(-1);
                9961 }
                9962 
                9963 static xmlSchemaSchemaRelationPtr
                9964 xmlSchemaSchemaRelationCreate(void)
                9965 {
                9966     xmlSchemaSchemaRelationPtr ret;
                9967 
                9968     ret = (xmlSchemaSchemaRelationPtr)
                9969     xmlMalloc(sizeof(xmlSchemaSchemaRelation));
                9970     if (ret == NULL) {
                9971     xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
                9972     return(NULL);
                9973     }
                9974     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
                9975     return(ret);
                9976 }
                9977 
                9978 #if 0
                9979 static void
                9980 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
                9981 {
                9982     xmlFree(rel);
                9983 }
                9984 #endif
                9985 
                9986 static void
                9987 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
                9988 {
                9989     xmlSchemaRedefPtr prev;
                9990 
                9991     while (redef != NULL) {
                9992     prev = redef;
                9993     redef = redef->next;
                9994     xmlFree(prev);
                9995     }
                9996 }
                9997 
                9998 static void
                9999 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
                10000 {
                10001     /*
                10002     * After the construction context has been freed, there will be
                10003     * no schema graph available any more. Only the schema buckets
                10004     * will stay alive, which are put into the "schemasImports" and
                10005     * "includes" slots of the xmlSchema.
                10006     */
                10007     if (con->buckets != NULL)
                10008     xmlSchemaItemListFree(con->buckets);
                10009     if (con->pending != NULL)
                10010     xmlSchemaItemListFree(con->pending);
                10011     if (con->substGroups != NULL)
                10012     xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
                10013     if (con->redefs != NULL)
                10014     xmlSchemaRedefListFree(con->redefs);
                10015     if (con->dict != NULL)
                10016     xmlDictFree(con->dict);
                10017     xmlFree(con);
                10018 }
                10019 
                10020 static xmlSchemaConstructionCtxtPtr
                10021 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
                10022 {
                10023     xmlSchemaConstructionCtxtPtr ret;
                10024 
                10025     ret = (xmlSchemaConstructionCtxtPtr)
                10026     xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
                10027     if (ret == NULL) {
                10028         xmlSchemaPErrMemory(NULL,
                10029         "allocating schema construction context", NULL);
                10030         return (NULL);
                10031     }
                10032     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
                10033 
                10034     ret->buckets = xmlSchemaItemListCreate();
                10035     if (ret->buckets == NULL) {
                10036     xmlSchemaPErrMemory(NULL,
                10037         "allocating list of schema buckets", NULL);
                10038     xmlFree(ret);
                10039         return (NULL);
                10040     }
                10041     ret->pending = xmlSchemaItemListCreate();
                10042     if (ret->pending == NULL) {
                10043     xmlSchemaPErrMemory(NULL,
                10044         "allocating list of pending global components", NULL);
                10045     xmlSchemaConstructionCtxtFree(ret);
                10046         return (NULL);
                10047     }
                10048     ret->dict = dict;
                10049     xmlDictReference(dict);
                10050     return(ret);
                10051 }
                10052 
                10053 static xmlSchemaParserCtxtPtr
                10054 xmlSchemaParserCtxtCreate(void)
                10055 {
                10056     xmlSchemaParserCtxtPtr ret;
                10057 
                10058     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
                10059     if (ret == NULL) {
                10060         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
                10061                             NULL);
                10062         return (NULL);
                10063     }
                10064     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
                10065     ret->type = XML_SCHEMA_CTXT_PARSER;
                10066     ret->attrProhibs = xmlSchemaItemListCreate();
                10067     if (ret->attrProhibs == NULL) {
                10068     xmlFree(ret);
                10069     return(NULL);
                10070     }
                10071     return(ret);
                10072 }
                10073 
                10074 /**
                10075  * xmlSchemaNewParserCtxtUseDict:
                10076  * @URL:  the location of the schema
                10077  * @dict: the dictionary to be used
                10078  *
                10079  * Create an XML Schemas parse context for that file/resource expected
                10080  * to contain an XML Schemas file.
                10081  *
                10082  * Returns the parser context or NULL in case of error
                10083  */
                10084 static xmlSchemaParserCtxtPtr
                10085 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
                10086 {
                10087     xmlSchemaParserCtxtPtr ret;
                10088 
                10089     ret = xmlSchemaParserCtxtCreate();
                10090     if (ret == NULL)
                10091         return (NULL);
                10092     ret->dict = dict;
                10093     xmlDictReference(dict);
                10094     if (URL != NULL)
                10095     ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
                10096     return (ret);
                10097 }
                10098 
                10099 static int
                10100 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
                10101 {
                10102     if (vctxt->pctxt == NULL) {
                10103         if (vctxt->schema != NULL)
                10104         vctxt->pctxt =
                10105         xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
                10106     else
                10107         vctxt->pctxt = xmlSchemaNewParserCtxt("*");
                10108     if (vctxt->pctxt == NULL) {
                10109         VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
                10110         "failed to create a temp. parser context");
                10111         return (-1);
                10112     }
                10113     /* TODO: Pass user data. */
                10114     xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
                10115         vctxt->warning, vctxt->errCtxt);
                10116     xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
                10117         vctxt->errCtxt);
                10118     }
                10119     return (0);
                10120 }
                10121 
                10122 /**
                10123  * xmlSchemaGetSchemaBucket:
                10124  * @pctxt: the schema parser context
                10125  * @schemaLocation: the URI of the schema document
                10126  *
                10127  * Returns a schema bucket if it was already parsed.
                10128  *
                10129  * Returns a schema bucket if it was already parsed from
                10130  *         @schemaLocation, NULL otherwise.
                10131  */
                10132 static xmlSchemaBucketPtr
                10133 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
                10134                 const xmlChar *schemaLocation)
                10135 {
                10136     xmlSchemaBucketPtr cur;
                10137     xmlSchemaItemListPtr list;
                10138 
                10139     list = pctxt->constructor->buckets;
                10140     if (list->nbItems == 0)
                10141     return(NULL);
                10142     else {
                10143     int i;
                10144     for (i = 0; i < list->nbItems; i++) {
                10145         cur = (xmlSchemaBucketPtr) list->items[i];
                10146         /* Pointer comparison! */
                10147         if (cur->schemaLocation == schemaLocation)
                10148         return(cur);
                10149     }
                10150     }
                10151     return(NULL);
                10152 }
                10153 
                10154 static xmlSchemaBucketPtr
                10155 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
                10156                      const xmlChar *schemaLocation,
                10157                      const xmlChar *targetNamespace)
                10158 {
                10159     xmlSchemaBucketPtr cur;
                10160     xmlSchemaItemListPtr list;
                10161 
                10162     list = pctxt->constructor->buckets;
                10163     if (list->nbItems == 0)
                10164     return(NULL);
                10165     else {
                10166     int i;
                10167     for (i = 0; i < list->nbItems; i++) {
                10168         cur = (xmlSchemaBucketPtr) list->items[i];
                10169         /* Pointer comparison! */
                10170         if ((cur->origTargetNamespace == NULL) &&
                10171         (cur->schemaLocation == schemaLocation) &&
                10172         (cur->targetNamespace == targetNamespace))
                10173         return(cur);
                10174     }
                10175     }
                10176     return(NULL);
                10177 }
                10178 
                10179 
                10180 #define IS_BAD_SCHEMA_DOC(b) \
                10181     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
                10182 
                10183 static xmlSchemaBucketPtr
                10184 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
                10185                  const xmlChar *targetNamespace,
                10186                  int imported)
                10187 {
                10188     xmlSchemaBucketPtr cur;
                10189     xmlSchemaItemListPtr list;
                10190 
                10191     list = pctxt->constructor->buckets;
                10192     if (list->nbItems == 0)
                10193     return(NULL);
                10194     else {
                10195     int i;
                10196     for (i = 0; i < list->nbItems; i++) {
                10197         cur = (xmlSchemaBucketPtr) list->items[i];
                10198         if ((! IS_BAD_SCHEMA_DOC(cur)) &&
                10199         (cur->origTargetNamespace == targetNamespace) &&
                10200         ((imported && cur->imported) ||
                10201          ((!imported) && (!cur->imported))))
                10202         return(cur);
                10203     }
                10204     }
                10205     return(NULL);
                10206 }
                10207 
                10208 static int
                10209 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
                10210              xmlSchemaPtr schema,
                10211              xmlSchemaBucketPtr bucket)
                10212 {
                10213     int oldFlags;
                10214     xmlDocPtr oldDoc;
                10215     xmlNodePtr node;
                10216     int ret, oldErrs;
                10217     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
                10218 
                10219     /*
                10220     * Save old values; reset the *main* schema.
                10221     * URGENT TODO: This is not good; move the per-document information
                10222     * to the parser. Get rid of passing the main schema to the
                10223     * parsing functions.
                10224     */
                10225     oldFlags = schema->flags;
                10226     oldDoc = schema->doc;
                10227     if (schema->flags != 0)
                10228     xmlSchemaClearSchemaDefaults(schema);
                10229     schema->doc = bucket->doc;
                10230     pctxt->schema = schema;
                10231     /*
                10232     * Keep the current target namespace on the parser *not* on the
                10233     * main schema.
                10234     */
                10235     pctxt->targetNamespace = bucket->targetNamespace;
                10236     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
                10237 
                10238     if ((bucket->targetNamespace != NULL) &&
                10239     xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
                10240     /*
                10241     * We are parsing the schema for schemas!
                10242     */
                10243     pctxt->isS4S = 1;
                10244     }
                10245     /* Mark it as parsed, even if parsing fails. */
                10246     bucket->parsed++;
                10247     /* Compile the schema doc. */
                10248     node = xmlDocGetRootElement(bucket->doc);
                10249     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
                10250     if (ret != 0)
                10251     goto exit;
                10252     /* An empty schema; just get out. */
                10253     if (node->children == NULL)
                10254     goto exit;
                10255     oldErrs = pctxt->nberrors;
                10256     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
                10257     if (ret != 0)
                10258     goto exit;
                10259     /*
                10260     * TODO: Not nice, but I'm not 100% sure we will get always an error
                10261     * as a result of the above functions; so better rely on pctxt->err
                10262     * as well.
                10263     */
                10264     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
                10265     ret = pctxt->err;
                10266     goto exit;
                10267     }
                10268 
                10269 exit:
                10270     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
                10271     /* Restore schema values. */
                10272     schema->doc = oldDoc;
                10273     schema->flags = oldFlags;
                10274     return(ret);
                10275 }
                10276 
                10277 static int
                10278 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
                10279              xmlSchemaPtr schema,
                10280              xmlSchemaBucketPtr bucket)
                10281 {
                10282     xmlSchemaParserCtxtPtr newpctxt;
                10283     int res = 0;
                10284 
                10285     if (bucket == NULL)
                10286     return(0);
                10287     if (bucket->parsed) {
                10288     PERROR_INT("xmlSchemaParseNewDoc",
                10289         "reparsing a schema doc");
                10290     return(-1);
                10291     }
                10292     if (bucket->doc == NULL) {
                10293     PERROR_INT("xmlSchemaParseNewDoc",
                10294         "parsing a schema doc, but there's no doc");
                10295     return(-1);
                10296     }
                10297     if (pctxt->constructor == NULL) {
                10298     PERROR_INT("xmlSchemaParseNewDoc",
                10299         "no constructor");
                10300     return(-1);
                10301     }
                10302     /* Create and init the temporary parser context. */
                10303     newpctxt = xmlSchemaNewParserCtxtUseDict(
                10304     (const char *) bucket->schemaLocation, pctxt->dict);
                10305     if (newpctxt == NULL)
                10306     return(-1);
                10307     newpctxt->constructor = pctxt->constructor;
                10308     /*
                10309     * TODO: Can we avoid that the parser knows about the main schema?
                10310     * It would be better if he knows about the current schema bucket
                10311     * only.
                10312     */
                10313     newpctxt->schema = schema;
                10314     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
                10315     pctxt->errCtxt);
                10316     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
                10317     pctxt->errCtxt);
                10318     newpctxt->counter = pctxt->counter;
                10319 
                10320 
                10321     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
                10322 
                10323     /* Channel back errors and cleanup the temporary parser context. */
                10324     if (res != 0)
                10325     pctxt->err = res;
                10326     pctxt->nberrors += newpctxt->nberrors;
                10327     pctxt->counter = newpctxt->counter;
                10328     newpctxt->constructor = NULL;
                10329     /* Free the parser context. */
                10330     xmlSchemaFreeParserCtxt(newpctxt);
                10331     return(res);
                10332 }
                10333 
                10334 static void
                10335 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
                10336                 xmlSchemaSchemaRelationPtr rel)
                10337 {
                10338     xmlSchemaSchemaRelationPtr cur = bucket->relations;
                10339 
                10340     if (cur == NULL) {
                10341     bucket->relations = rel;
                10342     return;
                10343     }
                10344     while (cur->next != NULL)
                10345     cur = cur->next;
                10346     cur->next = rel;
                10347 }
                10348 
                10349 
                10350 static const xmlChar *
                10351 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
                10352               xmlNodePtr ctxtNode)
                10353 {
                10354     /*
                10355     * Build an absolute location URI.
                10356     */
                10357     if (location != NULL) {
                10358     if (ctxtNode == NULL)
                10359         return(location);
                10360     else {
                10361         xmlChar *base, *URI;
                10362         const xmlChar *ret = NULL;
                10363 
                10364         base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
                10365         if (base == NULL) {
                10366         URI = xmlBuildURI(location, ctxtNode->doc->URL);
                10367         } else {
                10368         URI = xmlBuildURI(location, base);
                10369         xmlFree(base);
                10370         }
                10371         if (URI != NULL) {
                10372         ret = xmlDictLookup(dict, URI, -1);
                10373         xmlFree(URI);
                10374         return(ret);
                10375         }
                10376     }
                10377     }
                10378     return(NULL);
                10379 }
                10380 
                10381 
                10382 
                10383 /**
                10384  * xmlSchemaAddSchemaDoc:
                10385  * @pctxt:  a schema validation context
                10386  * @schema:  the schema being built
                10387  * @node:  a subtree containing XML Schema information
                10388  *
                10389  * Parse an included (and to-be-redefined) XML schema document.
                10390  *
                10391  * Returns 0 on success, a positive error code on errors and
                10392  *         -1 in case of an internal or API error.
                10393  */
                10394 
                10395 static int
                10396 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
                10397         int type, /* import or include or redefine */
                10398         const xmlChar *schemaLocation,
                10399         xmlDocPtr schemaDoc,
                10400         const char *schemaBuffer,
                10401         int schemaBufferLen,
                10402         xmlNodePtr invokingNode,
                10403         const xmlChar *sourceTargetNamespace,
                10404         const xmlChar *importNamespace,
                10405         xmlSchemaBucketPtr *bucket)
                10406 {
                10407     const xmlChar *targetNamespace = NULL;
                10408     xmlSchemaSchemaRelationPtr relation = NULL;
                10409     xmlDocPtr doc = NULL;
                10410     int res = 0, err = 0, located = 0, preserveDoc = 0;
                10411     xmlSchemaBucketPtr bkt = NULL;
                10412 
                10413     if (bucket != NULL)
                10414     *bucket = NULL;
                10415 
                10416     switch (type) {
                10417     case XML_SCHEMA_SCHEMA_IMPORT:
                10418     case XML_SCHEMA_SCHEMA_MAIN:
                10419         err = XML_SCHEMAP_SRC_IMPORT;
                10420         break;
                10421     case XML_SCHEMA_SCHEMA_INCLUDE:
                10422         err = XML_SCHEMAP_SRC_INCLUDE;
                10423         break;
                10424     case XML_SCHEMA_SCHEMA_REDEFINE:
                10425         err = XML_SCHEMAP_SRC_REDEFINE;
                10426         break;
                10427     }
                10428 
                10429 
                10430     /* Special handling for the main schema:
                10431     * skip the location and relation logic and just parse the doc.
                10432     * We need just a bucket to be returned in this case.
                10433     */
                10434     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
                10435     goto doc_load;
                10436 
                10437     /* Note that we expect the location to be an absolute URI. */
                10438     if (schemaLocation != NULL) {
                10439     bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
                10440     if ((bkt != NULL) &&
                10441         (pctxt->constructor->bucket == bkt)) {
                10442         /* Report self-imports/inclusions/redefinitions. */
                10443 
                10444         xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
                10445         invokingNode, NULL,
                10446         "The schema must not import/include/redefine itself",
                10447         NULL, NULL);
                10448         goto exit;
                10449     }
                10450     }
                10451     /*
                10452     * Create a relation for the graph of schemas.
                10453     */
                10454     relation = xmlSchemaSchemaRelationCreate();
                10455     if (relation == NULL)
                10456     return(-1);
                10457     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
                10458     relation);
                10459     relation->type = type;
                10460 
                10461     /*
                10462     * Save the namespace import information.
                10463     */
                10464     if (WXS_IS_BUCKET_IMPMAIN(type)) {
                10465     relation->importNamespace = importNamespace;
                10466     if (schemaLocation == NULL) {
                10467         /*
                10468         * No location; this is just an import of the namespace.
                10469         * Note that we don't assign a bucket to the relation
                10470         * in this case.
                10471         */
                10472         goto exit;
                10473     }
                10474     targetNamespace = importNamespace;
                10475     }
                10476 
                10477     /* Did we already fetch the doc? */
                10478     if (bkt != NULL) {
                10479     if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
                10480         /*
                10481         * We included/redefined and then try to import a schema,
                10482         * but the new location provided for import was different.
                10483         */
                10484         if (schemaLocation == NULL)
                10485         schemaLocation = BAD_CAST "in_memory_buffer";
                10486         if (!xmlStrEqual(schemaLocation,
                10487         bkt->schemaLocation)) {
                10488         xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
                10489             invokingNode, NULL,
                10490             "The schema document '%s' cannot be imported, since "
                10491             "it was already included or redefined",
                10492             schemaLocation, NULL);
                10493         goto exit;
                10494         }
                10495     } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
                10496         /*
                10497         * We imported and then try to include/redefine a schema,
                10498         * but the new location provided for the include/redefine
                10499         * was different.
                10500         */
                10501         if (schemaLocation == NULL)
                10502         schemaLocation = BAD_CAST "in_memory_buffer";
                10503         if (!xmlStrEqual(schemaLocation,
                10504         bkt->schemaLocation)) {
                10505         xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
                10506             invokingNode, NULL,
                10507             "The schema document '%s' cannot be included or "
                10508             "redefined, since it was already imported",
                10509             schemaLocation, NULL);
                10510         goto exit;
                10511         }
                10512     }
                10513     }
                10514 
                10515     if (WXS_IS_BUCKET_IMPMAIN(type)) {
                10516     /*
                10517     * Given that the schemaLocation [attribute] is only a hint, it is open
                10518     * to applications to ignore all but the first <import> for a given
                10519     * namespace, regardless of the `actual value` of schemaLocation, but
                10520     * such a strategy risks missing useful information when new
                10521     * schemaLocations are offered.
                10522     *
                10523     * We will use the first <import> that comes with a location.
                10524     * Further <import>s *with* a location, will result in an error.
                10525     * TODO: Better would be to just report a warning here, but
                10526     * we'll try it this way until someone complains.
                10527     *
                10528     * Schema Document Location Strategy:
                10529     * 3 Based on the namespace name, identify an existing schema document,
                10530     * either as a resource which is an XML document or a <schema> element
                10531     * information item, in some local schema repository;
                10532     * 5 Attempt to resolve the namespace name to locate such a resource.
                10533     *
                10534     * NOTE: (3) and (5) are not supported.
                10535     */
                10536     if (bkt != NULL) {
                10537         relation->bucket = bkt;
                10538         goto exit;
                10539     }
                10540     bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
                10541         importNamespace, 1);
                10542 
                10543     if (bkt != NULL) {
                10544         relation->bucket = bkt;
                10545         if (bkt->schemaLocation == NULL) {
                10546         /* First given location of the schema; load the doc. */
                10547         bkt->schemaLocation = schemaLocation;
                10548         } else {
                10549         if (!xmlStrEqual(schemaLocation,
                10550             bkt->schemaLocation)) {
                10551             /*
                10552             * Additional location given; just skip it.
                10553             * URGENT TODO: We should report a warning here.
                10554             * res = XML_SCHEMAP_SRC_IMPORT;
                10555             */
                10556             if (schemaLocation == NULL)
                10557             schemaLocation = BAD_CAST "in_memory_buffer";
                10558 
                10559             xmlSchemaCustomWarning(ACTXT_CAST pctxt,
                10560             XML_SCHEMAP_WARN_SKIP_SCHEMA,
                10561             invokingNode, NULL,
                10562             "Skipping import of schema located at '%s' for the "
                10563             "namespace '%s', since this namespace was already "
                10564             "imported with the schema located at '%s'",
                10565             schemaLocation, importNamespace, bkt->schemaLocation);
                10566         }
                10567         goto exit;
                10568         }
                10569     }
                10570     /*
                10571     * No bucket + first location: load the doc and create a
                10572     * bucket.
                10573     */
                10574     } else {
                10575     /* <include> and <redefine> */
                10576     if (bkt != NULL) {
                10577 
                10578         if ((bkt->origTargetNamespace == NULL) &&
                10579         (bkt->targetNamespace != sourceTargetNamespace)) {
                10580         xmlSchemaBucketPtr chamel;
                10581 
                10582         /*
                10583         * Chameleon include/redefine: skip loading only if it was
                10584         * already build for the targetNamespace of the including
                10585         * schema.
                10586         */
                10587         /*
                10588         * URGENT TODO: If the schema is a chameleon-include then copy
                10589         * the components into the including schema and modify the
                10590         * targetNamespace of those components, do nothing otherwise.
                10591         * NOTE: This is currently worked-around by compiling the
                10592         * chameleon for every distinct including targetNamespace; thus
                10593         * not performant at the moment.
                10594         * TODO: Check when the namespace in wildcards for chameleons
                10595         * needs to be converted: before we built wildcard intersections
                10596         * or after.
                10597         *   Answer: after!
                10598         */
                10599         chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
                10600             schemaLocation, sourceTargetNamespace);
                10601         if (chamel != NULL) {
                10602             /* A fitting chameleon was already parsed; NOP. */
                10603             relation->bucket = chamel;
                10604             goto exit;
                10605         }
                10606         /*
                10607         * We need to parse the chameleon again for a different
                10608         * targetNamespace.
                10609         * CHAMELEON TODO: Optimize this by only parsing the
                10610         * chameleon once, and then copying the components to
                10611         * the new targetNamespace.
                10612         */
                10613         bkt = NULL;
                10614         } else {
                10615         relation->bucket = bkt;
                10616         goto exit;
                10617         }
                10618     }
                10619     }
                10620     if ((bkt != NULL) && (bkt->doc != NULL)) {
                10621     PERROR_INT("xmlSchemaAddSchemaDoc",
                10622         "trying to load a schema doc, but a doc is already "
                10623         "assigned to the schema bucket");
                10624     goto exit_failure;
                10625     }
                10626 
                10627 doc_load:
                10628     /*
                10629     * Load the document.
                10630     */
                10631     if (schemaDoc != NULL) {
                10632     doc = schemaDoc;
                10633     /* Don' free this one, since it was provided by the caller. */
                10634     preserveDoc = 1;
                10635     /* TODO: Does the context or the doc hold the location? */
                10636     if (schemaDoc->URL != NULL)
                10637         schemaLocation = xmlDictLookup(pctxt->dict,
                10638         schemaDoc->URL, -1);
                10639         else
                10640         schemaLocation = BAD_CAST "in_memory_buffer";
                10641     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
                10642     xmlParserCtxtPtr parserCtxt;
                10643 
                10644     parserCtxt = xmlNewParserCtxt();
                10645     if (parserCtxt == NULL) {
                10646         xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
                10647         "allocating a parser context", NULL);
                10648         goto exit_failure;
                10649     }
                10650     if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
                10651         /*
                10652         * TODO: Do we have to burden the schema parser dict with all
                10653         * the content of the schema doc?
                10654         */
                10655         xmlDictFree(parserCtxt->dict);
                10656         parserCtxt->dict = pctxt->dict;
                10657         xmlDictReference(parserCtxt->dict);
                10658     }
                10659     if (schemaLocation != NULL) {
                10660         /* Parse from file. */
                10661         doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
                10662         NULL, SCHEMAS_PARSE_OPTIONS);
                10663     } else if (schemaBuffer != NULL) {
                10664         /* Parse from memory buffer. */
                10665         doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
                10666         NULL, NULL, SCHEMAS_PARSE_OPTIONS);
                10667         schemaLocation = BAD_CAST "in_memory_buffer";
                10668         if (doc != NULL)
                10669         doc->URL = xmlStrdup(schemaLocation);
                10670     }
                10671     /*
                10672     * For <import>:
                10673     * 2.1 The referent is (a fragment of) a resource which is an
                10674     * XML document (see clause 1.1), which in turn corresponds to
                10675     * a <schema> element information item in a well-formed information
                10676     * set, which in turn corresponds to a valid schema.
                10677     * TODO: (2.1) fragments of XML documents are not supported.
                10678     *
                10679     * 2.2 The referent is a <schema> element information item in
                10680     * a well-formed information set, which in turn corresponds
                10681     * to a valid schema.
                10682     * TODO: (2.2) is not supported.
                10683     */
                10684     if (doc == NULL) {
                10685         xmlErrorPtr lerr;
                10686         lerr = xmlGetLastError();
                10687         /*
                10688         * Check if this a parser error, or if the document could
                10689         * just not be located.
                10690         * TODO: Try to find specific error codes to react only on
                10691         * localisation failures.
                10692         */
                10693         if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
                10694         /*
                10695         * We assume a parser error here.
                10696         */
                10697         located = 1;
                10698         /* TODO: Error code ?? */
                10699         res = XML_SCHEMAP_SRC_IMPORT_2_1;
                10700         xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
                10701             invokingNode, NULL,
                10702             "Failed to parse the XML resource '%s'",
                10703             schemaLocation, NULL);
                10704         }
                10705     }
                10706     xmlFreeParserCtxt(parserCtxt);
                10707     if ((doc == NULL) && located)
                10708         goto exit_error;
                10709     } else {
                10710     xmlSchemaPErr(pctxt, NULL,
                10711         XML_SCHEMAP_NOTHING_TO_PARSE,
                10712         "No information for parsing was provided with the "
                10713         "given schema parser context.\n",
                10714         NULL, NULL);
                10715     goto exit_failure;
                10716     }
                10717     /*
                10718     * Preprocess the document.
                10719     */
                10720     if (doc != NULL) {
                10721     xmlNodePtr docElem = NULL;
                10722 
                10723     located = 1;
                10724     docElem = xmlDocGetRootElement(doc);
                10725     if (docElem == NULL) {
                10726         xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
                10727         invokingNode, NULL,
                10728         "The document '%s' has no document element",
                10729         schemaLocation, NULL);
                10730         goto exit_error;
                10731     }
                10732     /*
                10733     * Remove all the blank text nodes.
                10734     */
                10735     xmlSchemaCleanupDoc(pctxt, docElem);
                10736     /*
                10737     * Check the schema's top level element.
                10738     */
                10739     if (!IS_SCHEMA(docElem, "schema")) {
                10740         xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
                10741         invokingNode, NULL,
                10742         "The XML document '%s' is not a schema document",
                10743         schemaLocation, NULL);
                10744         goto exit_error;
                10745     }
                10746     /*
                10747     * Note that we don't apply a type check for the
                10748     * targetNamespace value here.
                10749     */
                10750     targetNamespace = xmlSchemaGetProp(pctxt, docElem,
                10751         "targetNamespace");
                10752     }
                10753 
                10754 /* after_doc_loading: */
                10755     if ((bkt == NULL) && located) {
                10756     /* Only create a bucket if the schema was located. */
                10757         bkt = xmlSchemaBucketCreate(pctxt, type,
                10758         targetNamespace);
                10759     if (bkt == NULL)
                10760         goto exit_failure;
                10761     }
                10762     if (bkt != NULL) {
                10763     bkt->schemaLocation = schemaLocation;
                10764     bkt->located = located;
                10765     if (doc != NULL) {
                10766         bkt->doc = doc;
                10767         bkt->targetNamespace = targetNamespace;
                10768         bkt->origTargetNamespace = targetNamespace;
                10769         if (preserveDoc)
                10770         bkt->preserveDoc = 1;
                10771     }
                10772     if (WXS_IS_BUCKET_IMPMAIN(type))
                10773         bkt->imported++;
                10774         /*
                10775         * Add it to the graph of schemas.
                10776         */
                10777     if (relation != NULL)
                10778         relation->bucket = bkt;
                10779     }
                10780 
                10781 exit:
                10782     /*
                10783     * Return the bucket explicitly; this is needed for the
                10784     * main schema.
                10785     */
                10786     if (bucket != NULL)
                10787     *bucket = bkt;
                10788     return (0);
                10789 
                10790 exit_error:
                10791     if ((doc != NULL) && (! preserveDoc)) {
                10792     xmlFreeDoc(doc);
                10793     if (bkt != NULL)
                10794         bkt->doc = NULL;
                10795     }
                10796     return(pctxt->err);
                10797 
                10798 exit_failure:
                10799     if ((doc != NULL) && (! preserveDoc)) {
                10800     xmlFreeDoc(doc);
                10801     if (bkt != NULL)
                10802         bkt->doc = NULL;
                10803     }
                10804     return (-1);
                10805 }
                10806 
                10807 /**
                10808  * xmlSchemaParseImport:
                10809  * @ctxt:  a schema validation context
                10810  * @schema:  the schema being built
                10811  * @node:  a subtree containing XML Schema information
                10812  *
                10813  * parse a XML schema Import definition
                10814  * *WARNING* this interface is highly subject to change
                10815  *
                10816  * Returns 0 in case of success, a positive error code if
                10817  * not valid and -1 in case of an internal error.
                10818  */
                10819 static int
                10820 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
                10821                      xmlNodePtr node)
                10822 {
                10823     xmlNodePtr child;
                10824     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
                10825     const xmlChar *thisTargetNamespace;
                10826     xmlAttrPtr attr;
                10827     int ret = 0;
                10828     xmlSchemaBucketPtr bucket = NULL;
                10829 
                10830     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
                10831         return (-1);
                10832 
                10833     /*
                10834     * Check for illegal attributes.
                10835     */
                10836     attr = node->properties;
                10837     while (attr != NULL) {
                10838     if (attr->ns == NULL) {
                10839         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                10840         (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
                10841         (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
                10842         xmlSchemaPIllegalAttrErr(pctxt,
                10843             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                10844         }
                10845     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                10846         xmlSchemaPIllegalAttrErr(pctxt,
                10847         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                10848     }
                10849     attr = attr->next;
                10850     }
                10851     /*
                10852     * Extract and validate attributes.
                10853     */
                10854     if (xmlSchemaPValAttr(pctxt, NULL, node,
                10855     "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
                10856     &namespaceName) != 0) {
                10857     xmlSchemaPSimpleTypeErr(pctxt,
                10858         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                10859         NULL, node,
                10860         xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
                10861         NULL, namespaceName, NULL, NULL, NULL);
                10862     return (pctxt->err);
                10863     }
                10864 
                10865     if (xmlSchemaPValAttr(pctxt, NULL, node,
                10866     "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
                10867     &schemaLocation) != 0) {
                10868     xmlSchemaPSimpleTypeErr(pctxt,
                10869         XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                10870         NULL, node,
                10871         xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
                10872         NULL, schemaLocation, NULL, NULL, NULL);
                10873     return (pctxt->err);
                10874     }
                10875     /*
                10876     * And now for the children...
                10877     */
                10878     child = node->children;
                10879     if (IS_SCHEMA(child, "annotation")) {
                10880         /*
                10881          * the annotation here is simply discarded ...
                10882      * TODO: really?
                10883          */
                10884         child = child->next;
                10885     }
                10886     if (child != NULL) {
                10887     xmlSchemaPContentErr(pctxt,
                10888         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                10889         NULL, node, child, NULL,
                10890         "(annotation?)");
                10891     }
                10892     /*
                10893     * Apply additional constraints.
                10894     *
                10895     * Note that it is important to use the original @targetNamespace
                10896     * (or none at all), to rule out imports of schemas _with_ a
                10897     * @targetNamespace if the importing schema is a chameleon schema
                10898     * (with no @targetNamespace).
                10899     */
                10900     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
                10901     if (namespaceName != NULL) {
                10902     /*
                10903     * 1.1 If the namespace [attribute] is present, then its `actual value`
                10904     * must not match the `actual value` of the enclosing <schema>'s
                10905     * targetNamespace [attribute].
                10906     */
                10907     if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
                10908         xmlSchemaPCustomErr(pctxt,
                10909         XML_SCHEMAP_SRC_IMPORT_1_1,
                10910         NULL, node,
                10911         "The value of the attribute 'namespace' must not match "
                10912         "the target namespace '%s' of the importing schema",
                10913         thisTargetNamespace);
                10914         return (pctxt->err);
                10915     }
                10916     } else {
                10917     /*
                10918     * 1.2 If the namespace [attribute] is not present, then the enclosing
                10919     * <schema> must have a targetNamespace [attribute].
                10920     */
                10921     if (thisTargetNamespace == NULL) {
                10922         xmlSchemaPCustomErr(pctxt,
                10923         XML_SCHEMAP_SRC_IMPORT_1_2,
                10924         NULL, node,
                10925         "The attribute 'namespace' must be existent if "
                10926         "the importing schema has no target namespace",
                10927         NULL);
                10928         return (pctxt->err);
                10929     }
                10930     }
                10931     /*
                10932     * Locate and acquire the schema document.
                10933     */
                10934     if (schemaLocation != NULL)
                10935     schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
                10936         schemaLocation, node);
                10937     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
                10938     schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
                10939     namespaceName, &bucket);
                10940 
                10941     if (ret != 0)
                10942     return(ret);
                10943 
                10944     /*
                10945     * For <import>: "It is *not* an error for the application
                10946     * schema reference strategy to fail."
                10947     * So just don't parse if no schema document was found.
                10948     * Note that we will get no bucket if the schema could not be
                10949     * located or if there was no schemaLocation.
                10950     */
                10951     if ((bucket == NULL) && (schemaLocation != NULL)) {
                10952     xmlSchemaCustomWarning(ACTXT_CAST pctxt,
                10953         XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
                10954         node, NULL,
                10955         "Failed to locate a schema at location '%s'. "
                10956         "Skipping the import", schemaLocation, NULL, NULL);
                10957     }
                10958 
                10959     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
                10960     ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
                10961     }
                10962 
                10963     return (ret);
                10964 }
                10965 
                10966 static int
                10967 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
                10968                      xmlSchemaPtr schema,
                10969                      xmlNodePtr node,
                10970                      xmlChar **schemaLocation,
                10971                      int type)
                10972 {
                10973     xmlAttrPtr attr;
                10974 
                10975     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
                10976     (schemaLocation == NULL))
                10977         return (-1);
                10978 
                10979     *schemaLocation = NULL;
                10980     /*
                10981     * Check for illegal attributes.
                10982     * Applies for both <include> and <redefine>.
                10983     */
                10984     attr = node->properties;
                10985     while (attr != NULL) {
                10986     if (attr->ns == NULL) {
                10987         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                10988         (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
                10989         xmlSchemaPIllegalAttrErr(pctxt,
                10990             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                10991         }
                10992     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                10993         xmlSchemaPIllegalAttrErr(pctxt,
                10994         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                10995     }
                10996     attr = attr->next;
                10997     }
                10998     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
                10999     /*
                11000     * Preliminary step, extract the URI-Reference and make an URI
                11001     * from the base.
                11002     */
                11003     /*
                11004     * Attribute "schemaLocation" is mandatory.
                11005     */
                11006     attr = xmlSchemaGetPropNode(node, "schemaLocation");
                11007     if (attr != NULL) {
                11008         xmlChar *base = NULL;
                11009         xmlChar *uri = NULL;
                11010 
                11011     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
                11012         xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
                11013         (const xmlChar **) schemaLocation) != 0)
                11014         goto exit_error;
                11015     base = xmlNodeGetBase(node->doc, node);
                11016     if (base == NULL) {
                11017         uri = xmlBuildURI(*schemaLocation, node->doc->URL);
                11018     } else {
                11019         uri = xmlBuildURI(*schemaLocation, base);
                11020         xmlFree(base);
                11021     }
                11022     if (uri == NULL) {
                11023         PERROR_INT("xmlSchemaParseIncludeOrRedefine",
                11024         "could not build an URI from the schemaLocation")
                11025         goto exit_failure;
                11026     }
                11027     (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
                11028     xmlFree(uri);
                11029     } else {
                11030     xmlSchemaPMissingAttrErr(pctxt,
                11031         XML_SCHEMAP_S4S_ATTR_MISSING,
                11032         NULL, node, "schemaLocation", NULL);
                11033     goto exit_error;
                11034     }
                11035     /*
                11036     * Report self-inclusion and self-redefinition.
                11037     */
                11038     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
                11039     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
                11040         xmlSchemaPCustomErr(pctxt,
                11041         XML_SCHEMAP_SRC_REDEFINE,
                11042         NULL, node,
                11043         "The schema document '%s' cannot redefine itself.",
                11044         *schemaLocation);
                11045     } else {
                11046         xmlSchemaPCustomErr(pctxt,
                11047         XML_SCHEMAP_SRC_INCLUDE,
                11048         NULL, node,
                11049         "The schema document '%s' cannot include itself.",
                11050         *schemaLocation);
                11051     }
                11052     goto exit_error;
                11053     }
                11054 
                11055     return(0);
                11056 exit_error:
                11057     return(pctxt->err);
                11058 exit_failure:
                11059     return(-1);
                11060 }
                11061 
                11062 static int
                11063 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
                11064                 xmlSchemaPtr schema,
                11065                 xmlNodePtr node,
                11066                 int type)
                11067 {
                11068     xmlNodePtr child = NULL;
                11069     const xmlChar *schemaLocation = NULL;
                11070     int res = 0; /* hasRedefinitions = 0 */
                11071     int isChameleon = 0, wasChameleon = 0;
                11072     xmlSchemaBucketPtr bucket = NULL;
                11073 
                11074     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
                11075         return (-1);
                11076 
                11077     /*
                11078     * Parse attributes. Note that the returned schemaLocation will
                11079     * be already converted to an absolute URI.
                11080     */
                11081     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
                11082     node, (xmlChar **) (&schemaLocation), type);
                11083     if (res != 0)
                11084     return(res);
                11085     /*
                11086     * Load and add the schema document.
                11087     */
                11088     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
                11089     NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
                11090     if (res != 0)
                11091     return(res);
                11092     /*
                11093     * If we get no schema bucket back, then this means that the schema
                11094     * document could not be located or was broken XML or was not
                11095     * a schema document.
                11096     */
                11097     if ((bucket == NULL) || (bucket->doc == NULL)) {
                11098     if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
                11099         /*
                11100         * WARNING for <include>:
                11101         * We will raise an error if the schema cannot be located
                11102         * for inclusions, since the that was the feedback from the
                11103         * schema people. I.e. the following spec piece will *not* be
                11104         * satisfied:
                11105         * SPEC src-include: "It is not an error for the `actual value` of the
                11106         * schemaLocation [attribute] to fail to resolve it all, in which
                11107         * case no corresponding inclusion is performed.
                11108         * So do we need a warning report here?"
                11109         */
                11110         res = XML_SCHEMAP_SRC_INCLUDE;
                11111         xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
                11112         node, NULL,
                11113         "Failed to load the document '%s' for inclusion",
                11114         schemaLocation, NULL);
                11115     } else {
                11116         /*
                11117         * NOTE: This was changed to raise an error even if no redefinitions
                11118         * are specified.
                11119         *
                11120         * SPEC src-redefine (1)
                11121         * "If there are any element information items among the [children]
                11122         * other than <annotation> then the `actual value` of the
                11123         * schemaLocation [attribute] must successfully resolve."
                11124         * TODO: Ask the WG if a the location has always to resolve
                11125         * here as well!
                11126         */
                11127         res = XML_SCHEMAP_SRC_REDEFINE;
                11128         xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
                11129         node, NULL,
                11130         "Failed to load the document '%s' for redefinition",
                11131         schemaLocation, NULL);
                11132     }
                11133     } else {
                11134     /*
                11135     * Check targetNamespace sanity before parsing the new schema.
                11136     * TODO: Note that we won't check further content if the
                11137     * targetNamespace was bad.
                11138     */
                11139     if (bucket->origTargetNamespace != NULL) {
                11140         /*
                11141         * SPEC src-include (2.1)
                11142         * "SII has a targetNamespace [attribute], and its `actual
                11143         * value` is identical to the `actual value` of the targetNamespace
                11144         * [attribute] of SII' (which must have such an [attribute])."
                11145         */
                11146         if (pctxt->targetNamespace == NULL) {
                11147         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                11148             XML_SCHEMAP_SRC_INCLUDE,
                11149             node, NULL,
                11150             "The target namespace of the included/redefined schema "
                11151             "'%s' has to be absent, since the including/redefining "
                11152             "schema has no target namespace",
                11153             schemaLocation, NULL);
                11154         goto exit_error;
                11155         } else if (!xmlStrEqual(bucket->origTargetNamespace,
                11156         pctxt->targetNamespace)) {
                11157         /* TODO: Change error function. */
                11158         xmlSchemaPCustomErrExt(pctxt,
                11159             XML_SCHEMAP_SRC_INCLUDE,
                11160             NULL, node,
                11161             "The target namespace '%s' of the included/redefined "
                11162             "schema '%s' differs from '%s' of the "
                11163             "including/redefining schema",
                11164             bucket->origTargetNamespace, schemaLocation,
                11165             pctxt->targetNamespace);
                11166         goto exit_error;
                11167         }
                11168     } else if (pctxt->targetNamespace != NULL) {
                11169         /*
                11170         * Chameleons: the original target namespace will
                11171         * differ from the resulting namespace.
                11172         */
                11173         isChameleon = 1;
                11174         bucket->targetNamespace = pctxt->targetNamespace;
                11175     }
                11176     }
                11177     /*
                11178     * Parse the schema.
                11179     */
                11180     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
                11181     if (isChameleon) {
                11182         /* TODO: Get rid of this flag on the schema itself. */
                11183         if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
                11184         schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
                11185         } else
                11186         wasChameleon = 1;
                11187     }
                11188     xmlSchemaParseNewDoc(pctxt, schema, bucket);
                11189     /* Restore chameleon flag. */
                11190     if (isChameleon && (!wasChameleon))
                11191         schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
                11192     }
                11193     /*
                11194     * And now for the children...
                11195     */
                11196     child = node->children;
                11197     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
                11198     /*
                11199     * Parse (simpleType | complexType | group | attributeGroup))*
                11200     */
                11201     pctxt->redefined = bucket;
                11202     /*
                11203     * How to proceed if the redefined schema was not located?
                11204     */
                11205     pctxt->isRedefine = 1;
                11206     while (IS_SCHEMA(child, "annotation") ||
                11207         IS_SCHEMA(child, "simpleType") ||
                11208         IS_SCHEMA(child, "complexType") ||
                11209         IS_SCHEMA(child, "group") ||
                11210         IS_SCHEMA(child, "attributeGroup")) {
                11211         if (IS_SCHEMA(child, "annotation")) {
                11212         /*
                11213         * TODO: discard or not?
                11214         */
                11215         } else if (IS_SCHEMA(child, "simpleType")) {
                11216         xmlSchemaParseSimpleType(pctxt, schema, child, 1);
                11217         } else if (IS_SCHEMA(child, "complexType")) {
                11218         xmlSchemaParseComplexType(pctxt, schema, child, 1);
                11219         /* hasRedefinitions = 1; */
                11220         } else if (IS_SCHEMA(child, "group")) {
                11221         /* hasRedefinitions = 1; */
                11222         xmlSchemaParseModelGroupDefinition(pctxt,
                11223             schema, child);
                11224         } else if (IS_SCHEMA(child, "attributeGroup")) {
                11225         /* hasRedefinitions = 1; */
                11226         xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
                11227             child);
                11228         }
                11229         child = child->next;
                11230     }
                11231     pctxt->redefined = NULL;
                11232     pctxt->isRedefine = 0;
                11233     } else {
                11234     if (IS_SCHEMA(child, "annotation")) {
                11235         /*
                11236         * TODO: discard or not?
                11237         */
                11238         child = child->next;
                11239     }
                11240     }
                11241     if (child != NULL) {
                11242     res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
                11243     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
                11244         xmlSchemaPContentErr(pctxt, res,
                11245         NULL, node, child, NULL,
                11246         "(annotation | (simpleType | complexType | group | attributeGroup))*");
                11247     } else {
                11248          xmlSchemaPContentErr(pctxt, res,
                11249         NULL, node, child, NULL,
                11250         "(annotation?)");
                11251     }
                11252     }
                11253     return(res);
                11254 
                11255 exit_error:
                11256     return(pctxt->err);
                11257 }
                11258 
                11259 static int
                11260 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
                11261                        xmlNodePtr node)
                11262 {
                11263     int res;
                11264 #ifndef ENABLE_REDEFINE
                11265     TODO
                11266     return(0);
                11267 #endif
                11268     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
                11269     XML_SCHEMA_SCHEMA_REDEFINE);
                11270     if (res != 0)
                11271     return(res);
                11272     return(0);
                11273 }
                11274 
                11275 static int
                11276 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
                11277                        xmlNodePtr node)
                11278 {
                11279     int res;
                11280 
                11281     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
                11282     XML_SCHEMA_SCHEMA_INCLUDE);
                11283     if (res != 0)
                11284     return(res);
                11285     return(0);
                11286 }
                11287 
                11288 /**
                11289  * xmlSchemaParseModelGroup:
                11290  * @ctxt:  a schema validation context
                11291  * @schema:  the schema being built
                11292  * @node:  a subtree containing XML Schema information
                11293  * @type: the "compositor" type
                11294  * @particleNeeded: if a a model group with a particle
                11295  *
                11296  * parse a XML schema Sequence definition.
                11297  * Applies parts of:
                11298  *   Schema Representation Constraint:
                11299  *     Redefinition Constraints and Semantics (src-redefine)
                11300  *     (6.1), (6.1.1), (6.1.2)
                11301  *
                11302  *   Schema Component Constraint:
                11303  *     All Group Limited (cos-all-limited) (2)
                11304  *     TODO: Actually this should go to component-level checks,
                11305  *     but is done here due to performance. Move it to an other layer
                11306  *     is schema construction via an API is implemented.
                11307  *
                11308  * *WARNING* this interface is highly subject to change
                11309  *
                11310  * Returns -1 in case of error, 0 if the declaration is improper and
                11311  *         1 in case of success.
                11312  */
                11313 static xmlSchemaTreeItemPtr
                11314 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                11315              xmlNodePtr node, xmlSchemaTypeType type,
                11316              int withParticle)
                11317 {
                11318     xmlSchemaModelGroupPtr item;
                11319     xmlSchemaParticlePtr particle = NULL;
                11320     xmlNodePtr child = NULL;
                11321     xmlAttrPtr attr;
                11322     int min = 1, max = 1, isElemRef, hasRefs = 0;
                11323 
                11324     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                11325         return (NULL);
                11326     /*
                11327     * Create a model group with the given compositor.
                11328     */
                11329     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
                11330     if (item == NULL)
                11331     return (NULL);
                11332 
                11333     if (withParticle) {
                11334     if (type == XML_SCHEMA_TYPE_ALL) {
                11335         min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
                11336         max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
                11337     } else {
                11338         /* choice + sequence */
                11339         min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
                11340         max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
                11341         "(xs:nonNegativeInteger | unbounded)");
                11342     }
                11343     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
                11344     /*
                11345     * Create a particle
                11346     */
                11347     particle = xmlSchemaAddParticle(ctxt, node, min, max);
                11348     if (particle == NULL)
                11349         return (NULL);
                11350     particle->children = (xmlSchemaTreeItemPtr) item;
                11351     /*
                11352     * Check for illegal attributes.
                11353     */
                11354     attr = node->properties;
                11355     while (attr != NULL) {
                11356         if (attr->ns == NULL) {
                11357         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                11358             (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
                11359             (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
                11360             xmlSchemaPIllegalAttrErr(ctxt,
                11361             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11362         }
                11363         } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                11364         xmlSchemaPIllegalAttrErr(ctxt,
                11365             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11366         }
                11367         attr = attr->next;
                11368     }
                11369     } else {
                11370     /*
                11371     * Check for illegal attributes.
                11372     */
                11373     attr = node->properties;
                11374     while (attr != NULL) {
                11375         if (attr->ns == NULL) {
                11376         if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
                11377             xmlSchemaPIllegalAttrErr(ctxt,
                11378             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11379         }
                11380         } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                11381         xmlSchemaPIllegalAttrErr(ctxt,
                11382             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11383         }
                11384         attr = attr->next;
                11385     }
                11386     }
                11387 
                11388     /*
                11389     * Extract and validate attributes.
                11390     */
                11391     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                11392     /*
                11393     * And now for the children...
                11394     */
                11395     child = node->children;
                11396     if (IS_SCHEMA(child, "annotation")) {
                11397         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                11398         child = child->next;
                11399     }
                11400     if (type == XML_SCHEMA_TYPE_ALL) {
                11401     xmlSchemaParticlePtr part, last = NULL;
                11402 
                11403     while (IS_SCHEMA(child, "element")) {
                11404         part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
                11405         schema, child, &isElemRef, 0);
                11406         /*
                11407         * SPEC cos-all-limited (2)
                11408         * "The {max occurs} of all the particles in the {particles}
                11409         * of the ('all') group must be 0 or 1.
                11410         */
                11411         if (part != NULL) {
                11412         if (isElemRef)
                11413             hasRefs++;
                11414         if (part->minOccurs > 1) {
                11415             xmlSchemaPCustomErr(ctxt,
                11416             XML_SCHEMAP_COS_ALL_LIMITED,
                11417             NULL, child,
                11418             "Invalid value for minOccurs (must be 0 or 1)",
                11419             NULL);
                11420             /* Reset to 1. */
                11421             part->minOccurs = 1;
                11422         }
                11423         if (part->maxOccurs > 1) {
                11424             xmlSchemaPCustomErr(ctxt,
                11425             XML_SCHEMAP_COS_ALL_LIMITED,
                11426             NULL, child,
                11427             "Invalid value for maxOccurs (must be 0 or 1)",
                11428             NULL);
                11429             /* Reset to 1. */
                11430             part->maxOccurs = 1;
                11431         }
                11432         if (last == NULL)
                11433             item->children = (xmlSchemaTreeItemPtr) part;
                11434         else
                11435             last->next = (xmlSchemaTreeItemPtr) part;
                11436         last = part;
                11437         }
                11438         child = child->next;
                11439     }
                11440     if (child != NULL) {
                11441         xmlSchemaPContentErr(ctxt,
                11442         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11443         NULL, node, child, NULL,
                11444         "(annotation?, (annotation?, element*)");
                11445     }
                11446     } else {
                11447     /* choice + sequence */
                11448     xmlSchemaTreeItemPtr part = NULL, last = NULL;
                11449 
                11450     while ((IS_SCHEMA(child, "element")) ||
                11451         (IS_SCHEMA(child, "group")) ||
                11452         (IS_SCHEMA(child, "any")) ||
                11453         (IS_SCHEMA(child, "choice")) ||
                11454         (IS_SCHEMA(child, "sequence"))) {
                11455 
                11456         if (IS_SCHEMA(child, "element")) {
                11457         part = (xmlSchemaTreeItemPtr)
                11458             xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
                11459         if (part && isElemRef)
                11460             hasRefs++;
                11461         } else if (IS_SCHEMA(child, "group")) {
                11462         part =
                11463             xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
                11464         if (part != NULL)
                11465             hasRefs++;
                11466         /*
                11467         * Handle redefinitions.
                11468         */
                11469         if (ctxt->isRedefine && ctxt->redef &&
                11470             (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
                11471             part && part->children)
                11472         {
                11473             if ((xmlSchemaGetQNameRefName(part->children) ==
                11474                 ctxt->redef->refName) &&
                11475             (xmlSchemaGetQNameRefTargetNs(part->children) ==
                11476                 ctxt->redef->refTargetNs))
                11477             {
                11478             /*
                11479             * SPEC src-redefine:
                11480             * (6.1) "If it has a <group> among its contents at
                11481             * some level the `actual value` of whose ref
                11482             * [attribute] is the same as the `actual value` of
                11483             * its own name attribute plus target namespace, then
                11484             * all of the following must be true:"
                11485             * (6.1.1) "It must have exactly one such group."
                11486             */
                11487             if (ctxt->redefCounter != 0) {
                11488                 xmlChar *str = NULL;
                11489 
                11490                 xmlSchemaCustomErr(ACTXT_CAST ctxt,
                11491                 XML_SCHEMAP_SRC_REDEFINE, child, NULL,
                11492                 "The redefining model group definition "
                11493                 "'%s' must not contain more than one "
                11494                 "reference to the redefined definition",
                11495                 xmlSchemaFormatQName(&str,
                11496                     ctxt->redef->refTargetNs,
                11497                     ctxt->redef->refName),
                11498                 NULL);
                11499                 FREE_AND_NULL(str)
                11500                 part = NULL;
                11501             } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
                11502                 ((WXS_PARTICLE(part))->maxOccurs != 1))
                11503             {
                11504                 xmlChar *str = NULL;
                11505                 /*
                11506                 * SPEC src-redefine:
                11507                 * (6.1.2) "The `actual value` of both that
                11508                 * group's minOccurs and maxOccurs [attribute]
                11509                 * must be 1 (or `absent`).
                11510                 */
                11511                 xmlSchemaCustomErr(ACTXT_CAST ctxt,
                11512                 XML_SCHEMAP_SRC_REDEFINE, child, NULL,
                11513                 "The redefining model group definition "
                11514                 "'%s' must not contain a reference to the "
                11515                 "redefined definition with a "
                11516                 "maxOccurs/minOccurs other than 1",
                11517                 xmlSchemaFormatQName(&str,
                11518                     ctxt->redef->refTargetNs,
                11519                     ctxt->redef->refName),
                11520                 NULL);
                11521                 FREE_AND_NULL(str)
                11522                 part = NULL;
                11523             }
                11524             ctxt->redef->reference = WXS_BASIC_CAST part;
                11525             ctxt->redefCounter++;
                11526             }
                11527         }
                11528         } else if (IS_SCHEMA(child, "any")) {
                11529         part = (xmlSchemaTreeItemPtr)
                11530             xmlSchemaParseAny(ctxt, schema, child);
                11531         } else if (IS_SCHEMA(child, "choice")) {
                11532         part = xmlSchemaParseModelGroup(ctxt, schema, child,
                11533             XML_SCHEMA_TYPE_CHOICE, 1);
                11534         } else if (IS_SCHEMA(child, "sequence")) {
                11535         part = xmlSchemaParseModelGroup(ctxt, schema, child,
                11536             XML_SCHEMA_TYPE_SEQUENCE, 1);
                11537         }
                11538         if (part != NULL) {
                11539         if (last == NULL)
                11540             item->children = part;
                11541         else
                11542             last->next = part;
                11543         last = part;
                11544         }
                11545         child = child->next;
                11546     }
                11547     if (child != NULL) {
                11548         xmlSchemaPContentErr(ctxt,
                11549         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11550         NULL, node, child, NULL,
                11551         "(annotation?, (element | group | choice | sequence | any)*)");
                11552     }
                11553     }
                11554     if ((max == 0) && (min == 0))
                11555     return (NULL);
                11556     if (hasRefs) {
                11557     /*
                11558     * We need to resolve references.
                11559     */
                11560     WXS_ADD_PENDING(ctxt, item);
                11561     }
                11562     if (withParticle)
                11563     return ((xmlSchemaTreeItemPtr) particle);
                11564     else
                11565     return ((xmlSchemaTreeItemPtr) item);
                11566 }
                11567 
                11568 /**
                11569  * xmlSchemaParseRestriction:
                11570  * @ctxt:  a schema validation context
                11571  * @schema:  the schema being built
                11572  * @node:  a subtree containing XML Schema information
                11573  *
                11574  * parse a XML schema Restriction definition
                11575  * *WARNING* this interface is highly subject to change
                11576  *
                11577  * Returns the type definition or NULL in case of error
                11578  */
                11579 static xmlSchemaTypePtr
                11580 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                11581                           xmlNodePtr node, xmlSchemaTypeType parentType)
                11582 {
                11583     xmlSchemaTypePtr type;
                11584     xmlNodePtr child = NULL;
                11585     xmlAttrPtr attr;
                11586 
                11587     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                11588         return (NULL);
                11589     /* Not a component, don't create it. */
                11590     type = ctxt->ctxtType;
                11591     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
                11592 
                11593     /*
                11594     * Check for illegal attributes.
                11595     */
                11596     attr = node->properties;
                11597     while (attr != NULL) {
                11598     if (attr->ns == NULL) {
                11599         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                11600         (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
                11601         xmlSchemaPIllegalAttrErr(ctxt,
                11602             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11603         }
                11604     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                11605         xmlSchemaPIllegalAttrErr(ctxt,
                11606         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11607     }
                11608     attr = attr->next;
                11609     }
                11610     /*
                11611     * Extract and validate attributes.
                11612     */
                11613     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                11614     /*
                11615     * Attribute
                11616     */
                11617     /*
                11618     * Extract the base type. The "base" attribute is mandatory if inside
                11619     * a complex type or if redefining.
                11620     *
                11621     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
                11622     * among its [children]), the simple type definition which is
                11623     * the {content type} of the type definition `resolved` to by
                11624     * the `actual value` of the base [attribute]"
                11625     */
                11626     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
                11627     &(type->baseNs), &(type->base)) == 0)
                11628     {
                11629     if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
                11630         xmlSchemaPMissingAttrErr(ctxt,
                11631         XML_SCHEMAP_S4S_ATTR_MISSING,
                11632         NULL, node, "base", NULL);
                11633     } else if ((ctxt->isRedefine) &&
                11634         (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
                11635     {
                11636         if (type->base == NULL) {
                11637         xmlSchemaPMissingAttrErr(ctxt,
                11638             XML_SCHEMAP_S4S_ATTR_MISSING,
                11639             NULL, node, "base", NULL);
                11640         } else if ((! xmlStrEqual(type->base, type->name)) ||
                11641         (! xmlStrEqual(type->baseNs, type->targetNamespace)))
                11642         {
                11643         xmlChar *str1 = NULL, *str2 = NULL;
                11644         /*
                11645         * REDEFINE: SPEC src-redefine (5)
                11646         * "Within the [children], each <simpleType> must have a
                11647         * <restriction> among its [children] ... the `actual value` of
                11648         * whose base [attribute] must be the same as the `actual value`
                11649         * of its own name attribute plus target namespace;"
                11650         */
                11651         xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
                11652             NULL, node, "This is a redefinition, but the QName "
                11653             "value '%s' of the 'base' attribute does not match the "
                11654             "type's designation '%s'",
                11655             xmlSchemaFormatQName(&str1, type->baseNs, type->base),
                11656             xmlSchemaFormatQName(&str2, type->targetNamespace,
                11657             type->name), NULL);
                11658         FREE_AND_NULL(str1);
                11659         FREE_AND_NULL(str2);
                11660         /* Avoid confusion and erase the values. */
                11661         type->base = NULL;
                11662         type->baseNs = NULL;
                11663         }
                11664     }
                11665     }
                11666     /*
                11667     * And now for the children...
                11668     */
                11669     child = node->children;
                11670     if (IS_SCHEMA(child, "annotation")) {
                11671     /*
                11672     * Add the annotation to the simple type ancestor.
                11673     */
                11674     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
                11675         xmlSchemaParseAnnotation(ctxt, child, 1));
                11676         child = child->next;
                11677     }
                11678     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
                11679     /*
                11680     * Corresponds to <simpleType><restriction><simpleType>.
                11681     */
                11682     if (IS_SCHEMA(child, "simpleType")) {
                11683         if (type->base != NULL) {
                11684         /*
                11685         * src-restriction-base-or-simpleType
                11686         * Either the base [attribute] or the simpleType [child] of the
                11687         * <restriction> element must be present, but not both.
                11688         */
                11689         xmlSchemaPContentErr(ctxt,
                11690             XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
                11691             NULL, node, child,
                11692             "The attribute 'base' and the <simpleType> child are "
                11693             "mutually exclusive", NULL);
                11694         } else {
                11695         type->baseType = (xmlSchemaTypePtr)
                11696             xmlSchemaParseSimpleType(ctxt, schema, child, 0);
                11697         }
                11698         child = child->next;
                11699     } else if (type->base == NULL) {
                11700         xmlSchemaPContentErr(ctxt,
                11701         XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
                11702         NULL, node, child,
                11703         "Either the attribute 'base' or a <simpleType> child "
                11704         "must be present", NULL);
                11705     }
                11706     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
                11707     /*
                11708     * Corresponds to <complexType><complexContent><restriction>...
                11709     * followed by:
                11710     *
                11711     * Model groups <all>, <choice> and <sequence>.
                11712     */
                11713     if (IS_SCHEMA(child, "all")) {
                11714         type->subtypes = (xmlSchemaTypePtr)
                11715         xmlSchemaParseModelGroup(ctxt, schema, child,
                11716             XML_SCHEMA_TYPE_ALL, 1);
                11717         child = child->next;
                11718     } else if (IS_SCHEMA(child, "choice")) {
                11719         type->subtypes = (xmlSchemaTypePtr)
                11720         xmlSchemaParseModelGroup(ctxt,
                11721             schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
                11722         child = child->next;
                11723     } else if (IS_SCHEMA(child, "sequence")) {
                11724         type->subtypes = (xmlSchemaTypePtr)
                11725         xmlSchemaParseModelGroup(ctxt, schema, child,
                11726             XML_SCHEMA_TYPE_SEQUENCE, 1);
                11727         child = child->next;
                11728     /*
                11729     * Model group reference <group>.
                11730     */
                11731     } else if (IS_SCHEMA(child, "group")) {
                11732         type->subtypes = (xmlSchemaTypePtr)
                11733         xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
                11734         /*
                11735         * Note that the reference will be resolved in
                11736         * xmlSchemaResolveTypeReferences();
                11737         */
                11738         child = child->next;
                11739     }
                11740     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
                11741     /*
                11742     * Corresponds to <complexType><simpleContent><restriction>...
                11743     *
                11744     * "1.1 the simple type definition corresponding to the <simpleType>
                11745     * among the [children] of <restriction> if there is one;"
                11746     */
                11747     if (IS_SCHEMA(child, "simpleType")) {
                11748         /*
                11749         * We will store the to-be-restricted simple type in
                11750         * type->contentTypeDef *temporarily*.
                11751         */
                11752         type->contentTypeDef = (xmlSchemaTypePtr)
                11753         xmlSchemaParseSimpleType(ctxt, schema, child, 0);
                11754         if ( type->contentTypeDef == NULL)
                11755         return (NULL);
                11756         child = child->next;
                11757     }
                11758     }
                11759 
                11760     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
                11761     (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
                11762     xmlSchemaFacetPtr facet, lastfacet = NULL;
                11763     /*
                11764     * Corresponds to <complexType><simpleContent><restriction>...
                11765     * <simpleType><restriction>...
                11766     */
                11767 
                11768     /*
                11769     * Add the facets to the simple type ancestor.
                11770     */
                11771     /*
                11772     * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
                11773     * Simple Type Definition Schema Representation Constraint:
                11774     * *Single Facet Value*
                11775     */
                11776     while ((IS_SCHEMA(child, "minInclusive")) ||
                11777         (IS_SCHEMA(child, "minExclusive")) ||
                11778         (IS_SCHEMA(child, "maxInclusive")) ||
                11779         (IS_SCHEMA(child, "maxExclusive")) ||
                11780         (IS_SCHEMA(child, "totalDigits")) ||
                11781         (IS_SCHEMA(child, "fractionDigits")) ||
                11782         (IS_SCHEMA(child, "pattern")) ||
                11783         (IS_SCHEMA(child, "enumeration")) ||
                11784         (IS_SCHEMA(child, "whiteSpace")) ||
                11785         (IS_SCHEMA(child, "length")) ||
                11786         (IS_SCHEMA(child, "maxLength")) ||
                11787         (IS_SCHEMA(child, "minLength"))) {
                11788         facet = xmlSchemaParseFacet(ctxt, schema, child);
                11789         if (facet != NULL) {
                11790         if (lastfacet == NULL)
                11791             type->facets = facet;
                11792         else
                11793             lastfacet->next = facet;
                11794         lastfacet = facet;
                11795         lastfacet->next = NULL;
                11796         }
                11797         child = child->next;
                11798     }
                11799     /*
                11800     * Create links for derivation and validation.
                11801     */
                11802     if (type->facets != NULL) {
                11803         xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
                11804 
                11805         facet = type->facets;
                11806         do {
                11807         facetLink = (xmlSchemaFacetLinkPtr)
                11808             xmlMalloc(sizeof(xmlSchemaFacetLink));
                11809         if (facetLink == NULL) {
                11810             xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
                11811             xmlFree(facetLink);
                11812             return (NULL);
                11813         }
                11814         facetLink->facet = facet;
                11815         facetLink->next = NULL;
                11816         if (lastFacetLink == NULL)
                11817             type->facetSet = facetLink;
                11818         else
                11819             lastFacetLink->next = facetLink;
                11820         lastFacetLink = facetLink;
                11821         facet = facet->next;
                11822         } while (facet != NULL);
                11823     }
                11824     }
                11825     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
                11826     /*
                11827     * Attribute uses/declarations.
                11828     */
                11829     if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
                11830         (xmlSchemaItemListPtr *) &(type->attrUses),
                11831         XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
                11832         return(NULL);
                11833     /*
                11834     * Attribute wildcard.
                11835     */
                11836     if (IS_SCHEMA(child, "anyAttribute")) {
                11837         type->attributeWildcard =
                11838         xmlSchemaParseAnyAttribute(ctxt, schema, child);
                11839         child = child->next;
                11840     }
                11841     }
                11842     if (child != NULL) {
                11843     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
                11844         xmlSchemaPContentErr(ctxt,
                11845         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11846         NULL, node, child, NULL,
                11847         "annotation?, (group | all | choice | sequence)?, "
                11848         "((attribute | attributeGroup)*, anyAttribute?))");
                11849     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
                11850          xmlSchemaPContentErr(ctxt,
                11851         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11852         NULL, node, child, NULL,
                11853         "(annotation?, (simpleType?, (minExclusive | minInclusive | "
                11854         "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
                11855         "length | minLength | maxLength | enumeration | whiteSpace | "
                11856         "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
                11857     } else {
                11858         /* Simple type */
                11859         xmlSchemaPContentErr(ctxt,
                11860         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11861         NULL, node, child, NULL,
                11862         "(annotation?, (simpleType?, (minExclusive | minInclusive | "
                11863         "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
                11864         "length | minLength | maxLength | enumeration | whiteSpace | "
                11865         "pattern)*))");
                11866     }
                11867     }
                11868     return (NULL);
                11869 }
                11870 
                11871 /**
                11872  * xmlSchemaParseExtension:
                11873  * @ctxt:  a schema validation context
                11874  * @schema:  the schema being built
                11875  * @node:  a subtree containing XML Schema information
                11876  *
                11877  * Parses an <extension>, which is found inside a
                11878  * <simpleContent> or <complexContent>.
                11879  * *WARNING* this interface is highly subject to change.
                11880  *
                11881  * TODO: Returns the type definition or NULL in case of error
                11882  */
                11883 static xmlSchemaTypePtr
                11884 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                11885                         xmlNodePtr node, xmlSchemaTypeType parentType)
                11886 {
                11887     xmlSchemaTypePtr type;
                11888     xmlNodePtr child = NULL;
                11889     xmlAttrPtr attr;
                11890 
                11891     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                11892         return (NULL);
                11893     /* Not a component, don't create it. */
                11894     type = ctxt->ctxtType;
                11895     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
                11896 
                11897     /*
                11898     * Check for illegal attributes.
                11899     */
                11900     attr = node->properties;
                11901     while (attr != NULL) {
                11902     if (attr->ns == NULL) {
                11903         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                11904         (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
                11905         xmlSchemaPIllegalAttrErr(ctxt,
                11906             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11907         }
                11908     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                11909         xmlSchemaPIllegalAttrErr(ctxt,
                11910         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                11911     }
                11912     attr = attr->next;
                11913     }
                11914 
                11915     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                11916 
                11917     /*
                11918     * Attribute "base" - mandatory.
                11919     */
                11920     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
                11921     "base", &(type->baseNs), &(type->base)) == 0) &&
                11922     (type->base == NULL)) {
                11923     xmlSchemaPMissingAttrErr(ctxt,
                11924         XML_SCHEMAP_S4S_ATTR_MISSING,
                11925         NULL, node, "base", NULL);
                11926     }
                11927     /*
                11928     * And now for the children...
                11929     */
                11930     child = node->children;
                11931     if (IS_SCHEMA(child, "annotation")) {
                11932     /*
                11933     * Add the annotation to the type ancestor.
                11934     */
                11935     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
                11936         xmlSchemaParseAnnotation(ctxt, child, 1));
                11937         child = child->next;
                11938     }
                11939     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
                11940     /*
                11941     * Corresponds to <complexType><complexContent><extension>... and:
                11942     *
                11943     * Model groups <all>, <choice>, <sequence> and <group>.
                11944     */
                11945     if (IS_SCHEMA(child, "all")) {
                11946         type->subtypes = (xmlSchemaTypePtr)
                11947         xmlSchemaParseModelGroup(ctxt, schema,
                11948             child, XML_SCHEMA_TYPE_ALL, 1);
                11949         child = child->next;
                11950     } else if (IS_SCHEMA(child, "choice")) {
                11951         type->subtypes = (xmlSchemaTypePtr)
                11952         xmlSchemaParseModelGroup(ctxt, schema,
                11953             child, XML_SCHEMA_TYPE_CHOICE, 1);
                11954         child = child->next;
                11955     } else if (IS_SCHEMA(child, "sequence")) {
                11956         type->subtypes = (xmlSchemaTypePtr)
                11957         xmlSchemaParseModelGroup(ctxt, schema,
                11958         child, XML_SCHEMA_TYPE_SEQUENCE, 1);
                11959         child = child->next;
                11960     } else if (IS_SCHEMA(child, "group")) {
                11961         type->subtypes = (xmlSchemaTypePtr)
                11962         xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
                11963         /*
                11964         * Note that the reference will be resolved in
                11965         * xmlSchemaResolveTypeReferences();
                11966         */
                11967         child = child->next;
                11968     }
                11969     }
                11970     if (child != NULL) {
                11971     /*
                11972     * Attribute uses/declarations.
                11973     */
                11974     if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
                11975         (xmlSchemaItemListPtr *) &(type->attrUses),
                11976         XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
                11977         return(NULL);
                11978     /*
                11979     * Attribute wildcard.
                11980     */
                11981     if (IS_SCHEMA(child, "anyAttribute")) {
                11982         ctxt->ctxtType->attributeWildcard =
                11983         xmlSchemaParseAnyAttribute(ctxt, schema, child);
                11984         child = child->next;
                11985     }
                11986     }
                11987     if (child != NULL) {
                11988     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
                11989         /* Complex content extension. */
                11990         xmlSchemaPContentErr(ctxt,
                11991         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11992         NULL, node, child, NULL,
                11993         "(annotation?, ((group | all | choice | sequence)?, "
                11994         "((attribute | attributeGroup)*, anyAttribute?)))");
                11995     } else {
                11996         /* Simple content extension. */
                11997         xmlSchemaPContentErr(ctxt,
                11998         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                11999         NULL, node, child, NULL,
                12000         "(annotation?, ((attribute | attributeGroup)*, "
                12001         "anyAttribute?))");
                12002     }
                12003     }
                12004     return (NULL);
                12005 }
                12006 
                12007 /**
                12008  * xmlSchemaParseSimpleContent:
                12009  * @ctxt:  a schema validation context
                12010  * @schema:  the schema being built
                12011  * @node:  a subtree containing XML Schema information
                12012  *
                12013  * parse a XML schema SimpleContent definition
                12014  * *WARNING* this interface is highly subject to change
                12015  *
                12016  * Returns the type definition or NULL in case of error
                12017  */
                12018 static int
                12019 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
                12020                             xmlSchemaPtr schema, xmlNodePtr node,
                12021                 int *hasRestrictionOrExtension)
                12022 {
                12023     xmlSchemaTypePtr type;
                12024     xmlNodePtr child = NULL;
                12025     xmlAttrPtr attr;
                12026 
                12027     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
                12028     (hasRestrictionOrExtension == NULL))
                12029         return (-1);
                12030     *hasRestrictionOrExtension = 0;
                12031     /* Not a component, don't create it. */
                12032     type = ctxt->ctxtType;
                12033     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
                12034     /*
                12035     * Check for illegal attributes.
                12036     */
                12037     attr = node->properties;
                12038     while (attr != NULL) {
                12039     if (attr->ns == NULL) {
                12040         if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
                12041         xmlSchemaPIllegalAttrErr(ctxt,
                12042             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12043         }
                12044     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                12045         xmlSchemaPIllegalAttrErr(ctxt,
                12046         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12047     }
                12048     attr = attr->next;
                12049     }
                12050 
                12051     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                12052 
                12053     /*
                12054     * And now for the children...
                12055     */
                12056     child = node->children;
                12057     if (IS_SCHEMA(child, "annotation")) {
                12058     /*
                12059     * Add the annotation to the complex type ancestor.
                12060     */
                12061     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
                12062         xmlSchemaParseAnnotation(ctxt, child, 1));
                12063         child = child->next;
                12064     }
                12065     if (child == NULL) {
                12066     xmlSchemaPContentErr(ctxt,
                12067         XML_SCHEMAP_S4S_ELEM_MISSING,
                12068         NULL, node, NULL, NULL,
                12069         "(annotation?, (restriction | extension))");
                12070     }
                12071     if (child == NULL) {
                12072     xmlSchemaPContentErr(ctxt,
                12073         XML_SCHEMAP_S4S_ELEM_MISSING,
                12074         NULL, node, NULL, NULL,
                12075         "(annotation?, (restriction | extension))");
                12076     }
                12077     if (IS_SCHEMA(child, "restriction")) {
                12078         xmlSchemaParseRestriction(ctxt, schema, child,
                12079         XML_SCHEMA_TYPE_SIMPLE_CONTENT);
                12080     (*hasRestrictionOrExtension) = 1;
                12081         child = child->next;
                12082     } else if (IS_SCHEMA(child, "extension")) {
                12083         xmlSchemaParseExtension(ctxt, schema, child,
                12084         XML_SCHEMA_TYPE_SIMPLE_CONTENT);
                12085     (*hasRestrictionOrExtension) = 1;
                12086         child = child->next;
                12087     }
                12088     if (child != NULL) {
                12089     xmlSchemaPContentErr(ctxt,
                12090         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                12091         NULL, node, child, NULL,
                12092         "(annotation?, (restriction | extension))");
                12093     }
                12094     return (0);
                12095 }
                12096 
                12097 /**
                12098  * xmlSchemaParseComplexContent:
                12099  * @ctxt:  a schema validation context
                12100  * @schema:  the schema being built
                12101  * @node:  a subtree containing XML Schema information
                12102  *
                12103  * parse a XML schema ComplexContent definition
                12104  * *WARNING* this interface is highly subject to change
                12105  *
                12106  * Returns the type definition or NULL in case of error
                12107  */
                12108 static int
                12109 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
                12110                              xmlSchemaPtr schema, xmlNodePtr node,
                12111                  int *hasRestrictionOrExtension)
                12112 {
                12113     xmlSchemaTypePtr type;
                12114     xmlNodePtr child = NULL;
                12115     xmlAttrPtr attr;
                12116 
                12117     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
                12118     (hasRestrictionOrExtension == NULL))
                12119         return (-1);
                12120     *hasRestrictionOrExtension = 0;
                12121     /* Not a component, don't create it. */
                12122     type = ctxt->ctxtType;
                12123     /*
                12124     * Check for illegal attributes.
                12125     */
                12126     attr = node->properties;
                12127     while (attr != NULL) {
                12128     if (attr->ns == NULL) {
                12129         if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
                12130         (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
                12131         {
                12132         xmlSchemaPIllegalAttrErr(ctxt,
                12133             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12134         }
                12135     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                12136         xmlSchemaPIllegalAttrErr(ctxt,
                12137         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12138     }
                12139     attr = attr->next;
                12140     }
                12141 
                12142     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                12143 
                12144     /*
                12145     * Set the 'mixed' on the complex type ancestor.
                12146     */
                12147     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
                12148     if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
                12149         type->flags |= XML_SCHEMAS_TYPE_MIXED;
                12150     }
                12151     child = node->children;
                12152     if (IS_SCHEMA(child, "annotation")) {
                12153     /*
                12154     * Add the annotation to the complex type ancestor.
                12155     */
                12156     xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
                12157         xmlSchemaParseAnnotation(ctxt, child, 1));
                12158         child = child->next;
                12159     }
                12160     if (child == NULL) {
                12161     xmlSchemaPContentErr(ctxt,
                12162         XML_SCHEMAP_S4S_ELEM_MISSING,
                12163         NULL, node, NULL,
                12164         NULL, "(annotation?, (restriction | extension))");
                12165     }
                12166     if (child == NULL) {
                12167     xmlSchemaPContentErr(ctxt,
                12168         XML_SCHEMAP_S4S_ELEM_MISSING,
                12169         NULL, node, NULL,
                12170         NULL, "(annotation?, (restriction | extension))");
                12171     }
                12172     if (IS_SCHEMA(child, "restriction")) {
                12173         xmlSchemaParseRestriction(ctxt, schema, child,
                12174         XML_SCHEMA_TYPE_COMPLEX_CONTENT);
                12175     (*hasRestrictionOrExtension) = 1;
                12176         child = child->next;
                12177     } else if (IS_SCHEMA(child, "extension")) {
                12178         xmlSchemaParseExtension(ctxt, schema, child,
                12179         XML_SCHEMA_TYPE_COMPLEX_CONTENT);
                12180     (*hasRestrictionOrExtension) = 1;
                12181         child = child->next;
                12182     }
                12183     if (child != NULL) {
                12184     xmlSchemaPContentErr(ctxt,
                12185         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                12186         NULL, node, child,
                12187         NULL, "(annotation?, (restriction | extension))");
                12188     }
                12189     return (0);
                12190 }
                12191 
                12192 /**
                12193  * xmlSchemaParseComplexType:
                12194  * @ctxt:  a schema validation context
                12195  * @schema:  the schema being built
                12196  * @node:  a subtree containing XML Schema information
                12197  *
                12198  * parse a XML schema Complex Type definition
                12199  * *WARNING* this interface is highly subject to change
                12200  *
                12201  * Returns the type definition or NULL in case of error
                12202  */
                12203 static xmlSchemaTypePtr
                12204 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
                12205                           xmlNodePtr node, int topLevel)
                12206 {
                12207     xmlSchemaTypePtr type, ctxtType;
                12208     xmlNodePtr child = NULL;
                12209     const xmlChar *name = NULL;
                12210     xmlAttrPtr attr;
                12211     const xmlChar *attrValue;
                12212 #ifdef ENABLE_NAMED_LOCALS
                12213     char buf[40];
                12214 #endif
                12215     int final = 0, block = 0, hasRestrictionOrExtension = 0;
                12216 
                12217 
                12218     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
                12219         return (NULL);
                12220 
                12221     ctxtType = ctxt->ctxtType;
                12222 
                12223     if (topLevel) {
                12224     attr = xmlSchemaGetPropNode(node, "name");
                12225     if (attr == NULL) {
                12226         xmlSchemaPMissingAttrErr(ctxt,
                12227         XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
                12228         return (NULL);
                12229     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
                12230         xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
                12231         return (NULL);
                12232     }
                12233     }
                12234 
                12235     if (topLevel == 0) {
                12236     /*
                12237     * Parse as local complex type definition.
                12238     */
                12239 #ifdef ENABLE_NAMED_LOCALS
                12240         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
                12241     type = xmlSchemaAddType(ctxt, schema,
                12242         XML_SCHEMA_TYPE_COMPLEX,
                12243         xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
                12244         ctxt->targetNamespace, node, 0);
                12245 #else
                12246     type = xmlSchemaAddType(ctxt, schema,
                12247         XML_SCHEMA_TYPE_COMPLEX,
                12248         NULL, ctxt->targetNamespace, node, 0);
                12249 #endif
                12250     if (type == NULL)
                12251         return (NULL);
                12252     name = type->name;
                12253     type->node = node;
                12254     type->type = XML_SCHEMA_TYPE_COMPLEX;
                12255     /*
                12256     * TODO: We need the target namespace.
                12257     */
                12258     } else {
                12259     /*
                12260     * Parse as global complex type definition.
                12261     */
                12262     type = xmlSchemaAddType(ctxt, schema,
                12263         XML_SCHEMA_TYPE_COMPLEX,
                12264         name, ctxt->targetNamespace, node, 1);
                12265     if (type == NULL)
                12266         return (NULL);
                12267     type->node = node;
                12268     type->type = XML_SCHEMA_TYPE_COMPLEX;
                12269     type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
                12270     }
                12271     type->targetNamespace = ctxt->targetNamespace;
                12272     /*
                12273     * Handle attributes.
                12274     */
                12275     attr = node->properties;
                12276     while (attr != NULL) {
                12277     if (attr->ns == NULL) {
                12278         if (xmlStrEqual(attr->name, BAD_CAST "id")) {
                12279         /*
                12280         * Attribute "id".
                12281         */
                12282         xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
                12283         } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
                12284         /*
                12285         * Attribute "mixed".
                12286         */
                12287         if (xmlSchemaPGetBoolNodeValue(ctxt,
                12288             NULL, (xmlNodePtr) attr))
                12289             type->flags |= XML_SCHEMAS_TYPE_MIXED;
                12290         } else if (topLevel) {
                12291         /*
                12292         * Attributes of global complex type definitions.
                12293         */
                12294         if (xmlStrEqual(attr->name, BAD_CAST "name")) {
                12295             /* Pass. */
                12296         } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
                12297             /*
                12298             * Attribute "abstract".
                12299             */
                12300             if (xmlSchemaPGetBoolNodeValue(ctxt,
                12301                 NULL, (xmlNodePtr) attr))
                12302             type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
                12303         } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
                12304             /*
                12305             * Attribute "final".
                12306             */
                12307             attrValue = xmlSchemaGetNodeContent(ctxt,
                12308             (xmlNodePtr) attr);
                12309             if (xmlSchemaPValAttrBlockFinal(attrValue,
                12310             &(type->flags),
                12311             -1,
                12312             XML_SCHEMAS_TYPE_FINAL_EXTENSION,
                12313             XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
                12314             -1, -1, -1) != 0)
                12315             {
                12316             xmlSchemaPSimpleTypeErr(ctxt,
                12317                 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                12318                 NULL, (xmlNodePtr) attr, NULL,
                12319                 "(#all | List of (extension | restriction))",
                12320                 attrValue, NULL, NULL, NULL);
                12321             } else
                12322             final = 1;
                12323         } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
                12324             /*
                12325             * Attribute "block".
                12326             */
                12327             attrValue = xmlSchemaGetNodeContent(ctxt,
                12328             (xmlNodePtr) attr);
                12329             if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
                12330             -1,
                12331             XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
                12332             XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
                12333             -1, -1, -1) != 0) {
                12334             xmlSchemaPSimpleTypeErr(ctxt,
                12335                 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
                12336                 NULL, (xmlNodePtr) attr, NULL,
                12337                 "(#all | List of (extension | restriction)) ",
                12338                 attrValue, NULL, NULL, NULL);
                12339             } else
                12340             block = 1;
                12341         } else {
                12342             xmlSchemaPIllegalAttrErr(ctxt,
                12343                 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12344         }
                12345         } else {
                12346         xmlSchemaPIllegalAttrErr(ctxt,
                12347             XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12348         }
                12349     } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
                12350         xmlSchemaPIllegalAttrErr(ctxt,
                12351         XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
                12352     }
                12353     attr = attr->next;
                12354     }
                12355     if (! block) {
                12356     /*
                12357     * Apply default "block" values.
                12358     */
                12359     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
                12360         type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
                12361     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
                12362         type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
                12363     }
                12364     if (! final) {
                12365     /*
                12366     * Apply default "block" values.
                12367     */
                12368     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
                12369         type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
                12370     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
                12371         type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
                12372     }
                12373     /*
                12374     * And now for the children...
                12375     */
                12376     child = node->children;
                12377     if (IS_SCHEMA(child, "annotation")) {
                12378         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
                12379         child = child->next;
                12380     }
                12381     ctxt->ctxtType = type;
                12382     if (IS_SCHEMA(child, "simpleContent")) {
                12383     /*
                12384     * <complexType><simpleContent>...
                12385     * 3.4.3 : 2.2
                12386     * Specifying mixed='true' when the <simpleContent>
                12387     * alternative is chosen has no effect
                12388     */
                12389     if (type->flags & XML_SCHEMAS_TYPE_MIXED)
                12390         type->flags ^= XML_SCHEMAS_TYPE_MIXED;
                12391         xmlSchemaParseSimpleContent(ctxt, schema, child,
                12392         &hasRestrictionOrExtension);
                12393         child = child->next;
                12394     } else if (IS_SCHEMA(child, "complexContent")) {
                12395     /*
                12396     * <complexType><complexContent>...
                12397     */
                12398     type->contentType = XML_SCHEMA_CONTENT_EMPTY;
                12399         xmlSchemaParseComplexContent(ctxt, schema, child,
                12400         &hasRestrictionOrExtension);
                12401         child = child->next;
                12402     } else {
                12403     /*
                12404     * E.g <complexType><sequence>... or <complexType><attribute>... etc.
                12405     *
                12406     * SPEC
                12407     * "...the third alternative (neither <simpleContent> nor
                12408     * <complexContent>) is chosen. This case is understood as shorthand
                12409     * for complex content restricting the `ur-type definition`, and the
                12410     * details of the mappings should be modified as necessary.
                12411     */
                12412     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
                12413     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
                12414     /*
                12415     * Parse model groups.
                12416     */
                12417         if (IS_SCHEMA(child, "all")) {
                12418             type->subtypes = (xmlSchemaTypePtr)
                12419         xmlSchemaParseModelGroup(ctxt, schema, child,
                12420             XML_SCHEMA_TYPE_ALL, 1);
                12421             child = child->next;
                12422         } else if (IS_SCHEMA(child, "choice")) {
                12423             type->subtypes = (xmlSchemaTypePtr)
                12424         xmlSchemaParseModelGroup(ctxt, schema, child,
                12425             XML_SCHEMA_TYPE_CHOICE, 1);
                12426             child = child->next;
                12427         } else if (IS_SCHEMA(child, "sequence")) {
                12428             type->subtypes = (xmlSchemaTypePtr)
                12429         xmlSchemaParseModelGroup(ctxt, schema, child,
                12430             XML_SCHEMA_TYPE_SEQUENCE, 1);
                12431             child = child->next;
                12432         } else if (IS_SCHEMA(child, "group")) {
                12433             type->subtypes = (xmlSchemaTypePtr)
                12434         xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
                12435         /*
                12436         * Note that the reference will be resolved in
                12437         * xmlSchemaResolveTypeReferences();
                12438         */
                12439             child = child->next;
                12440         }
                12441     /*
                12442     * Parse attribute decls/refs.
                12443     */
                12444         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
                12445         (xmlSchemaItemListPtr *) &(type->attrUses),
                12446         XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
                12447         return(NULL);
                12448     /*
                12449     * Parse attribute wildcard.
                12450     */
                12451     if (IS_SCHEMA(child, "anyAttribute")) {
                12452         type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
                12453         child = child->next;
                12454     }
                12455     }
                12456     if (child != NULL) {
                12457     xmlSchemaPContentErr(ctxt,
                12458         XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
                12459         NULL, node, child,
                12460         NULL, "(annotation?, (simpleContent | complexContent | "
                12461         "((group | all | choice | sequence)?, ((attribute | "
                12462         "attributeGroup)*, anyAttribute?))))");
                12463     }
                12464     /*
                12465     * REDEFINE: SPEC src-redefine (5)
                12466     */
                12467     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
                12468     xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
                12469         NULL, node, "This is a redefinition, thus the "
                12470         "<complexType> must have a <restriction> or <extension> "
                12471         "grand-child", NULL);
                12472     }
                12473     ctxt->ctxtType = ctxtType;
                12474     return (type);
                12475 }
                12476 
                12477 /************************************************************************
                12478  *                                  *
                12479  *          Validating using Schemas            *
                12480  *                                  *
                12481  ************************************************************************/
                12482 
                12483 /************************************************************************
                12484  *                                  *
                12485  *          Reading/Writing Schemas             *
                12486  *                                  *
                12487  ************************************************************************/
                12488 
                12489 #if 0 /* Will be enabled if it is clear what options are needed. */
                12490 /**
                12491  * xmlSchemaParserCtxtSetOptions:
                12492  * @ctxt:   a schema parser context
                12493  * @options: a combination of xmlSchemaParserOption
                12494  *
                12495  * Sets the options to be used during the parse.
                12496  *
                12497  * Returns 0 in case of success, -1 in case of an
                12498  * API error.
                12499  */
                12500 static int
                12501 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
                12502                   int options)
                12503 
                12504 {
                12505     int i;
                12506 
                12507     if (ctxt == NULL)
                12508     return (-1);
                12509     /*
                12510     * WARNING: Change the start value if adding to the
                12511     * xmlSchemaParseOption.
                12512     */
                12513     for (i = 1; i < (int) sizeof(int) * 8; i++) {
                12514         if (options & 1<<i) {
                12515         return (-1);
                12516         }
                12517     }
                12518     ctxt->options = options;
                12519     return (0);
                12520 }
                12521 
                12522 /**
                12523  * xmlSchemaValidCtxtGetOptions:
                12524  * @ctxt: a schema parser context
                12525  *
                12526  * Returns the option combination of the parser context.
                12527  */
                12528 static int
                12529 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
                12530 
                12531 {
                12532     if (ctxt == NULL)
                12533     return (-1);
                12534     else
                12535     return (ctxt->options);
                12536 }
                12537 #endif
                12538 
                12539 /**
                12540  * xmlSchemaNewParserCtxt:
                12541  * @URL:  the location of the schema
                12542  *
                12543  * Create an XML Schemas parse context for that file/resource expected
                12544  * to contain an XML Schemas file.
                12545  *
                12546  * Returns the parser context or NULL in case of error
                12547  */
                12548 xmlSchemaParserCtxtPtr
                12549 xmlSchemaNewParserCtxt(const char *URL)
                12550 {
                12551     xmlSchemaParserCtxtPtr ret;
                12552 
                12553     if (URL == NULL)
                12554         return (NULL);
                12555 
                12556     ret = xmlSchemaParserCtxtCreate();
                12557     if (ret == NULL)
                12558     return(NULL);
                12559     ret->dict = xmlDictCreate();
                12560     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
                12561     return (ret);
                12562 }
                12563 
                12564 /**
                12565  * xmlSchemaNewMemParserCtxt:
                12566  * @buffer:  a pointer to a char array containing the schemas
                12567  * @size:  the size of the array
                12568  *
                12569  * Create an XML Schemas parse context for that memory buffer expected
                12570  * to contain an XML Schemas file.
                12571  *
                12572  * Returns the parser context or NULL in case of error
                12573  */
                12574 xmlSchemaParserCtxtPtr
                12575 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
                12576 {
                12577     xmlSchemaParserCtxtPtr ret;
                12578 
                12579     if ((buffer == NULL) || (size <= 0))
                12580         return (NULL);
                12581     ret = xmlSchemaParserCtxtCreate();
                12582     if (ret == NULL)
                12583     return(NULL);
                12584     ret->buffer = buffer;
                12585     ret->size = size;
                12586     ret->dict = xmlDictCreate();
                12587     return (ret);
                12588 }
                12589 
                12590 /**
                12591  * xmlSchemaNewDocParserCtxt:
                12592  * @doc:  a preparsed document tree
                12593  *
                12594  * Create an XML Schemas parse context for that document.
                12595  * NB. The document may be modified during the parsing process.
                12596  *
                12597  * Returns the parser context or NULL in case of error
                12598  */
                12599 xmlSchemaParserCtxtPtr
                12600 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
                12601 {
                12602     xmlSchemaParserCtxtPtr ret;
                12603 
                12604     if (doc == NULL)
                12605       return (NULL);
                12606     ret = xmlSchemaParserCtxtCreate();
                12607     if (ret == NULL)
                12608     return(NULL);
                12609     ret->doc = doc;
                12610     ret->dict = xmlDictCreate();
                12611     /* The application has responsibility for the document */
                12612     ret->preserve = 1;
                12613 
                12614     return (ret);
                12615 }
                12616 
                12617 /**
                12618  * xmlSchemaFreeParserCtxt:
                12619  * @ctxt:  the schema parser context
                12620  *
                12621  * Free the resources associated to the schema parser context
                12622  */
                12623 void
                12624 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
                12625 {
                12626     if (ctxt == NULL)
                12627         return;
                12628     if (ctxt->doc != NULL && !ctxt->preserve)
                12629         xmlFreeDoc(ctxt->doc);
                12630     if (ctxt->vctxt != NULL) {
                12631     xmlSchemaFreeValidCtxt(ctxt->vctxt);
                12632     }
                12633     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
                12634     xmlSchemaConstructionCtxtFree(ctxt->constructor);
                12635     ctxt->constructor = NULL;
                12636     ctxt->ownsConstructor = 0;
                12637     }
                12638     if (ctxt->attrProhibs != NULL)
                12639     xmlSchemaItemListFree(ctxt->attrProhibs);
                12640     xmlDictFree(ctxt->dict);
                12641     xmlFree(ctxt);
                12642 }
                12643 
                12644 /************************************************************************
                12645  *                                  *
                12646  *          Building the content models         *
                12647  *                                  *
                12648  ************************************************************************/
                12649 
                12650 /**
                12651  * xmlSchemaBuildContentModelForSubstGroup:
                12652  *
                12653  * Returns 1 if nillable, 0 otherwise
                12654  */
                12655 static int
                12656 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
                12657     xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
                12658 {
                12659     xmlAutomataStatePtr start, tmp;
                12660     xmlSchemaElementPtr elemDecl, member;
                12661     xmlSchemaSubstGroupPtr substGroup;
                12662     int i;
                12663     int ret = 0;
                12664 
                12665     elemDecl = (xmlSchemaElementPtr) particle->children;
                12666     /*
                12667     * Wrap the substitution group with a CHOICE.
                12668     */
                12669     start = pctxt->state;
                12670     if (end == NULL)
                12671     end = xmlAutomataNewState(pctxt->am);
                12672     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
                12673     if (substGroup == NULL) {
                12674     xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
                12675         XML_SCHEMAP_INTERNAL,
                12676         "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
                12677         "declaration is marked having a subst. group but none "
                12678         "available.\n", elemDecl->name, NULL);
                12679     return(0);
                12680     }
                12681     if (counter >= 0) {
                12682     /*
                12683     * NOTE that we put the declaration in, even if it's abstract.
                12684     * However, an error will be raised during *validation* if an element
                12685     * information item shall be validated against an abstract element
                12686     * declaration.
                12687     */
                12688     tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
                12689         xmlAutomataNewTransition2(pctxt->am, tmp, end,
                12690                 elemDecl->name, elemDecl->targetNamespace, elemDecl);
                12691     /*
                12692     * Add subst. group members.
                12693     */
                12694     for (i = 0; i < substGroup->members->nbItems; i++) {
                12695         member = (xmlSchemaElementPtr) substGroup->members->items[i];
                12696             xmlAutomataNewTransition2(pctxt->am, tmp, end,
                12697                        member->name, member->targetNamespace, member);
                12698     }
                12699     } else if (particle->maxOccurs == 1) {
                12700     /*
                12701     * NOTE that we put the declaration in, even if it's abstract,
                12702     */
                12703     xmlAutomataNewEpsilon(pctxt->am,
                12704         xmlAutomataNewTransition2(pctxt->am,
                12705         start, NULL,
                12706         elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
                12707     /*
                12708     * Add subst. group members.
                12709     */
                12710     for (i = 0; i < substGroup->members->nbItems; i++) {
                12711         member = (xmlSchemaElementPtr) substGroup->members->items[i];
                12712         /*
                12713         * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
                12714         *  was incorrectly used instead of xmlAutomataNewTransition2()
                12715         *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
                12716         *  section in xmlSchemaBuildAContentModel() ).
                12717         * TODO: Check if xmlAutomataNewOnceTrans2() was instead
                12718         *  intended for the above "counter" section originally. I.e.,
                12719         *  check xs:all with subst-groups.
                12720         *
                12721         * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
                12722         *                  member->name, member->targetNamespace,
                12723         *              1, 1, member);
                12724         */
                12725         tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
                12726         member->name, member->targetNamespace, member);
                12727         xmlAutomataNewEpsilon(pctxt->am, tmp, end);
                12728     }
                12729     } else {
                12730     xmlAutomataStatePtr hop;
                12731     int maxOccurs = particle->maxOccurs == UNBOUNDED ?
                12732         UNBOUNDED : particle->maxOccurs - 1;
                12733     int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
                12734 
                12735     counter =
                12736         xmlAutomataNewCounter(pctxt->am, minOccurs,
                12737         maxOccurs);
                12738     hop = xmlAutomataNewState(pctxt->am);
                12739 
                12740     xmlAutomataNewEpsilon(pctxt->am,
                12741         xmlAutomataNewTransition2(pctxt->am,
                12742         start, NULL,
                12743         elemDecl->name, elemDecl->targetNamespace, elemDecl),
                12744         hop);
                12745     /*
                12746      * Add subst. group members.
                12747      */
                12748     for (i = 0; i < substGroup->members->nbItems; i++) {
                12749         member = (xmlSchemaElementPtr) substGroup->members->items[i];
                12750         xmlAutomataNewEpsilon(pctxt->am,
                12751         xmlAutomataNewTransition2(pctxt->am,
                12752         start, NULL,
                12753         member->name, member->targetNamespace, member),
                12754         hop);
                12755     }
                12756     xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
                12757     xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
                12758     }
                12759     if (particle->minOccurs == 0) {
                12760     xmlAutomataNewEpsilon(pctxt->am, start, end);
                12761         ret = 1;
                12762     }
                12763     pctxt->state = end;
                12764     return(ret);
                12765 }
                12766 
                12767 /**
                12768  * xmlSchemaBuildContentModelForElement:
                12769  *
                12770  * Returns 1 if nillable, 0 otherwise
                12771  */
                12772 static int
                12773 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
                12774                      xmlSchemaParticlePtr particle)
                12775 {
                12776     int ret = 0;
                12777 
                12778     if (((xmlSchemaElementPtr) particle->children)->flags &
                12779     XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
                12780     /*
                12781     * Substitution groups.
                12782     */
                12783     ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
                12784     } else {
                12785     xmlSchemaElementPtr elemDecl;
                12786     xmlAutomataStatePtr start;
                12787 
                12788     elemDecl = (xmlSchemaElementPtr) particle->children;
                12789 
                12790     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
                12791         return(0);
                12792     if (particle->maxOccurs == 1) {
                12793         start = ctxt->state;
                12794         ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
                12795             elemDecl->name, elemDecl->targetNamespace, elemDecl);
                12796     } else if ((particle->maxOccurs >= UNBOUNDED) &&
                12797                (particle->minOccurs < 2)) {
                12798         /* Special case. */
                12799         start = ctxt->state;
                12800         ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
                12801         elemDecl->name, elemDecl->targetNamespace, elemDecl);
                12802         ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
                12803         elemDecl->name, elemDecl->targetNamespace, elemDecl);
                12804     } else {
                12805         int counter;
                12806         int maxOccurs = particle->maxOccurs == UNBOUNDED ?
                12807                 UNBOUNDED : particle->maxOccurs - 1;
                12808         int minOccurs = particle->minOccurs < 1 ?
                12809                 0 : particle->minOccurs - 1;
                12810 
                12811         start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
                12812         counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
                12813         ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
                12814         elemDecl->name, elemDecl->targetNamespace, elemDecl);
                12815         xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
                12816         ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
                12817         NULL, counter);
                12818     }
                12819     if (particle->minOccurs == 0) {
                12820         xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
                12821             ret = 1;
                12822         }
                12823     }
                12824     return(ret);
                12825 }
                12826 
                12827 /**
                12828  * xmlSchemaBuildAContentModel:
                12829  * @ctxt:  the schema parser context
                12830  * @particle:  the particle component
                12831  * @name:  the complex type's name whose content is being built
                12832  *
                12833  * Create the automaton for the {content type} of a complex type.
                12834  *
                12835  * Returns 1 if the content is nillable, 0 otherwise
                12836  */
                12837 static int
                12838 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
                12839                 xmlSchemaParticlePtr particle)
                12840 {
                12841     int ret = 0, tmp2;
                12842 
                12843     if (particle == NULL) {
                12844     PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
                12845     return(1);
                12846     }
                12847     if (particle->children == NULL) {
                12848     /*
                12849     * Just return in this case. A missing "term" of the particle
                12850     * might arise due to an invalid "term" component.
                12851     */
                12852     return(1);
                12853     }
                12854 
                12855     switch (particle->children->type) {
                12856     case XML_SCHEMA_TYPE_ANY: {
                12857         xmlAutomataStatePtr start, end;
                12858         xmlSchemaWildcardPtr wild;
                12859         xmlSchemaWildcardNsPtr ns;
                12860 
                12861         wild = (xmlSchemaWildcardPtr) particle->children;
                12862 
                12863         start = pctxt->state;
                12864         end = xmlAutomataNewState(pctxt->am);
                12865 
                12866         if (particle->maxOccurs == 1) {
                12867         if (wild->any == 1) {
                12868             /*
                12869             * We need to add both transitions:
                12870             *
                12871             * 1. the {"*", "*"} for elements in a namespace.
                12872             */
                12873             pctxt->state =
                12874             xmlAutomataNewTransition2(pctxt->am,
                12875             start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
                12876             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
                12877             /*
                12878             * 2. the {"*"} for elements in no namespace.
                12879             */
                12880             pctxt->state =
                12881             xmlAutomataNewTransition2(pctxt->am,
                12882             start, NULL, BAD_CAST "*", NULL, wild);
                12883             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
                12884 
                12885         } else if (wild->nsSet != NULL) {
                12886             ns = wild->nsSet;
                12887             do {
                12888             pctxt->state = start;
                12889             pctxt->state = xmlAutomataNewTransition2(pctxt->am,
                12890                 pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
                12891             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
                12892             ns = ns->next;
                12893             } while (ns != NULL);
                12894 
                12895         } else if (wild->negNsSet != NULL) {
                12896             pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
                12897             start, end, BAD_CAST "*", wild->negNsSet->value,
                12898             wild);
                12899         }
                12900         } else {
                12901         int counter;
                12902         xmlAutomataStatePtr hop;
                12903         int maxOccurs =
                12904             particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
                12905                                            particle->maxOccurs - 1;
                12906         int minOccurs =
                12907             particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
                12908 
                12909         counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
                12910         hop = xmlAutomataNewState(pctxt->am);
                12911         if (wild->any == 1) {
                12912             pctxt->state =
                12913             xmlAutomataNewTransition2(pctxt->am,
                12914             start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
                12915             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
                12916             pctxt->state =
                12917             xmlAutomataNewTransition2(pctxt->am,
                12918             start, NULL, BAD_CAST "*", NULL, wild);
                12919             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
                12920         } else if (wild->nsSet != NULL) {
                12921             ns = wild->nsSet;
                12922             do {
                12923             pctxt->state =
                12924                 xmlAutomataNewTransition2(pctxt->am,
                12925                 start, NULL, BAD_CAST "*", ns->value, wild);
                12926             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
                12927             ns = ns->next;
                12928             } while (ns != NULL);
                12929 
                12930         } else if (wild->negNsSet != NULL) {
                12931             pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
                12932             start, hop, BAD_CAST "*", wild->negNsSet->value,
                12933             wild);
                12934         }
                12935         xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
                12936         xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
                12937         }
                12938         if (particle->minOccurs == 0) {
                12939         xmlAutomataNewEpsilon(pctxt->am, start, end);
                12940                 ret = 1;
                12941         }
                12942         pctxt->state = end;
                12943             break;
                12944     }
                12945         case XML_SCHEMA_TYPE_ELEMENT:
                12946         ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
                12947         break;
                12948         case XML_SCHEMA_TYPE_SEQUENCE:{
                12949             xmlSchemaTreeItemPtr sub;
                12950 
                12951             ret = 1;
                12952             /*
                12953              * If max and min occurrences are default (1) then
                12954              * simply iterate over the particles of the <sequence>.
                12955              */
                12956             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
                12957                 sub = particle->children->children;
                12958 
                12959                 while (sub != NULL) {
                12960                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
                12961                                         (xmlSchemaParticlePtr) sub);
                12962                     if (tmp2 != 1) ret = 0;
                12963                     sub = sub->next;
                12964                 }
                12965             } else {
                12966                 xmlAutomataStatePtr oldstate = pctxt->state;
                12967 
                12968                 if (particle->maxOccurs >= UNBOUNDED) {
                12969                     if (particle->minOccurs > 1) {
                12970                         xmlAutomataStatePtr tmp;
                12971                         int counter;
                12972 
                12973                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
                12974                             oldstate, NULL);
                12975                         oldstate = pctxt->state;
                12976 
                12977                         counter = xmlAutomataNewCounter(pctxt->am,
                12978                             particle->minOccurs - 1, UNBOUNDED);
                12979 
                12980                         sub = particle->children->children;
                12981                         while (sub != NULL) {
                12982                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
                12983                                             (xmlSchemaParticlePtr) sub);
                12984                             if (tmp2 != 1) ret = 0;
                12985                             sub = sub->next;
                12986                         }
                12987                         tmp = pctxt->state;
                12988                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
                12989                                                    oldstate, counter);
                12990                         pctxt->state =
                12991                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
                12992                                                        NULL, counter);
                12993                         if (ret == 1)
                12994                             xmlAutomataNewEpsilon(pctxt->am,
                12995                                                 oldstate, pctxt->state);
                12996 
                12997                     } else {
                12998                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
                12999                             oldstate, NULL);
                13000                         oldstate = pctxt->state;
                13001 
                13002                         sub = particle->children->children;
                13003                         while (sub != NULL) {
                13004                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
                13005                                         (xmlSchemaParticlePtr) sub);
                13006                             if (tmp2 != 1) ret = 0;
                13007                             sub = sub->next;
                13008                         }
                13009                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
                13010                                               oldstate);
                13011                         /*
                13012                          * epsilon needed to block previous trans from
                13013                          * being allowed to enter back from another
                13014                          * construct
                13015                          */
                13016                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
                13017                                             pctxt->state, NULL);
                13018                         if (particle->minOccurs == 0) {
                13019                             xmlAutomataNewEpsilon(pctxt->am,
                13020                                 oldstate, pctxt->state);
                13021                             ret = 1;
                13022                         }
                13023                     }
                13024                 } else if ((particle->maxOccurs > 1)
                13025                            || (particle->minOccurs > 1)) {
                13026                     xmlAutomataStatePtr tmp;
                13027                     int counter;
                13028 
                13029                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
                13030                         oldstate, NULL);
                13031                     oldstate = pctxt->state;
                13032 
                13033                     counter = xmlAutomataNewCounter(pctxt->am,
                13034                         particle->minOccurs - 1,
                13035                         particle->maxOccurs - 1);
                13036 
                13037                     sub = particle->children->children;
                13038                     while (sub != NULL) {
                13039                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
                13040                                         (xmlSchemaParticlePtr) sub);
                13041                         if (tmp2 != 1) ret = 0;
                13042                         sub = sub->next;
                13043                     }
                13044                     tmp = pctxt->state;
                13045                     xmlAutomataNewCountedTrans(pctxt->am,
                13046                         tmp, oldstate, counter);
                13047                     pctxt->state =
                13048                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
                13049                                                    counter);
                13050                     if ((particle->minOccurs == 0) || (ret == 1)) {
                13051                         xmlAutomataNewEpsilon(pctxt->am,
                13052                                             oldstate, pctxt->state);
                13053                         ret = 1;
                13054                     }
                13055                 } else {
                13056                     sub = particle->children->children;
                13057                     while (sub != NULL) {
                13058                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
                13059                                         (xmlSchemaParticlePtr) sub);
                13060                         if (tmp2 != 1) ret = 0;
                13061                         sub = sub->next;
                13062                     }
                13063 
                13064             /*
                13065              * epsilon needed to block previous trans from
                13066              * being allowed to enter back from another
                13067              * construct
                13068              */
                13069             pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
                13070                     pctxt->state, NULL);
                13071 
                13072                     if (particle->minOccurs == 0) {
                13073                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
                13074                                               pctxt->state);
                13075                         ret = 1;
                13076                     }
                13077                 }
                13078             }
                13079             break;
                13080         }
                13081         case XML_SCHEMA_TYPE_CHOICE:{
                13082             xmlSchemaTreeItemPtr sub;
                13083             xmlAutomataStatePtr start, end;
                13084 
                13085             ret = 0;
                13086             start = pctxt->state;
                13087             end = xmlAutomataNewState(pctxt->am);
                13088 
                13089             /*
                13090              * iterate over the subtypes and remerge the end with an
                13091              * epsilon transition
                13092              */
                13093             if (particle->maxOccurs == 1) {
                13094                 sub = particle->children->children;
                13095                 while (sub != NULL) {
                13096                     pctxt->state = start;
                13097                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
                13098                                         (xmlSchemaParticlePtr) sub);
                13099                     if (tmp2 == 1) ret = 1;
                13100                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
                13101                     sub = sub->next;
                13102                 }
                13103             } else {
                13104                 int counter;
                13105                 xmlAutomataStatePtr hop, base;
                13106                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
                13107                     UNBOUNDED : particle->maxOccurs - 1;
                13108                 int minOccurs =
                13109                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
                13110 
                13111                 /*
                13112                  * use a counter to keep track of the number of transitions
                13113                  * which went through the choice.
                13114                  */
                13115                 counter =
                13116                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
                13117                 hop = xmlAutomataNewState(pctxt->am);
                13118                 base = xmlAutomataNewState(pctxt->am);
                13119 
                13120                 sub = particle->children->children;
                13121                 while (sub != NULL) {
                13122                     pctxt->state = base;
                13123                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
                13124                                         (xmlSchemaParticlePtr) sub);
                13125                     if (tmp2 == 1) ret = 1;
                13126                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
                13127                     sub = sub->next;
                13128                 }
                13129                 xmlAutomataNewEpsilon(pctxt->am, start, base);
                13130                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
                13131                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
                13132                 if (ret == 1)
                13133                     xmlAutomataNewEpsilon(pctxt->am, base, end);
                13134             }
                13135             if (particle->minOccurs == 0) {
                13136                 xmlAutomataNewEpsilon(pctxt->am, start, end);
                13137                 ret = 1;
                13138             }
                13139             pctxt->state = end;
                13140             break;
                13141         }
                13142         case XML_SCHEMA_TYPE_ALL:{
                13143             xmlAutomataStatePtr start, tmp;
                13144             xmlSchemaParticlePtr sub;
                13145             xmlSchemaElementPtr elemDecl;
                13146 
                13147             ret = 1;
                13148 
                13149             sub = (xmlSchemaParticlePtr) particle->children->children;
                13150             if (sub == NULL)
                13151                 break;
                13152 
                13153             ret = 0;
                13154 
                13155             start = pctxt->state;
                13156             tmp = xmlAutomataNewState(pctxt->am);
                13157             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
                13158             pctxt->state = tmp;
                13159             while (sub != NULL) {
                13160                 pctxt->state = tmp;
                13161 
                13162                 elemDecl = (xmlSchemaElementPtr) sub->children;
                13163                 if (elemDecl == NULL) {
                13164                     PERROR_INT("xmlSchemaBuildAContentModel",
                13165                         "<element> particle has no term");
                13166                     return(ret);
                13167                 };
                13168                 /*
                13169                 * NOTE: The {max occurs} of all the particles in the
                13170                 * {particles} of the group must be 0 or 1; this is
                13171                 * already ensured during the parse of the content of
                13172                 * <all>.
                13173                 */
                13174                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
                13175                     int counter;
                13176 
                13177                     /*
                13178                      * This is an abstract group, we need to share
                13179                      * the same counter for all the element transitions
                13180                      * derived from the group
                13181                      */
                13182                     counter = xmlAutomataNewCounter(pctxt->am,
                13183                                        sub->minOccurs, sub->maxOccurs);
                13184                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
                13185                                        sub, counter, pctxt->state);
                13186                 } else {
                13187                     if ((sub->minOccurs == 1) &&
                13188                         (sub->maxOccurs == 1)) {
                13189                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
                13190                                                 pctxt->state,
                13191                                                 elemDecl->name,
                13192                                                 elemDecl->targetNamespace,
                13193                                                 1, 1, elemDecl);
                13194                     } else if ((sub->minOccurs == 0) &&
                13195                         (sub->maxOccurs == 1)) {
                13196 
                13197                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
                13198                                                  pctxt->state,
                13199                                                  elemDecl->name,
                13200                                                  elemDecl->targetNamespace,
                13201                                                  0,
                13202                                                  1,
                13203                                                  elemDecl);
                13204                     }
                13205                 }
                13206                 sub = (xmlSchemaParticlePtr) sub->next;
                13207             }
                13208             pctxt->state =
                13209                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
                13210             if (particle->minOccurs == 0) {
                13211                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
                13212                 ret = 1;
                13213             }
                13214             break;
                13215         }
                13216     case XML_SCHEMA_TYPE_GROUP:
                13217         /*
                13218         * If we hit a model group definition, then this means that
                13219         * it was empty, thus was not substituted for the containing
                13220         * model group. Just do nothing in this case.
                13221         * TODO: But the group should be substituted and not occur at
                13222         * all in the content model at this point. Fix this.
                13223         */
                13224             ret = 1;
                13225         break;
                13226         default:
                13227         xmlSchemaInternalErr2(ACTXT_CAST pctxt,
                13228         "xmlSchemaBuildAContentModel",
                13229         "found unexpected term of type '%s' in content model",
                13230         WXS_ITEM_TYPE_NAME(particle->children), NULL);
                13231             return(ret);
                13232     }
                13233     return(ret);
                13234 }
                13235 
                13236 /**
                13237  * xmlSchemaBuildContentModel:
                13238  * @ctxt:  the schema parser context
                13239  * @type:  the complex type definition
                13240  * @name:  the element name
                13241  *
                13242  * Builds the content model of the complex type.
                13243  */
                13244 static void
                13245 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
                13246                xmlSchemaParserCtxtPtr ctxt)
                13247 {
                13248     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
                13249     (type->contModel != NULL) ||
                13250     ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
                13251     (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
                13252     return;
                13253 
                13254 #ifdef DEBUG_CONTENT
                13255     xmlGenericError(xmlGenericErrorContext,
                13256                     "Building content model for %s\n", name);
                13257 #endif
                13258     ctxt->am = NULL;
                13259     ctxt->am = xmlNewAutomata();
                13260     if (ctxt->am == NULL) {
                13261         xmlGenericError(xmlGenericErrorContext,
                13262         "Cannot create automata for complex type %s\n", type->name);
                13263         return;
                13264     }
                13265     ctxt->state = xmlAutomataGetInitState(ctxt->am);
                13266     /*
                13267     * Build the automaton.
                13268     */
                13269     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
                13270     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
                13271     type->contModel = xmlAutomataCompile(ctxt->am);
                13272     if (type->contModel == NULL) {
                13273         xmlSchemaPCustomErr(ctxt,
                13274         XML_SCHEMAP_INTERNAL,
                13275         WXS_BASIC_CAST type, type->node,
                13276         "Failed to compile the content model", NULL);
                13277     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
                13278         xmlSchemaPCustomErr(ctxt,
                13279         XML_SCHEMAP_NOT_DETERMINISTIC,
                13280         /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
                13281         WXS_BASIC_CAST type, type->node,
                13282         "The content model is not determinist", NULL);
                13283     } else {
                13284 #ifdef DEBUG_CONTENT_REGEXP
                13285         xmlGenericError(xmlGenericErrorContext,
                13286                         "Content model of %s:\n", type->name);
                13287         xmlRegexpPrint(stderr, type->contModel);
                13288 #endif
                13289     }
                13290     ctxt->state = NULL;
                13291     xmlFreeAutomata(ctxt->am);
                13292     ctxt->am = NULL;
                13293 }
                13294 
                13295 /**
                13296  * xmlSchemaResolveElementReferences:
                13297  * @elem:  the schema element context
                13298  * @ctxt:  the schema parser context
                13299  *
                13300  * Resolves the references of an element declaration
                13301  * or particle, which has an element declaration as it's
                13302  * term.
                13303  */
                13304 static void
                13305 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
                13306                   xmlSchemaParserCtxtPtr ctxt)
                13307 {
                13308     if ((ctxt == NULL) || (elemDecl == NULL) ||
                13309     ((elemDecl != NULL) &&
                13310     (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
                13311         return;
                13312     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
                13313 
                13314     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
                13315     xmlSchemaTypePtr type;
                13316 
                13317     /* (type definition) ... otherwise the type definition `resolved`
                13318     * to by the `actual value` of the type [attribute] ...
                13319     */
                13320     type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
                13321         elemDecl->namedTypeNs);
                13322     if (type == NULL) {
                13323         xmlSchemaPResCompAttrErr(ctxt,
                13324         XML_SCHEMAP_SRC_RESOLVE,
                13325         WXS_BASIC_CAST elemDecl, elemDecl->node,
                13326         "type", elemDecl->namedType, elemDecl->namedTypeNs,
                13327         XML_SCHEMA_TYPE_BASIC, "type definition");
                13328     } else
                13329         elemDecl->subtypes = type;
                13330     }
                13331     if (elemDecl->substGroup != NULL) {
                13332     xmlSchemaElementPtr substHead;
                13333 
                13334     /*
                13335     * FIXME TODO: Do we need a new field in _xmlSchemaElement for
                13336     * substitutionGroup?
                13337     */
                13338     substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
                13339         elemDecl->substGroupNs);
                13340     if (substHead == NULL) {
                13341         xmlSchemaPResCompAttrErr(ctxt,
                13342         XML_SCHEMAP_SRC_RESOLVE,
                13343         WXS_BASIC_CAST elemDecl, NULL,
                13344         "substitutionGroup", elemDecl->substGroup,
                13345         elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
                13346     } else {
                13347         xmlSchemaResolveElementReferences(substHead, ctxt);
                13348         /*
                13349         * Set the "substitution group affiliation".
                13350         * NOTE that now we use the "refDecl" field for this.
                13351         */
                13352         WXS_SUBST_HEAD(elemDecl) = substHead;
                13353         /*
                13354         * The type definitions is set to:
                13355         * SPEC "...the {type definition} of the element
                13356         * declaration `resolved` to by the `actual value`
                13357         * of the substitutionGroup [attribute], if present"
                13358         */
ad7b9726c Alex*13359         if (elemDecl->subtypes == NULL) {
                13360                 if (substHead->subtypes == NULL) {
                13361                     /*
                13362                      * This can happen with self-referencing substitution
                13363                      * groups. The cycle will be detected later, but we have
                13364                      * to set subtypes to avoid null-pointer dereferences.
                13365                      */
                13366                 elemDecl->subtypes = xmlSchemaGetBuiltInType(
                13367                             XML_SCHEMAS_ANYTYPE);
                13368                 } else {
                13369             elemDecl->subtypes = substHead->subtypes;
                13370                 }
                13371             }
9d9d4fcc3 Alex*13372     }
                13373     }
                13374     /*
                13375     * SPEC "The definition of anyType serves as the default type definition
                13376     * for element declarations whose XML representation does not specify one."
                13377     */
                13378     if ((elemDecl->subtypes == NULL) &&
                13379     (elemDecl->namedType == NULL) &&
                13380     (elemDecl->substGroup == NULL))
                13381     elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
                13382 }
                13383 
                13384 /**
                13385  * xmlSchemaResolveUnionMemberTypes:
                13386  * @ctxt:  the schema parser context
                13387  * @type:  the schema simple type definition
                13388  *
                13389  * Checks and builds the "member type definitions" property of the union
                13390  * simple type. This handles part (1), part (2) is done in
                13391  * xmlSchemaFinishMemberTypeDefinitionsProperty()
                13392  *
                13393  * Returns -1 in case of an internal error, 0 otherwise.
                13394  */
                13395 static int
                13396 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
                13397                  xmlSchemaTypePtr type)
                13398 {
                13399 
                13400     xmlSchemaTypeLinkPtr link, lastLink, newLink;
                13401     xmlSchemaTypePtr memberType;
                13402 
                13403     /*
                13404     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
                13405     * define the explicit members as the type definitions `resolved`
                13406     * to by the items in the `actual value` of the memberTypes [attribute],
                13407     * if any, followed by the type definitions corresponding to the
                13408     * <simpleType>s among the [children] of <union>, if any."
                13409     */
                13410     /*
                13411     * Resolve references.
                13412     */
                13413     link = type->memberTypes;
                13414     lastLink = NULL;
                13415     while (link != NULL) {
                13416     const xmlChar *name, *nsName;
                13417 
                13418     name = ((xmlSchemaQNameRefPtr) link->type)->name;
                13419     nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
                13420 
                13421     memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
                13422     if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
                13423         xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
                13424         WXS_BASIC_CAST type, type->node, "memberTypes",
                13425         name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
                13426         /*
                13427         * Remove the member type link.
                13428         */
                13429         if (lastLink == NULL)
                13430         type->memberTypes = link->next;
                13431         else
                13432         lastLink->next = link->next;
                13433         newLink = link;
                13434         link = link->next;
                13435         xmlFree(newLink);
                13436     } else {
                13437         link->type = memberType;
                13438         lastLink = link;
                13439         link = link->next;
                13440     }
                13441     }
                13442     /*
                13443     * Add local simple types,
                13444     */
                13445     memberType = type->subtypes;
                13446     while (memberType != NULL) {
                13447     link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
                13448     if (link == NULL) {
                13449         xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
                13450         return (-1);
                13451     }
                13452     link->type = memberType;
                13453     link->next = NULL;
                13454     if (lastLink == NULL)
                13455         type->memberTypes = link;
                13456     else
                13457         lastLink->next = link;
                13458     lastLink = link;
                13459     memberType = memberType->next;
                13460     }
                13461     return (0);
                13462 }
                13463 
                13464 /**
                13465  * xmlSchemaIsDerivedFromBuiltInType:
                13466  * @ctxt:  the schema parser context
                13467  * @type:  the type definition
                13468  * @valType: the value type
                13469  *
                13470  *
                13471  * Returns 1 if the type has the given value type, or
                13472  * is derived from such a type.
                13473  */
                13474 static int
                13475 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
                13476 {
                13477     if (type == NULL)
                13478     return (0);
                13479     if (WXS_IS_COMPLEX(type))
                13480     return (0);
                13481     if (type->type == XML_SCHEMA_TYPE_BASIC) {
                13482     if (type->builtInType == valType)
                13483         return(1);
                13484     if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
                13485         (type->builtInType == XML_SCHEMAS_ANYTYPE))
                13486         return (0);
                13487     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
                13488     }
                13489     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
                13490 }
                13491 
                13492 #if 0
                13493 /**
                13494  * xmlSchemaIsDerivedFromBuiltInType:
                13495  * @ctxt:  the schema parser context
                13496  * @type:  the type definition
                13497  * @valType: the value type
                13498  *
                13499  *
                13500  * Returns 1 if the type has the given value type, or
                13501  * is derived from such a type.
                13502  */
                13503 static int
                13504 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
                13505 {
                13506     if (type == NULL)
                13507     return (0);
                13508     if (WXS_IS_COMPLEX(type))
                13509     return (0);
                13510     if (type->type == XML_SCHEMA_TYPE_BASIC) {
                13511     if (type->builtInType == valType)
                13512         return(1);
                13513     return (0);
                13514     } else
                13515     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
                13516 
                13517     return (0);
                13518 }
                13519 
                13520 static xmlSchemaTypePtr
                13521 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
                13522 {
                13523     if (type == NULL)
                13524     return (NULL);
                13525     if (WXS_IS_COMPLEX(type))
                13526     return (NULL);
                13527     if (type->type == XML_SCHEMA_TYPE_BASIC)
                13528     return(type);
                13529     return(xmlSchemaQueryBuiltInType(type->subtypes));
                13530 }
                13531 #endif
                13532 
                13533 /**
                13534  * xmlSchemaGetPrimitiveType:
                13535  * @type:  the simpleType definition
                13536  *
                13537  * Returns the primitive type of the given type or
                13538  * NULL in case of error.
                13539  */
                13540 static xmlSchemaTypePtr
                13541 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
                13542 {
                13543 
                13544     while (type != NULL) {
                13545     /*
                13546     * Note that anySimpleType is actually not a primitive type
                13547     * but we need that here.
                13548     */
                13549     if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
                13550        (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
                13551         return (type);
                13552     type = type->baseType;
                13553     }
                13554 
                13555     return (NULL);
                13556 }
                13557 
                13558 #if 0
                13559 /**
                13560  * xmlSchemaGetBuiltInTypeAncestor:
                13561  * @type:  the simpleType definition
                13562  *
                13563  * Returns the primitive type of the given type or
                13564  * NULL in case of error.
                13565  */
                13566 static xmlSchemaTypePtr
                13567 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
                13568 {
                13569     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
                13570     return (0);
                13571     while (type != NULL) {
                13572     if (type->type == XML_SCHEMA_TYPE_BASIC)
                13573         return (type);
                13574     type = type->baseType;
                13575     }
                13576 
                13577     return (NULL);
                13578 }
                13579 #endif
                13580 
                13581 /**
                13582  * xmlSchemaCloneWildcardNsConstraints:
                13583  * @ctxt:  the schema parser context
                13584  * @dest:  the destination wildcard
                13585  * @source: the source wildcard
                13586  *
                13587  * Clones the namespace constraints of source
                13588  * and assigns them to dest.
                13589  * Returns -1 on internal error, 0 otherwise.
                13590  */
                13591 static int
                13592 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
                13593                     xmlSchemaWildcardPtr dest,
                13594                     xmlSchemaWildcardPtr source)
                13595 {
                13596     xmlSchemaWildcardNsPtr cur, tmp, last;
                13597 
                13598     if ((source == NULL) || (dest == NULL))
                13599     return(-1);
                13600     dest->any = source->any;
                13601     cur = source->nsSet;
                13602     last = NULL;
                13603     while (cur != NULL) {
                13604     tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
                13605     if (tmp == NULL)
                13606         return(-1);
                13607     tmp->value = cur->value;
                13608     if (last == NULL)
                13609         dest->nsSet = tmp;
                13610     else
                13611         last->next = tmp;
                13612     last = tmp;
                13613     cur = cur->next;
                13614     }
                13615     if (dest->negNsSet != NULL)
                13616     xmlSchemaFreeWildcardNsSet(dest->negNsSet);
                13617     if (source->negNsSet != NULL) {
                13618     dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
                13619     if (dest->negNsSet == NULL)
                13620         return(-1);
                13621     dest->negNsSet->value = source->negNsSet->value;
                13622     } else
                13623     dest->negNsSet = NULL;
                13624     return(0);
                13625 }
                13626 
                13627 /**
                13628  * xmlSchemaUnionWildcards:
                13629  * @ctxt:  the schema parser context
                13630  * @completeWild:  the first wildcard
                13631  * @curWild: the second wildcard
                13632  *
                13633  * Unions the namespace constraints of the given wildcards.
                13634  * @completeWild will hold the resulting union.
                13635  * Returns a positive error code on failure, -1 in case of an
                13636  * internal error, 0 otherwise.
                13637  */
                13638 static int
                13639 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
                13640                 xmlSchemaWildcardPtr completeWild,
                13641                 xmlSchemaWildcardPtr curWild)
                13642 {
                13643     xmlSchemaWildcardNsPtr cur, curB, tmp;
                13644 
                13645     /*
                13646     * 1 If O1 and O2 are the same value, then that value must be the
                13647     * value.
                13648     */
                13649     if ((completeWild->any == curWild->any) &&
                13650     ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
                13651     ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
                13652 
                13653     if ((completeWild->negNsSet == NULL) ||
                13654         (completeWild->negNsSet->value == curWild->negNsSet->value)) {
                13655 
                13656         if (completeWild->nsSet != NULL) {
                13657         int found = 0;
                13658 
                13659         /*
                13660         * Check equality of sets.
                13661         */
                13662         cur = completeWild->nsSet;
                13663         while (cur != NULL) {
                13664             found = 0;
                13665             curB = curWild->nsSet;
                13666             while (curB != NULL) {
                13667             if (cur->value == curB->value) {
                13668                 found = 1;
                13669                 break;
                13670             }
                13671             curB = curB->next;
                13672             }
                13673             if (!found)
                13674             break;
                13675             cur = cur->next;
                13676         }
                13677         if (found)
                13678             return(0);
                13679         } else
                13680         return(0);
                13681     }
                13682     }
                13683     /*
                13684     * 2 If either O1 or O2 is any, then any must be the value
                13685     */
                13686     if (completeWild->any != curWild->any) {
                13687     if (completeWild->any == 0) {
                13688         completeWild->any = 1;
                13689         if (completeWild->nsSet != NULL) {
                13690         xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
                13691         completeWild->nsSet = NULL;
                13692         }
                13693         if (completeWild->negNsSet != NULL) {
                13694         xmlFree(completeWild->negNsSet);
                13695         completeWild->negNsSet = NULL;
                13696         }
                13697     }
                13698     return (0);
                13699     }
                13700     /*
                13701     * 3 If both O1 and O2 are sets of (namespace names or `absent`),
                13702     * then the union of those sets must be the value.
                13703     */
                13704     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
                13705     int found;
                13706     xmlSchemaWildcardNsPtr start;
                13707 
                13708     cur = curWild->nsSet;
                13709     start = completeWild->nsSet;
                13710     while (cur != NULL) {
                13711         found = 0;
                13712         curB = start;
                13713         while (curB != NULL) {
                13714         if (cur->value == curB->value) {
                13715             found = 1;
                13716             break;
                13717         }
                13718         curB = curB->next;
                13719         }
                13720         if (!found) {
                13721         tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
                13722         if (tmp == NULL)
                13723             return (-1);
                13724         tmp->value = cur->value;
                13725         tmp->next = completeWild->nsSet;
                13726         completeWild->nsSet = tmp;
                13727         }
                13728         cur = cur->next;
                13729     }
                13730 
                13731     return(0);
                13732     }
                13733     /*
                13734     * 4 If the two are negations of different values (namespace names
                13735     * or `absent`), then a pair of not and `absent` must be the value.
                13736     */
                13737     if ((completeWild->negNsSet != NULL) &&
                13738     (curWild->negNsSet != NULL) &&
                13739     (completeWild->negNsSet->value != curWild->negNsSet->value)) {
                13740     completeWild->negNsSet->value = NULL;
                13741 
                13742     return(0);
                13743     }
                13744     /*
                13745      * 5.
                13746      */
                13747     if (((completeWild->negNsSet != NULL) &&
                13748     (completeWild->negNsSet->value != NULL) &&
                13749     (curWild->nsSet != NULL)) ||
                13750     ((curWild->negNsSet != NULL) &&
                13751     (curWild->negNsSet->value != NULL) &&
                13752     (completeWild->nsSet != NULL))) {
                13753 
                13754     int nsFound, absentFound = 0;
                13755 
                13756     if (completeWild->nsSet != NULL) {
                13757         cur = completeWild->nsSet;
                13758         curB = curWild->negNsSet;
                13759     } else {
                13760         cur = curWild->nsSet;
                13761         curB = completeWild->negNsSet;
                13762     }
                13763     nsFound = 0;
                13764     while (cur != NULL) {
                13765         if (cur->value == NULL)
                13766         absentFound = 1;
                13767         else if (cur->value == curB->value)
                13768         nsFound = 1;
                13769         if (nsFound && absentFound)
                13770         break;
                13771         cur = cur->next;
                13772     }
                13773 
                13774     if (nsFound && absentFound) {
                13775         /*
                13776         * 5.1 If the set S includes both the negated namespace
                13777         * name and `absent`, then any must be the value.
                13778         */
                13779         completeWild->any = 1;
                13780         if (completeWild->nsSet != NULL) {
                13781         xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
                13782         completeWild->nsSet = NULL;
                13783         }
                13784         if (completeWild->negNsSet != NULL) {
                13785         xmlFree(completeWild->negNsSet);
                13786         completeWild->negNsSet = NULL;
                13787         }
                13788     } else if (nsFound && (!absentFound)) {
                13789         /*
                13790         * 5.2 If the set S includes the negated namespace name
                13791         * but not `absent`, then a pair of not and `absent` must
                13792         * be the value.
                13793         */
                13794         if (completeWild->nsSet != NULL) {
                13795         xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
                13796         completeWild->nsSet = NULL;
                13797         }
                13798         if (completeWild->negNsSet == NULL) {
                13799         completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
                13800         if (completeWild->negNsSet == NULL)
                13801             return (-1);
                13802         }
                13803         completeWild->negNsSet->value = NULL;
                13804     } else if ((!nsFound) && absentFound) {
                13805         /*
                13806         * 5.3 If the set S includes `absent` but not the negated
                13807         * namespace name, then the union is not expressible.
                13808         */
                13809         xmlSchemaPErr(ctxt, completeWild->node,
                13810         XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
                13811         "The union of the wildcard is not expressible.\n",
                13812         NULL, NULL);
                13813         return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
                13814     } else if ((!nsFound) && (!absentFound)) {
                13815         /*
                13816         * 5.4 If the set S does not include either the negated namespace
                13817         * name or `absent`, then whichever of O1 or O2 is a pair of not
                13818         * and a namespace name must be the value.
                13819         */
                13820         if (completeWild->negNsSet == NULL) {
                13821         if (completeWild->nsSet != NULL) {
                13822             xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
                13823             completeWild->nsSet = NULL;
                13824         }
                13825         completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
                13826         if (completeWild->negNsSet == NULL)
                13827             return (-1);
                13828         completeWild->negNsSet->value = curWild->negNsSet->value;
                13829         }
                13830     }
                13831     return (0);
                13832     }
                13833     /*
                13834      * 6.
                13835      */
                13836     if (((completeWild->negNsSet != NULL) &&
                13837     (completeWild->negNsSet->value == NULL) &&
                13838     (curWild->nsSet != NULL)) ||
                13839     ((curWild->negNsSet != NULL) &&
                13840     (curWild->negNsSet->value == NULL) &&
                13841     (completeWild->nsSet != NULL))) {
                13842 
                13843     if (completeWild->nsSet != NULL) {
                13844         cur = completeWild->nsSet;
                13845     } else {
                13846         cur = curWild->nsSet;
                13847     }
                13848     while (cur != NULL) {
                13849         if (cur->value == NULL) {
                13850         /*
                13851         * 6.1 If the set S includes `absent`, then any must be the
                13852         * value.
                13853         */
                13854         completeWild->any = 1;
                13855         if (completeWild->nsSet != NULL) {
                13856             xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
                13857             completeWild->nsSet = NULL;
                13858         }
                13859         if (completeWild->negNsSet != NULL) {
                13860             xmlFree(completeWild->negNsSet);
                13861             completeWild->negNsSet = NULL;
                13862         }
                13863         return (0);
                13864         }
                13865         cur = cur->next;
                13866     }
                13867     if (completeWild->negNsSet == NULL) {
                13868         /*
                13869         * 6.2 If the set S does not include `absent`, then a pair of not
                13870         * and `absent` must be the value.
                13871         */
                13872         if (completeWild->nsSet != NULL) {
                13873         xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
                13874         completeWild->nsSet = NULL;
                13875         }
                13876         completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
                13877         if (completeWild->negNsSet == NULL)
                13878         return (-1);
                13879         completeWild->negNsSet->value = NULL;
                13880     }
                13881     return (0);
                13882     }
                13883     return (0);
                13884 
                13885 }
                13886 
                13887 /**
                13888  * xmlSchemaIntersectWildcards:
                13889  * @ctxt:  the schema parser context
                13890  * @completeWild:  the first wildcard
                13891  * @curWild: the second wildcard
                13892  *
                13893  * Intersects the namespace constraints of the given wildcards.
                13894  * @completeWild will hold the resulting intersection.
                13895  * Returns a positive error code on failure, -1 in case of an
                13896  * internal error, 0 otherwise.
                13897  */
                13898 static int
                13899 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
                13900                 xmlSchemaWildcardPtr completeWild,
                13901                 xmlSchemaWildcardPtr curWild)
                13902 {
                13903     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
                13904 
                13905     /*
                13906     * 1 If O1 and O2 are the same value, then that value must be the
                13907     * value.
                13908     */
                13909     if ((completeWild->any == curWild->any) &&
                13910     ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
                13911     ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
                13912 
                13913     if ((completeWild->negNsSet == NULL) ||
                13914         (completeWild->negNsSet->value == curWild->negNsSet->value)) {
                13915 
                13916         if (completeWild->nsSet != NULL) {
                13917         int found = 0;
                13918 
                13919         /*
                13920         * Check equality of sets.
                13921         */
                13922         cur = completeWild->nsSet;
                13923         while (cur != NULL) {
                13924             found = 0;
                13925             curB = curWild->nsSet;
                13926             while (curB != NULL) {
                13927             if (cur->value == curB->value) {
                13928                 found = 1;
                13929                 break;
                13930             }
                13931             curB = curB->next;
                13932             }
                13933             if (!found)
                13934             break;
                13935             cur = cur->next;
                13936         }
                13937         if (found)
                13938             return(0);
                13939         } else
                13940         return(0);
                13941     }
                13942     }
                13943     /*
                13944     * 2 If either O1 or O2 is any, then the other must be the value.
                13945     */
                13946     if ((completeWild->any != curWild->any) && (completeWild->any)) {
                13947     if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
                13948         return(-1);
                13949     return(0);
                13950     }
                13951     /*
                13952     * 3 If either O1 or O2 is a pair of not and a value (a namespace
                13953     * name or `absent`) and the other is a set of (namespace names or
                13954     * `absent`), then that set, minus the negated value if it was in
                13955     * the set, minus `absent` if it was in the set, must be the value.
                13956     */
                13957     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
                13958     ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
                13959     const xmlChar *neg;
                13960 
                13961     if (completeWild->nsSet == NULL) {
                13962         neg = completeWild->negNsSet->value;
                13963         if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
                13964         return(-1);
                13965     } else
                13966         neg = curWild->negNsSet->value;
                13967     /*
                13968     * Remove absent and negated.
                13969     */
                13970     prev = NULL;
                13971     cur = completeWild->nsSet;
                13972     while (cur != NULL) {
                13973         if (cur->value == NULL) {
                13974         if (prev == NULL)
                13975             completeWild->nsSet = cur->next;
                13976         else
                13977             prev->next = cur->next;
                13978         xmlFree(cur);
                13979         break;
                13980         }
                13981         prev = cur;
                13982         cur = cur->next;
                13983     }
                13984     if (neg != NULL) {
                13985         prev = NULL;
                13986         cur = completeWild->nsSet;
                13987         while (cur != NULL) {
                13988         if (cur->value == neg) {
                13989             if (prev == NULL)
                13990             completeWild->nsSet = cur->next;
                13991             else
                13992             prev->next = cur->next;
                13993             xmlFree(cur);
                13994             break;
                13995         }
                13996         prev = cur;
                13997         cur = cur->next;
                13998         }
                13999     }
                14000 
                14001     return(0);
                14002     }
                14003     /*
                14004     * 4 If both O1 and O2 are sets of (namespace names or `absent`),
                14005     * then the intersection of those sets must be the value.
                14006     */
                14007     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
                14008     int found;
                14009 
                14010     cur = completeWild->nsSet;
                14011     prev = NULL;
                14012     while (cur != NULL) {
                14013         found = 0;
                14014         curB = curWild->nsSet;
                14015         while (curB != NULL) {
                14016         if (cur->value == curB->value) {
                14017             found = 1;
                14018             break;
                14019         }
                14020         curB = curB->next;
                14021         }
                14022         if (!found) {
                14023         if (prev == NULL)
                14024             completeWild->nsSet = cur->next;
                14025         else
                14026             prev->next = cur->next;
                14027         tmp = cur->next;
                14028         xmlFree(cur);
                14029         cur = tmp;
                14030         continue;
                14031         }
                14032         prev = cur;
                14033         cur = cur->next;
                14034     }
                14035 
                14036     return(0);
                14037     }
                14038     /* 5 If the two are negations of different namespace names,
                14039     * then the intersection is not expressible
                14040     */
                14041     if ((completeWild->negNsSet != NULL) &&
                14042     (curWild->negNsSet != NULL) &&
                14043     (completeWild->negNsSet->value != curWild->negNsSet->value) &&
                14044     (completeWild->negNsSet->value != NULL) &&
                14045     (curWild->negNsSet->value != NULL)) {
                14046 
                14047     xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
                14048         "The intersection of the wildcard is not expressible.\n",
                14049         NULL, NULL);
                14050     return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
                14051     }
                14052     /*
                14053     * 6 If the one is a negation of a namespace name and the other
                14054     * is a negation of `absent`, then the one which is the negation
                14055     * of a namespace name must be the value.
                14056     */
                14057     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
                14058     (completeWild->negNsSet->value != curWild->negNsSet->value) &&
                14059     (completeWild->negNsSet->value == NULL)) {
                14060     completeWild->negNsSet->value =  curWild->negNsSet->value;
                14061     }
                14062     return(0);
                14063 }
                14064 
                14065 /**
                14066  * xmlSchemaIsWildcardNsConstraintSubset:
                14067  * @ctxt:  the schema parser context
                14068  * @sub:  the first wildcard
                14069  * @super: the second wildcard
                14070  *
                14071  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
                14072  *
                14073  * Returns 0 if the namespace constraint of @sub is an intensional
                14074  * subset of @super, 1 otherwise.
                14075  */
                14076 static int
                14077 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
                14078               xmlSchemaWildcardPtr super)
                14079 {
                14080     /*
                14081     * 1 super must be any.
                14082     */
                14083     if (super->any)
                14084     return (0);
                14085     /*
                14086     * 2.1 sub must be a pair of not and a namespace name or `absent`.
                14087     * 2.2 super must be a pair of not and the same value.
                14088     */
                14089     if ((sub->negNsSet != NULL) &&
                14090     (super->negNsSet != NULL) &&
                14091     (sub->negNsSet->value == super->negNsSet->value))
                14092     return (0);
                14093     /*
                14094     * 3.1 sub must be a set whose members are either namespace names or `absent`.
                14095     */
                14096     if (sub->nsSet != NULL) {
                14097     /*
                14098     * 3.2.1 super must be the same set or a superset thereof.
                14099     */
                14100     if (super->nsSet != NULL) {
                14101         xmlSchemaWildcardNsPtr cur, curB;
                14102         int found = 0;
                14103 
                14104         cur = sub->nsSet;
                14105         while (cur != NULL) {
                14106         found = 0;
                14107         curB = super->nsSet;
                14108         while (curB != NULL) {
                14109             if (cur->value == curB->value) {
                14110             found = 1;
                14111             break;
                14112             }
                14113             curB = curB->next;
                14114         }
                14115         if (!found)
                14116             return (1);
                14117         cur = cur->next;
                14118         }
                14119         if (found)
                14120         return (0);
                14121     } else if (super->negNsSet != NULL) {
                14122         xmlSchemaWildcardNsPtr cur;
                14123         /*
                14124         * 3.2.2 super must be a pair of not and a namespace name or
                14125         * `absent` and that value must not be in sub's set.
                14126         */
                14127         cur = sub->nsSet;
                14128         while (cur != NULL) {
                14129         if (cur->value == super->negNsSet->value)
                14130             return (1);
                14131         cur = cur->next;
                14132         }
                14133         return (0);
                14134     }
                14135     }
                14136     return (1);
                14137 }
                14138 
                14139 static int
                14140 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
                14141                      int *fixed,
                14142                      const xmlChar **value,
                14143                      xmlSchemaValPtr *val)
                14144 {
                14145     *fixed = 0;
                14146     *value = NULL;
                14147     if (val != 0)
                14148     *val = NULL;
                14149 
                14150     if (attruse->defValue != NULL) {
                14151     *value = attruse->defValue;
                14152     if (val != NULL)
                14153         *val = attruse->defVal;
                14154     if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
                14155         *fixed = 1;
                14156     return(1);
                14157     } else if ((attruse->attrDecl != NULL) &&
                14158     (attruse->attrDecl->defValue != NULL)) {
                14159     *value = attruse->attrDecl->defValue;
                14160     if (val != NULL)
                14161         *val = attruse->attrDecl->defVal;
                14162     if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
                14163         *fixed = 1;
                14164     return(1);
                14165     }
                14166     return(0);
                14167 }
                14168 /**
                14169  * xmlSchemaCheckCVCWildcardNamespace:
                14170  * @wild:  the wildcard
                14171  * @ns:  the namespace
                14172  *
                14173  * Validation Rule: Wildcard allows Namespace Name
                14174  * (cvc-wildcard-namespace)
                14175  *
                14176  * Returns 0 if the given namespace matches the wildcard,
                14177  * 1 otherwise and -1 on API errors.
                14178  */
                14179 static int
                14180 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
                14181                    const xmlChar* ns)
                14182 {
                14183     if (wild == NULL)
                14184     return(-1);
                14185 
                14186     if (wild->any)
                14187     return(0);
                14188     else if (wild->nsSet != NULL) {
                14189     xmlSchemaWildcardNsPtr cur;
                14190 
                14191     cur = wild->nsSet;
                14192     while (cur != NULL) {
                14193         if (xmlStrEqual(cur->value, ns))
                14194         return(0);
                14195         cur = cur->next;
                14196     }
                14197     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
                14198     (!xmlStrEqual(wild->negNsSet->value, ns)))
                14199     return(0);
                14200 
                14201     return(1);
                14202 }
                14203 
                14204 #define XML_SCHEMA_ACTION_DERIVE 0
                14205 #define XML_SCHEMA_ACTION_REDEFINE 1
                14206 
                14207 #define WXS_ACTION_STR(a) \
                14208 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
                14209 
                14210 /*
                14211 * Schema Component Constraint:
                14212 *   Derivation Valid (Restriction, Complex)
                14213 *   derivation-ok-restriction (2) - (4)
                14214 *
                14215 * ATTENTION:
                14216 * In XML Schema 1.1 this will be:
                14217 * Validation Rule:
                14218 *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
                14219 *
                14220 */
                14221 static int
                14222 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
                14223                        int action,
                14224                        xmlSchemaBasicItemPtr item,
                14225                        xmlSchemaBasicItemPtr baseItem,
                14226                        xmlSchemaItemListPtr uses,
                14227                        xmlSchemaItemListPtr baseUses,
                14228                        xmlSchemaWildcardPtr wild,
                14229                        xmlSchemaWildcardPtr baseWild)
                14230 {
                14231     xmlSchemaAttributeUsePtr cur = NULL, bcur;
                14232     int i, j, found; /* err = 0; */
                14233     const xmlChar *bEffValue;
                14234     int effFixed;
                14235 
                14236     if (uses != NULL) {
                14237     for (i = 0; i < uses->nbItems; i++) {
                14238         cur = uses->items[i];
                14239         found = 0;
                14240         if (baseUses == NULL)
                14241         goto not_found;
                14242         for (j = 0; j < baseUses->nbItems; j++) {
                14243         bcur = baseUses->items[j];
                14244         if ((WXS_ATTRUSE_DECL_NAME(cur) ==
                14245             WXS_ATTRUSE_DECL_NAME(bcur)) &&
                14246             (WXS_ATTRUSE_DECL_TNS(cur) ==
                14247             WXS_ATTRUSE_DECL_TNS(bcur)))
                14248         {
                14249             /*
                14250             * (2.1) "If there is an attribute use in the {attribute
                14251             * uses} of the {base type definition} (call this B) whose
                14252             * {attribute declaration} has the same {name} and {target
                14253             * namespace}, then  all of the following must be true:"
                14254             */
                14255             found = 1;
                14256 
                14257             if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
                14258             (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
                14259             {
                14260             xmlChar *str = NULL;
                14261             /*
                14262             * (2.1.1) "one of the following must be true:"
                14263             * (2.1.1.1) "B's {required} is false."
                14264             * (2.1.1.2) "R's {required} is true."
                14265             */
                14266             xmlSchemaPAttrUseErr4(pctxt,
                14267                 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
                14268                 WXS_ITEM_NODE(item), item, cur,
                14269                 "The 'optional' attribute use is inconsistent "
                14270                 "with the corresponding 'required' attribute use of "
                14271                 "the %s %s",
                14272                 WXS_ACTION_STR(action),
                14273                 xmlSchemaGetComponentDesignation(&str, baseItem),
                14274                 NULL, NULL);
                14275             FREE_AND_NULL(str);
                14276             /* err = pctxt->err; */
                14277             } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
                14278             WXS_ATTRUSE_TYPEDEF(cur),
                14279             WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
                14280             {
                14281             xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
                14282 
                14283             /*
                14284             * SPEC (2.1.2) "R's {attribute declaration}'s
                14285             * {type definition} must be validly derived from
                14286             * B's {type definition} given the empty set as
                14287             * defined in Type Derivation OK (Simple) ($3.14.6)."
                14288             */
                14289             xmlSchemaPAttrUseErr4(pctxt,
                14290                 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
                14291                 WXS_ITEM_NODE(item), item, cur,
                14292                 "The attribute declaration's %s "
                14293                 "is not validly derived from "
                14294                 "the corresponding %s of the "
                14295                 "attribute declaration in the %s %s",
                14296                 xmlSchemaGetComponentDesignation(&strA,
                14297                 WXS_ATTRUSE_TYPEDEF(cur)),
                14298                 xmlSchemaGetComponentDesignation(&strB,
                14299                 WXS_ATTRUSE_TYPEDEF(bcur)),
                14300                 WXS_ACTION_STR(action),
                14301                 xmlSchemaGetComponentDesignation(&strC, baseItem));
                14302                 /* xmlSchemaGetComponentDesignation(&str, baseItem), */
                14303             FREE_AND_NULL(strA);
                14304             FREE_AND_NULL(strB);
                14305             FREE_AND_NULL(strC);
                14306             /* err = pctxt->err; */
                14307             } else {
                14308             /*
                14309             * 2.1.3 [Definition:]  Let the effective value
                14310             * constraint of an attribute use be its {value
                14311             * constraint}, if present, otherwise its {attribute
                14312             * declaration}'s {value constraint} .
                14313             */
                14314             xmlSchemaGetEffectiveValueConstraint(bcur,
                14315                 &effFixed, &bEffValue, NULL);
                14316             /*
                14317             * 2.1.3 ... one of the following must be true
                14318             *
                14319             * 2.1.3.1 B's `effective value constraint` is
                14320             * `absent` or default.
                14321             */
                14322             if ((bEffValue != NULL) &&
                14323                 (effFixed == 1)) {
                14324                 const xmlChar *rEffValue = NULL;
                14325 
                14326                 xmlSchemaGetEffectiveValueConstraint(bcur,
                14327                 &effFixed, &rEffValue, NULL);
                14328                 /*
                14329                 * 2.1.3.2 R's `effective value constraint` is
                14330                 * fixed with the same string as B's.
                14331                 * MAYBE TODO: Compare the computed values.
                14332                 *       Hmm, it says "same string" so
                14333                 *       string-equality might really be sufficient.
                14334                 */
                14335                 if ((effFixed == 0) ||
                14336                 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
                14337                 {
                14338                 xmlChar *str = NULL;
                14339 
                14340                 xmlSchemaPAttrUseErr4(pctxt,
                14341                     XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
                14342                     WXS_ITEM_NODE(item), item, cur,
                14343                     "The effective value constraint of the "
                14344                     "attribute use is inconsistent with "
                14345                     "its correspondent in the %s %s",
                14346                     WXS_ACTION_STR(action),
                14347                     xmlSchemaGetComponentDesignation(&str,
                14348                     baseItem),
                14349                     NULL, NULL);
                14350                 FREE_AND_NULL(str);
                14351                 /* err = pctxt->err; */
                14352                 }
                14353             }
                14354             }
                14355             break;
                14356         }
                14357         }
                14358 not_found:
                14359         if (!found) {
                14360         /*
                14361         * (2.2) "otherwise the {base type definition} must have an
                14362         * {attribute wildcard} and the {target namespace} of the
                14363         * R's {attribute declaration} must be `valid` with respect
                14364         * to that wildcard, as defined in Wildcard allows Namespace
                14365         * Name ($3.10.4)."
                14366         */
                14367         if ((baseWild == NULL) ||
                14368             (xmlSchemaCheckCVCWildcardNamespace(baseWild,
                14369             (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
                14370         {
                14371             xmlChar *str = NULL;
                14372 
                14373             xmlSchemaPAttrUseErr4(pctxt,
                14374             XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
                14375             WXS_ITEM_NODE(item), item, cur,
                14376             "Neither a matching attribute use, "
                14377             "nor a matching wildcard exists in the %s %s",
                14378             WXS_ACTION_STR(action),
                14379             xmlSchemaGetComponentDesignation(&str, baseItem),
                14380             NULL, NULL);
                14381             FREE_AND_NULL(str);
                14382             /* err = pctxt->err; */
                14383         }
                14384         }
                14385     }
                14386     }
                14387     /*
                14388     * SPEC derivation-ok-restriction (3):
                14389     * (3) "For each attribute use in the {attribute uses} of the {base type
                14390     * definition} whose {required} is true, there must be an attribute
                14391     * use with an {attribute declaration} with the same {name} and
                14392     * {target namespace} as its {attribute declaration} in the {attribute
                14393     * uses} of the complex type definition itself whose {required} is true.
                14394     */
                14395     if (baseUses != NULL) {
                14396     for (j = 0; j < baseUses->nbItems; j++) {
                14397         bcur = baseUses->items[j];
                14398         if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
                14399         continue;
                14400         found = 0;
                14401         if (uses != NULL) {
                14402         for (i = 0; i < uses->nbItems; i++) {
                14403             cur = uses->items[i];
                14404             if ((WXS_ATTRUSE_DECL_NAME(cur) ==
                14405             WXS_ATTRUSE_DECL_NAME(bcur)) &&
                14406             (WXS_ATTRUSE_DECL_TNS(cur) ==
                14407             WXS_ATTRUSE_DECL_TNS(bcur))) {
                14408             found = 1;
                14409             break;
                14410             }
                14411         }
                14412         }
                14413         if (!found) {
                14414         xmlChar *strA = NULL, *strB = NULL;
                14415 
                14416         xmlSchemaCustomErr4(ACTXT_CAST pctxt,
                14417             XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
                14418             NULL, item,
                14419             "A matching attribute use for the "
                14420             "'required' %s of the %s %s is missing",
                14421             xmlSchemaGetComponentDesignation(&strA, bcur),
                14422             WXS_ACTION_STR(action),
                14423             xmlSchemaGetComponentDesignation(&strB, baseItem),
                14424             NULL);
                14425         FREE_AND_NULL(strA);
                14426         FREE_AND_NULL(strB);
                14427         }
                14428     }
                14429     }
                14430     /*
                14431     * derivation-ok-restriction (4)
                14432     */
                14433     if (wild != NULL) {
                14434     /*
                14435     * (4) "If there is an {attribute wildcard}, all of the
                14436     * following must be true:"
                14437     */
                14438     if (baseWild == NULL) {
                14439         xmlChar *str = NULL;
                14440 
                14441         /*
                14442         * (4.1) "The {base type definition} must also have one."
                14443         */
                14444         xmlSchemaCustomErr4(ACTXT_CAST pctxt,
                14445         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
                14446         NULL, item,
                14447         "The %s has an attribute wildcard, "
                14448         "but the %s %s '%s' does not have one",
                14449         WXS_ITEM_TYPE_NAME(item),
                14450         WXS_ACTION_STR(action),
                14451         WXS_ITEM_TYPE_NAME(baseItem),
                14452         xmlSchemaGetComponentQName(&str, baseItem));
                14453         FREE_AND_NULL(str);
                14454         return(pctxt->err);
                14455     } else if ((baseWild->any == 0) &&
                14456         xmlSchemaCheckCOSNSSubset(wild, baseWild))
                14457     {
                14458         xmlChar *str = NULL;
                14459         /*
                14460         * (4.2) "The complex type definition's {attribute wildcard}'s
                14461         * {namespace constraint} must be a subset of the {base type
                14462         * definition}'s {attribute wildcard}'s {namespace constraint},
                14463         * as defined by Wildcard Subset ($3.10.6)."
                14464         */
                14465         xmlSchemaCustomErr4(ACTXT_CAST pctxt,
                14466         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
                14467         NULL, item,
                14468         "The attribute wildcard is not a valid "
                14469         "subset of the wildcard in the %s %s '%s'",
                14470         WXS_ACTION_STR(action),
                14471         WXS_ITEM_TYPE_NAME(baseItem),
                14472         xmlSchemaGetComponentQName(&str, baseItem),
                14473         NULL);
                14474         FREE_AND_NULL(str);
                14475         return(pctxt->err);
                14476     }
                14477     /* 4.3 Unless the {base type definition} is the `ur-type
                14478     * definition`, the complex type definition's {attribute
                14479     * wildcard}'s {process contents} must be identical to or
                14480     * stronger than the {base type definition}'s {attribute
                14481     * wildcard}'s {process contents}, where strict is stronger
                14482     * than lax is stronger than skip.
                14483     */
                14484     if ((! WXS_IS_ANYTYPE(baseItem)) &&
                14485         (wild->processContents < baseWild->processContents)) {
                14486         xmlChar *str = NULL;
                14487         xmlSchemaCustomErr4(ACTXT_CAST pctxt,
                14488         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
                14489         NULL, baseItem,
                14490         "The {process contents} of the attribute wildcard is "
                14491         "weaker than the one in the %s %s '%s'",
                14492         WXS_ACTION_STR(action),
                14493         WXS_ITEM_TYPE_NAME(baseItem),
                14494         xmlSchemaGetComponentQName(&str, baseItem),
                14495         NULL);
                14496         FREE_AND_NULL(str)
                14497         return(pctxt->err);
                14498     }
                14499     }
                14500     return(0);
                14501 }
                14502 
                14503 
                14504 static int
                14505 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
                14506                   xmlSchemaBasicItemPtr item,
                14507                   xmlSchemaWildcardPtr *completeWild,
                14508                   xmlSchemaItemListPtr list,
                14509                   xmlSchemaItemListPtr prohibs);
                14510 /**
                14511  * xmlSchemaFixupTypeAttributeUses:
                14512  * @ctxt:  the schema parser context
                14513  * @type:  the complex type definition
                14514  *
                14515  *
                14516  * Builds the wildcard and the attribute uses on the given complex type.
                14517  * Returns -1 if an internal error occurs, 0 otherwise.
                14518  *
                14519  * ATTENTION TODO: Experimentally this uses pointer comparisons for
                14520  * strings, so recheck this if we start to hardcode some schemata, since
                14521  * they might not be in the same dict.
                14522  * NOTE: It is allowed to "extend" the xs:anyType type.
                14523  */
                14524 static int
                14525 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
                14526                   xmlSchemaTypePtr type)
                14527 {
                14528     xmlSchemaTypePtr baseType = NULL;
                14529     xmlSchemaAttributeUsePtr use;
                14530     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
                14531 
                14532     if (type->baseType == NULL) {
                14533     PERROR_INT("xmlSchemaFixupTypeAttributeUses",
                14534         "no base type");
                14535         return (-1);
                14536     }
                14537     baseType = type->baseType;
                14538     if (WXS_IS_TYPE_NOT_FIXED(baseType))
                14539     if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
                14540         return(-1);
                14541 
                14542     uses = type->attrUses;
                14543     baseUses = baseType->attrUses;
                14544     /*
                14545     * Expand attribute group references. And build the 'complete'
                14546     * wildcard, i.e. intersect multiple wildcards.
                14547     * Move attribute prohibitions into a separate list.
                14548     */
                14549     if (uses != NULL) {
                14550     if (WXS_IS_RESTRICTION(type)) {
                14551         /*
                14552         * This one will transfer all attr. prohibitions
                14553         * into pctxt->attrProhibs.
                14554         */
                14555         if (xmlSchemaExpandAttributeGroupRefs(pctxt,
                14556         WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
                14557         pctxt->attrProhibs) == -1)
                14558         {
                14559         PERROR_INT("xmlSchemaFixupTypeAttributeUses",
                14560         "failed to expand attributes");
ad7b9726c Alex*14561                 return(-1);
9d9d4fcc3 Alex*14562         }
                14563         if (pctxt->attrProhibs->nbItems != 0)
                14564         prohibs = pctxt->attrProhibs;
                14565     } else {
                14566         if (xmlSchemaExpandAttributeGroupRefs(pctxt,
                14567         WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
                14568         NULL) == -1)
                14569         {
                14570         PERROR_INT("xmlSchemaFixupTypeAttributeUses",
                14571         "failed to expand attributes");
ad7b9726c Alex*14572                 return(-1);
9d9d4fcc3 Alex*14573         }
                14574     }
                14575     }
                14576     /*
                14577     * Inherit the attribute uses of the base type.
                14578     */
                14579     if (baseUses != NULL) {
                14580     int i, j;
                14581     xmlSchemaAttributeUseProhibPtr pro;
                14582 
                14583     if (WXS_IS_RESTRICTION(type)) {
                14584         int usesCount;
                14585         xmlSchemaAttributeUsePtr tmp;
                14586 
                14587         if (uses != NULL)
                14588         usesCount = uses->nbItems;
                14589         else
                14590         usesCount = 0;
                14591 
                14592         /* Restriction. */
                14593         for (i = 0; i < baseUses->nbItems; i++) {
                14594         use = baseUses->items[i];
                14595         if (prohibs) {
                14596             /*
                14597             * Filter out prohibited uses.
                14598             */
                14599             for (j = 0; j < prohibs->nbItems; j++) {
                14600             pro = prohibs->items[j];
                14601             if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
                14602                 (WXS_ATTRUSE_DECL_TNS(use) ==
                14603                 pro->targetNamespace))
                14604             {
                14605                 goto inherit_next;
                14606             }
                14607             }
                14608         }
                14609         if (usesCount) {
                14610             /*
                14611             * Filter out existing uses.
                14612             */
                14613             for (j = 0; j < usesCount; j++) {
                14614             tmp = uses->items[j];
                14615             if ((WXS_ATTRUSE_DECL_NAME(use) ==
                14616                 WXS_ATTRUSE_DECL_NAME(tmp)) &&
                14617                 (WXS_ATTRUSE_DECL_TNS(use) ==
                14618                 WXS_ATTRUSE_DECL_TNS(tmp)))
                14619             {
                14620                 goto inherit_next;
                14621             }
                14622             }
                14623         }
                14624         if (uses == NULL) {
                14625             type->attrUses = xmlSchemaItemListCreate();
                14626             if (type->attrUses == NULL)
                14627             goto exit_failure;
                14628             uses = type->attrUses;
                14629         }
                14630         xmlSchemaItemListAddSize(uses, 2, use);
                14631 inherit_next: {}
                14632         }
                14633     } else {
                14634         /* Extension. */
                14635         for (i = 0; i < baseUses->nbItems; i++) {
                14636         use = baseUses->items[i];
                14637         if (uses == NULL) {
                14638             type->attrUses = xmlSchemaItemListCreate();
                14639             if (type->attrUses == NULL)
                14640             goto exit_failure;
                14641             uses = type->attrUses;
                14642         }
                14643         xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
                14644         }
                14645     }
                14646     }
                14647     /*
                14648     * Shrink attr. uses.
                14649     */
                14650     if (uses) {
                14651     if (uses->nbItems == 0) {
                14652         xmlSchemaItemListFree(uses);
                14653         type->attrUses = NULL;
                14654     }
                14655     /*
                14656     * TODO: We could shrink the size of the array
                14657     * to fit the actual number of items.
                14658     */
                14659     }
                14660     /*
                14661     * Compute the complete wildcard.
                14662     */
                14663     if (WXS_IS_EXTENSION(type)) {
                14664     if (baseType->attributeWildcard != NULL) {
                14665         /*
                14666         * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
                14667         * the appropriate case among the following:"
                14668         */
                14669         if (type->attributeWildcard != NULL) {
                14670         /*
                14671         * Union the complete wildcard with the base wildcard.
                14672         * SPEC {attribute wildcard}
                14673         * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
                14674         * and {annotation} are those of the `complete wildcard`,
                14675         * and whose {namespace constraint} is the intensional union
                14676         * of the {namespace constraint} of the `complete wildcard`
                14677         * and of the `base wildcard`, as defined in Attribute
                14678         * Wildcard Union ($3.10.6)."
                14679         */
                14680         if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
                14681             baseType->attributeWildcard) == -1)
                14682             goto exit_failure;
                14683         } else {
                14684         /*
                14685         * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
                14686         * then the `base wildcard`."
                14687         */
                14688         type->attributeWildcard = baseType->attributeWildcard;
                14689         }
                14690     } else {
                14691         /*
                14692         * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
                14693         * `complete wildcard`"
                14694         * NOOP
                14695         */
                14696     }
                14697     } else {
                14698     /*
                14699     * SPEC {attribute wildcard}
                14700     * (3.1) "If the <restriction> alternative is chosen, then the
                14701     * `complete wildcard`;"
                14702     * NOOP
                14703     */
                14704     }
                14705 
                14706     return (0);
                14707 
                14708 exit_failure:
                14709     return(-1);
                14710 }
                14711 
                14712 /**
                14713  * xmlSchemaTypeFinalContains:
                14714  * @schema:  the schema
                14715  * @type:  the type definition
                14716  * @final: the final
                14717  *
                14718  * Evaluates if a type definition contains the given "final".
                14719  * This does take "finalDefault" into account as well.
                14720  *
                14721  * Returns 1 if the type does contain the given "final",
                14722  * 0 otherwise.
                14723  */
                14724 static int
                14725 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
                14726 {
                14727     if (type == NULL)
                14728     return (0);
                14729     if (type->flags & final)
                14730     return (1);
                14731     else
                14732     return (0);
                14733 }
                14734 
                14735 /**
                14736  * xmlSchemaGetUnionSimpleTypeMemberTypes:
                14737  * @type:  the Union Simple Type
                14738  *
                14739  * Returns a list of member types of @type if existing,
                14740  * returns NULL otherwise.
                14741  */
                14742 static xmlSchemaTypeLinkPtr
                14743 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
                14744 {
                14745     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
                14746     if (type->memberTypes != NULL)
                14747         return (type->memberTypes);
                14748     else
                14749         type = type->baseType;
                14750     }
                14751     return (NULL);
                14752 }
                14753 
                14754 #if 0
                14755 /**
                14756  * xmlSchemaGetParticleTotalRangeMin:
                14757  * @particle: the particle
                14758  *
                14759  * Schema Component Constraint: Effective Total Range
                14760  * (all and sequence) + (choice)
                14761  *
                14762  * Returns the minimum Effective Total Range.
                14763  */
                14764 static int
                14765 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
                14766 {
                14767     if ((particle->children == NULL) ||
                14768     (particle->minOccurs == 0))
                14769     return (0);
                14770     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
                14771     int min = -1, cur;
                14772     xmlSchemaParticlePtr part =
                14773         (xmlSchemaParticlePtr) particle->children->children;
                14774 
                14775     if (part == NULL)
                14776         return (0);
                14777     while (part != NULL) {
                14778         if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
                14779         (part->children->type == XML_SCHEMA_TYPE_ANY))
                14780         cur = part->minOccurs;
                14781         else
                14782         cur = xmlSchemaGetParticleTotalRangeMin(part);
                14783         if (cur == 0)
                14784         return (0);
                14785         if ((min > cur) || (min == -1))
                14786         min = cur;
                14787         part = (xmlSchemaParticlePtr) part->next;
                14788     }
                14789     return (particle->minOccurs * min);
                14790     } else {
                14791     /* <all> and <sequence> */
                14792     int sum = 0;
                14793     xmlSchemaParticlePtr part =
                14794         (xmlSchemaParticlePtr) particle->children->children;
                14795 
                14796     if (part == NULL)
                14797         return (0);
                14798     do {
                14799         if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
                14800         (part->children->type == XML_SCHEMA_TYPE_ANY))
                14801         sum += part->minOccurs;
                14802         else
                14803         sum += xmlSchemaGetParticleTotalRangeMin(part);
                14804         part = (xmlSchemaParticlePtr) part->next;
                14805     } while (part != NULL);
                14806     return (particle->minOccurs * sum);
                14807     }
                14808 }
                14809 
                14810 /**
                14811  * xmlSchemaGetParticleTotalRangeMax:
                14812  * @particle: the particle
                14813  *
                14814  * Schema Component Constraint: Effective Total Range
                14815  * (all and sequence) + (choice)
                14816  *
                14817  * Returns the maximum Effective Total Range.
                14818  */
                14819 static int
                14820 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
                14821 {
                14822     if ((particle->children == NULL) ||
                14823     (particle->children->children == NULL))
                14824     return (0);
                14825     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
                14826     int max = -1, cur;
                14827     xmlSchemaParticlePtr part =
                14828         (xmlSchemaParticlePtr) particle->children->children;
                14829 
                14830     for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
                14831         if (part->children == NULL)
                14832         continue;
                14833         if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
                14834         (part->children->type == XML_SCHEMA_TYPE_ANY))
                14835         cur = part->maxOccurs;
                14836         else
                14837         cur = xmlSchemaGetParticleTotalRangeMax(part);
                14838         if (cur == UNBOUNDED)
                14839         return (UNBOUNDED);
                14840         if ((max < cur) || (max == -1))
                14841         max = cur;
                14842     }
                14843     /* TODO: Handle overflows? */
                14844     return (particle->maxOccurs * max);
                14845     } else {
                14846     /* <all> and <sequence> */
                14847     int sum = 0, cur;
                14848     xmlSchemaParticlePtr part =
                14849         (xmlSchemaParticlePtr) particle->children->children;
                14850 
                14851     for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
                14852         if (part->children == NULL)
                14853         continue;
                14854         if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
                14855         (part->children->type == XML_SCHEMA_TYPE_ANY))
                14856         cur = part->maxOccurs;
                14857         else
                14858         cur = xmlSchemaGetParticleTotalRangeMax(part);
                14859         if (cur == UNBOUNDED)
                14860         return (UNBOUNDED);
                14861         if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
                14862         return (UNBOUNDED);
                14863         sum += cur;
                14864     }
                14865     /* TODO: Handle overflows? */
                14866     return (particle->maxOccurs * sum);
                14867     }
                14868 }
                14869 #endif
                14870 
                14871 /**
                14872  * xmlSchemaGetParticleEmptiable:
                14873  * @particle: the particle
                14874  *
                14875  * Returns 1 if emptiable, 0 otherwise.
                14876  */
                14877 static int
                14878 xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
                14879 {
                14880     xmlSchemaParticlePtr part;
                14881     int emptiable;
                14882 
                14883     if ((particle->children == NULL) || (particle->minOccurs == 0))
                14884     return (1);
                14885 
                14886     part = (xmlSchemaParticlePtr) particle->children->children;
                14887     if (part == NULL)
                14888         return (1);
                14889 
                14890     while (part != NULL) {
                14891         if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
                14892             (part->children->type == XML_SCHEMA_TYPE_ANY))
                14893             emptiable = (part->minOccurs == 0);
                14894         else
                14895             emptiable = xmlSchemaGetParticleEmptiable(part);
                14896         if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
                14897             if (emptiable)
                14898                 return (1);
                14899         } else {
                14900         /* <all> and <sequence> */
                14901             if (!emptiable)
                14902                 return (0);
                14903         }
                14904         part = (xmlSchemaParticlePtr) part->next;
                14905     }
                14906 
                14907     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
                14908         return (0);
                14909     else
                14910         return (1);
                14911 }
                14912 
                14913 /**
                14914  * xmlSchemaIsParticleEmptiable:
                14915  * @particle: the particle
                14916  *
                14917  * Schema Component Constraint: Particle Emptiable
                14918  * Checks whether the given particle is emptiable.
                14919  *
                14920  * Returns 1 if emptiable, 0 otherwise.
                14921  */
                14922 static int
                14923 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
                14924 {
                14925     /*
                14926     * SPEC (1) "Its {min occurs} is 0."
                14927     */
                14928     if ((particle == NULL) || (particle->minOccurs == 0) ||
                14929     (particle->children == NULL))
                14930     return (1);
                14931     /*
                14932     * SPEC (2) "Its {term} is a group and the minimum part of the
                14933     * effective total range of that group, [...] is 0."
                14934     */
                14935     if (WXS_IS_MODEL_GROUP(particle->children))
                14936     return (xmlSchemaGetParticleEmptiable(particle));
                14937     return (0);
                14938 }
                14939 
                14940 /**
                14941  * xmlSchemaCheckCOSSTDerivedOK:
                14942  * @actxt: a context
                14943  * @type:  the derived simple type definition
                14944  * @baseType:  the base type definition
                14945  * @subset: the subset of ('restriction', etc.)
                14946  *
                14947  * Schema Component Constraint:
                14948  * Type Derivation OK (Simple) (cos-st-derived-OK)
                14949  *
                14950  * Checks whether @type can be validly
                14951  * derived from @baseType.
                14952  *
                14953  * Returns 0 on success, an positive error code otherwise.
                14954  */
                14955 static int
                14956 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
                14957                  xmlSchemaTypePtr type,
                14958                  xmlSchemaTypePtr baseType,
                14959                  int subset)
                14960 {
                14961     /*
                14962     * 1 They are the same type definition.
                14963     * TODO: The identity check might have to be more complex than this.
                14964     */
                14965     if (type == baseType)
                14966     return (0);
                14967     /*
                14968     * 2.1 restriction is not in the subset, or in the {final}
                14969     * of its own {base type definition};
                14970     *
                14971     * NOTE that this will be used also via "xsi:type".
                14972     *
                14973     * TODO: Revise this, it looks strange. How can the "type"
                14974     * not be fixed or *in* fixing?
                14975     */
                14976     if (WXS_IS_TYPE_NOT_FIXED(type))
                14977     if (xmlSchemaTypeFixup(type, actxt) == -1)
                14978         return(-1);
                14979     if (WXS_IS_TYPE_NOT_FIXED(baseType))
                14980     if (xmlSchemaTypeFixup(baseType, actxt) == -1)
                14981         return(-1);
                14982     if ((subset & SUBSET_RESTRICTION) ||
                14983     (xmlSchemaTypeFinalContains(type->baseType,
                14984         XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
                14985     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
                14986     }
                14987     /* 2.2 */
                14988     if (type->baseType == baseType) {
                14989     /*
                14990     * 2.2.1 D's `base type definition` is B.
                14991     */
                14992     return (0);
                14993     }
                14994     /*
                14995     * 2.2.2 D's `base type definition` is not the `ur-type definition`
                14996     * and is validly derived from B given the subset, as defined by this
                14997     * constraint.
                14998     */
                14999     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
                15000     (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
                15001         baseType, subset) == 0)) {
                15002     return (0);
                15003     }
                15004     /*
                15005     * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
                15006     * definition`.
                15007     */
                15008     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
                15009     (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
                15010     return (0);
                15011     }
                15012     /*
                15013     * 2.2.4 B's {variety} is union and D is validly derived from a type
                15014     * definition in B's {member type definitions} given the subset, as
                15015     * defined by this constraint.
                15016     *
                15017     * NOTE: This seems not to involve built-in types, since there is no
                15018     * built-in Union Simple Type.
                15019     */
                15020     if (WXS_IS_UNION(baseType)) {
                15021     xmlSchemaTypeLinkPtr cur;
                15022 
                15023     cur = baseType->memberTypes;
                15024     while (cur != NULL) {
                15025         if (WXS_IS_TYPE_NOT_FIXED(cur->type))
                15026         if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
                15027             return(-1);
                15028         if (xmlSchemaCheckCOSSTDerivedOK(actxt,
                15029             type, cur->type, subset) == 0)
                15030         {
                15031         /*
                15032         * It just has to be validly derived from at least one
                15033         * member-type.
                15034         */
                15035         return (0);
                15036         }
                15037         cur = cur->next;
                15038     }
                15039     }
                15040     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
                15041 }
                15042 
                15043 /**
                15044  * xmlSchemaCheckTypeDefCircularInternal:
                15045  * @pctxt:  the schema parser context
                15046  * @ctxtType:  the type definition
                15047  * @ancestor: an ancestor of @ctxtType
                15048  *
                15049  * Checks st-props-correct (2) + ct-props-correct (3).
                15050  * Circular type definitions are not allowed.
                15051  *
                15052  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
                15053  * circular, 0 otherwise.
                15054  */
                15055 static int
                15056 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
                15057                xmlSchemaTypePtr ctxtType,
                15058                xmlSchemaTypePtr ancestor)
                15059 {
                15060     int ret;
                15061 
                15062     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
                15063     return (0);
                15064 
                15065     if (ctxtType == ancestor) {
                15066     xmlSchemaPCustomErr(pctxt,
                15067         XML_SCHEMAP_ST_PROPS_CORRECT_2,
                15068         WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
                15069         "The definition is circular", NULL);
                15070     return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
                15071     }
                15072     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
                15073     /*
                15074     * Avoid infinite recursion on circular types not yet checked.
                15075     */
                15076     return (0);
                15077     }
                15078     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
                15079     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
                15080     ancestor->baseType);
                15081     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
                15082     return (ret);
                15083 }
                15084 
                15085 /**
                15086  * xmlSchemaCheckTypeDefCircular:
                15087  * @item:  the complex/simple type definition
                15088  * @ctxt:  the parser context
                15089  * @name:  the name
                15090  *
                15091  * Checks for circular type definitions.
                15092  */
                15093 static void
                15094 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
                15095                   xmlSchemaParserCtxtPtr ctxt)
                15096 {
                15097     if ((item == NULL) ||
                15098     (item->type == XML_SCHEMA_TYPE_BASIC) ||
                15099     (item->baseType == NULL))
                15100     return;
                15101     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
                15102     item->baseType);
                15103 }
                15104 
                15105 /*
                15106 * Simple Type Definition Representation OK (src-simple-type) 4
                15107 *
                15108 * "4 Circular union type definition is disallowed. That is, if the
                15109 * <union> alternative is chosen, there must not be any entries in the
                15110 * memberTypes [attribute] at any depth which resolve to the component
                15111 * corresponding to the <simpleType>."
                15112 *
                15113 * Note that this should work on the *representation* of a component,
                15114 * thus assumes any union types in the member types not being yet
                15115 * substituted. At this stage we need the variety of the types
                15116 * to be already computed.
                15117 */
                15118 static int
                15119 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
                15120                     xmlSchemaTypePtr ctxType,
                15121                     xmlSchemaTypeLinkPtr members)
                15122 {
                15123     xmlSchemaTypeLinkPtr member;
                15124     xmlSchemaTypePtr memberType;
                15125 
                15126     member = members;
                15127     while (member != NULL) {
                15128     memberType = member->type;
                15129     while ((memberType != NULL) &&
                15130         (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
                15131         if (memberType == ctxType) {
                15132         xmlSchemaPCustomErr(pctxt,
                15133             XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
                15134             WXS_BASIC_CAST ctxType, NULL,
                15135             "The union type definition is circular", NULL);
                15136         return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
                15137         }
                15138         if ((WXS_IS_UNION(memberType)) &&
                15139         ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
                15140         {
                15141         int res;
                15142         memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
                15143         res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
                15144             ctxType,
                15145             xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
                15146         memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
                15147         if (res != 0)
                15148             return(res);
                15149         }
                15150         memberType = memberType->baseType;
                15151     }
                15152     member = member->next;
                15153     }
                15154     return(0);
                15155 }
                15156 
                15157 static int
                15158 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
                15159                    xmlSchemaTypePtr type)
                15160 {
                15161     if (! WXS_IS_UNION(type))
                15162     return(0);
                15163     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
                15164     type->memberTypes));
                15165 }
                15166 
                15167 /**
                15168  * xmlSchemaResolveTypeReferences:
                15169  * @item:  the complex/simple type definition
                15170  * @ctxt:  the parser context
                15171  * @name:  the name
                15172  *
                15173  * Resolves type definition references
                15174  */
                15175 static void
                15176 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
                15177              xmlSchemaParserCtxtPtr ctxt)
                15178 {
                15179     if (typeDef == NULL)
                15180     return;
                15181 
                15182     /*
                15183     * Resolve the base type.
                15184     */
                15185     if (typeDef->baseType == NULL) {
                15186     typeDef->baseType = xmlSchemaGetType(ctxt->schema,
                15187         typeDef->base, typeDef->baseNs);
                15188     if (typeDef->baseType == NULL) {
                15189         xmlSchemaPResCompAttrErr(ctxt,
                15190         XML_SCHEMAP_SRC_RESOLVE,
                15191         WXS_BASIC_CAST typeDef, typeDef->node,
                15192         "base", typeDef->base, typeDef->baseNs,
                15193         XML_SCHEMA_TYPE_SIMPLE, NULL);
                15194         return;
                15195     }
                15196     }
                15197     if (WXS_IS_SIMPLE(typeDef)) {
                15198     if (WXS_IS_UNION(typeDef)) {
                15199         /*
                15200         * Resolve the memberTypes.
                15201         */
                15202         xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
                15203         return;
                15204     } else if (WXS_IS_LIST(typeDef)) {
                15205         /*
                15206         * Resolve the itemType.
                15207         */
                15208         if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
                15209 
                15210         typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
                15211             typeDef->base, typeDef->baseNs);
                15212 
                15213         if ((typeDef->subtypes == NULL) ||
                15214             (! WXS_IS_SIMPLE(typeDef->subtypes)))
                15215         {
                15216             typeDef->subtypes = NULL;
                15217             xmlSchemaPResCompAttrErr(ctxt,
                15218             XML_SCHEMAP_SRC_RESOLVE,
                15219             WXS_BASIC_CAST typeDef, typeDef->node,
                15220             "itemType", typeDef->base, typeDef->baseNs,
                15221             XML_SCHEMA_TYPE_SIMPLE, NULL);
                15222         }
                15223         }
                15224         return;
                15225     }
                15226     }
                15227     /*
                15228     * The ball of letters below means, that if we have a particle
                15229     * which has a QName-helper component as its {term}, we want
                15230     * to resolve it...
                15231     */
                15232     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
                15233     ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
                15234         XML_SCHEMA_TYPE_PARTICLE) &&
                15235     (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
                15236     ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
                15237         XML_SCHEMA_EXTRA_QNAMEREF))
                15238     {
                15239     xmlSchemaQNameRefPtr ref =
                15240         WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
                15241     xmlSchemaModelGroupDefPtr groupDef;
                15242 
                15243     /*
                15244     * URGENT TODO: Test this.
                15245     */
                15246     WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
                15247     /*
                15248     * Resolve the MG definition reference.
                15249     */
                15250     groupDef =
                15251         WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
                15252         ref->itemType, ref->name, ref->targetNamespace);
                15253     if (groupDef == NULL) {
                15254         xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
                15255         NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
                15256         "ref", ref->name, ref->targetNamespace, ref->itemType,
                15257         NULL);
                15258         /* Remove the particle. */
                15259         WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
                15260     } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
                15261         /* Remove the particle. */
                15262         WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
                15263     else {
                15264         /*
                15265         * Assign the MG definition's {model group} to the
                15266         * particle's {term}.
                15267         */
                15268         WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
                15269 
                15270         if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
                15271         /*
                15272         * SPEC cos-all-limited (1.2)
                15273         * "1.2 the {term} property of a particle with
                15274         * {max occurs}=1 which is part of a pair which constitutes
                15275         * the {content type} of a complex type definition."
                15276         */
                15277         if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
                15278             xmlSchemaCustomErr(ACTXT_CAST ctxt,
                15279             /* TODO: error code */
                15280             XML_SCHEMAP_COS_ALL_LIMITED,
                15281             WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
                15282             "The particle's {max occurs} must be 1, since the "
                15283             "reference resolves to an 'all' model group",
                15284             NULL, NULL);
                15285         }
                15286         }
                15287     }
                15288     }
                15289 }
                15290 
                15291 
                15292 
                15293 /**
                15294  * xmlSchemaCheckSTPropsCorrect:
                15295  * @ctxt:  the schema parser context
                15296  * @type:  the simple type definition
                15297  *
                15298  * Checks st-props-correct.
                15299  *
                15300  * Returns 0 if the properties are correct,
                15301  * if not, a positive error code and -1 on internal
                15302  * errors.
                15303  */
                15304 static int
                15305 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
                15306                  xmlSchemaTypePtr type)
                15307 {
                15308     xmlSchemaTypePtr baseType = type->baseType;
                15309     xmlChar *str = NULL;
                15310 
                15311     /* STATE: error funcs converted. */
                15312     /*
                15313     * Schema Component Constraint: Simple Type Definition Properties Correct
                15314     *
                15315     * NOTE: This is somehow redundant, since we actually built a simple type
                15316     * to have all the needed information; this acts as an self test.
                15317     */
                15318     /* Base type: If the datatype has been `derived` by `restriction`
                15319     * then the Simple Type Definition component from which it is `derived`,
                15320     * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
                15321     */
                15322     if (baseType == NULL) {
                15323     /*
                15324     * TODO: Think about: "modulo the impact of Missing
                15325     * Sub-components ($5.3)."
                15326     */
                15327     xmlSchemaPCustomErr(ctxt,
                15328         XML_SCHEMAP_ST_PROPS_CORRECT_1,
                15329         WXS_BASIC_CAST type, NULL,
                15330         "No base type existent", NULL);
                15331     return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
                15332 
                15333     }
                15334     if (! WXS_IS_SIMPLE(baseType)) {
                15335     xmlSchemaPCustomErr(ctxt,
                15336         XML_SCHEMAP_ST_PROPS_CORRECT_1,
                15337         WXS_BASIC_CAST type, NULL,
                15338         "The base type '%s' is not a simple type",
                15339         xmlSchemaGetComponentQName(&str, baseType));
                15340     FREE_AND_NULL(str)
                15341     return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
                15342     }
                15343     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
                15344     (WXS_IS_RESTRICTION(type) == 0) &&
                15345     ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
                15346          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
                15347     xmlSchemaPCustomErr(ctxt,
                15348         XML_SCHEMAP_ST_PROPS_CORRECT_1,
                15349         WXS_BASIC_CAST type, NULL,
                15350         "A type, derived by list or union, must have "
                15351         "the simple ur-type definition as base type, not '%s'",
                15352         xmlSchemaGetComponentQName(&str, baseType));
                15353     FREE_AND_NULL(str)
                15354     return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
                15355     }
                15356     /*
                15357     * Variety: One of {atomic, list, union}.
                15358     */
                15359     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
                15360     (! WXS_IS_LIST(type))) {
                15361     xmlSchemaPCustomErr(ctxt,
                15362         XML_SCHEMAP_ST_PROPS_CORRECT_1,
                15363         WXS_BASIC_CAST type, NULL,
                15364         "The variety is absent", NULL);
                15365     return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
                15366     }
                15367     /* TODO: Finish this. Hmm, is this finished? */
                15368 
                15369     /*
                15370     * 3 The {final} of the {base type definition} must not contain restriction.
                15371     */
                15372     if (xmlSchemaTypeFinalContains(baseType,
                15373     XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
                15374     xmlSchemaPCustomErr(ctxt,
                15375         XML_SCHEMAP_ST_PROPS_CORRECT_3,
                15376         WXS_BASIC_CAST type, NULL,
                15377         "The 'final' of its base type '%s' must not contain "
                15378         "'restriction'",
                15379         xmlSchemaGetComponentQName(&str, baseType));
                15380     FREE_AND_NULL(str)
                15381     return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
                15382     }
                15383 
                15384     /*
                15385     * 2 All simple type definitions must be derived ultimately from the `simple
                15386     * ur-type definition` (so circular definitions are disallowed). That is, it
                15387     * must be possible to reach a built-in primitive datatype or the `simple
                15388     * ur-type definition` by repeatedly following the {base type definition}.
                15389     *
                15390     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
                15391     */
                15392     return (0);
                15393 }
                15394 
                15395 /**
                15396  * xmlSchemaCheckCOSSTRestricts:
                15397  * @ctxt:  the schema parser context
                15398  * @type:  the simple type definition
                15399  *
                15400  * Schema Component Constraint:
                15401  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
                15402 
                15403  * Checks if the given @type (simpleType) is derived validly by restriction.
                15404  * STATUS:
                15405  *
                15406  * Returns -1 on internal errors, 0 if the type is validly derived,
                15407  * a positive error code otherwise.
                15408  */
                15409 static int
                15410 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
                15411                  xmlSchemaTypePtr type)
                15412 {
                15413     xmlChar *str = NULL;
                15414 
                15415     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
                15416     PERROR_INT("xmlSchemaCheckCOSSTRestricts",
                15417         "given type is not a user-derived simpleType");
                15418     return (-1);
                15419     }
                15420 
                15421     if (WXS_IS_ATOMIC(type)) {
                15422     xmlSchemaTypePtr primitive;
                15423     /*
                15424     * 1.1 The {base type definition} must be an atomic simple
                15425     * type definition or a built-in primitive datatype.
                15426     */
                15427     if (! WXS_IS_ATOMIC(type->baseType)) {
                15428         xmlSchemaPCustomErr(pctxt,
                15429         XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
                15430         WXS_BASIC_CAST type, NULL,
                15431         "The base type '%s' is not an atomic simple type",
                15432         xmlSchemaGetComponentQName(&str, type->baseType));
                15433         FREE_AND_NULL(str)
                15434         return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
                15435     }
                15436     /* 1.2 The {final} of the {base type definition} must not contain
                15437     * restriction.
                15438     */
                15439     /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
                15440     if (xmlSchemaTypeFinalContains(type->baseType,
                15441         XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
                15442         xmlSchemaPCustomErr(pctxt,
                15443         XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
                15444         WXS_BASIC_CAST type, NULL,
                15445         "The final of its base type '%s' must not contain 'restriction'",
                15446         xmlSchemaGetComponentQName(&str, type->baseType));
                15447         FREE_AND_NULL(str)
                15448         return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
                15449     }
                15450 
                15451     /*
                15452     * 1.3.1 DF must be an allowed constraining facet for the {primitive
                15453     * type definition}, as specified in the appropriate subsection of 3.2
                15454     * Primitive datatypes.
                15455     */
                15456     if (type->facets != NULL) {
                15457         xmlSchemaFacetPtr facet;
                15458         int ok = 1;
                15459 
                15460         primitive = xmlSchemaGetPrimitiveType(type);
                15461         if (primitive == NULL) {
                15462         PERROR_INT("xmlSchemaCheckCOSSTRestricts",
                15463             "failed to get primitive type");
                15464         return (-1);
                15465         }
                15466         facet = type->facets;
                15467         do {
                15468         if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
                15469             ok = 0;
                15470             xmlSchemaPIllegalFacetAtomicErr(pctxt,
                15471             XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
                15472             type, primitive, facet);
                15473         }
                15474         facet = facet->next;
                15475         } while (facet != NULL);
                15476         if (ok == 0)
                15477         return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
                15478     }
                15479     /*
                15480     * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
                15481     * of the {base type definition} (call this BF),then the DF's {value}
                15482     * must be a valid restriction of BF's {value} as defined in
                15483     * [XML Schemas: Datatypes]."
                15484     *
                15485     * NOTE (1.3.2) Facet derivation constraints are currently handled in
                15486     * xmlSchemaDeriveAndValidateFacets()
                15487     */
                15488     } else if (WXS_IS_LIST(type)) {
                15489     xmlSchemaTypePtr itemType = NULL;
                15490 
                15491     itemType = type->subtypes;
                15492     if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
                15493         PERROR_INT("xmlSchemaCheckCOSSTRestricts",
                15494         "failed to evaluate the item type");
                15495         return (-1);
                15496     }
                15497     if (WXS_IS_TYPE_NOT_FIXED(itemType))
                15498         xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
                15499     /*
                15500     * 2.1 The {item type definition} must have a {variety} of atomic or
                15501     * union (in which case all the {member type definitions}
                15502     * must be atomic).
                15503     */
                15504     if ((! WXS_IS_ATOMIC(itemType)) &&
                15505         (! WXS_IS_UNION(itemType))) {
                15506         xmlSchemaPCustomErr(pctxt,
                15507         XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
                15508         WXS_BASIC_CAST type, NULL,
                15509         "The item type '%s' does not have a variety of atomic or union",
                15510         xmlSchemaGetComponentQName(&str, itemType));
                15511         FREE_AND_NULL(str)
                15512         return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
                15513     } else if (WXS_IS_UNION(itemType)) {
                15514         xmlSchemaTypeLinkPtr member;
                15515 
                15516         member = itemType->memberTypes;
                15517         while (member != NULL) {
                15518         if (! WXS_IS_ATOMIC(member->type)) {
                15519             xmlSchemaPCustomErr(pctxt,
                15520             XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
                15521             WXS_BASIC_CAST type, NULL,
                15522             "The item type is a union type, but the "
                15523             "member type '%s' of this item type is not atomic",
                15524             xmlSchemaGetComponentQName(&str, member->type));
                15525             FREE_AND_NULL(str)
                15526             return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
                15527         }
                15528         member = member->next;
                15529         }
                15530     }
                15531 
                15532     if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
                15533         xmlSchemaFacetPtr facet;
                15534         /*
                15535         * This is the case if we have: <simpleType><list ..
                15536         */
                15537         /*
                15538         * 2.3.1
                15539         * 2.3.1.1 The {final} of the {item type definition} must not
                15540         * contain list.
                15541         */
                15542         if (xmlSchemaTypeFinalContains(itemType,
                15543         XML_SCHEMAS_TYPE_FINAL_LIST)) {
                15544         xmlSchemaPCustomErr(pctxt,
                15545             XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
                15546             WXS_BASIC_CAST type, NULL,
                15547             "The final of its item type '%s' must not contain 'list'",
                15548             xmlSchemaGetComponentQName(&str, itemType));
                15549         FREE_AND_NULL(str)
                15550         return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
                15551         }
                15552         /*
                15553         * 2.3.1.2 The {facets} must only contain the whiteSpace
                15554         * facet component.
                15555         * OPTIMIZE TODO: the S4S already disallows any facet
                15556         * to be specified.
                15557         */
                15558         if (type->facets != NULL) {
                15559         facet = type->facets;
                15560         do {
                15561             if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
                15562             xmlSchemaPIllegalFacetListUnionErr(pctxt,
                15563                 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
                15564                 type, facet);
                15565             return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
                15566             }
                15567             facet = facet->next;
                15568         } while (facet != NULL);
                15569         }
                15570         /*
                15571         * MAYBE TODO: (Hmm, not really) Datatypes states:
                15572         * A `list` datatype can be `derived` from an `atomic` datatype
                15573         * whose `lexical space` allows space (such as string or anyURI)or
                15574         * a `union` datatype any of whose {member type definitions}'s
                15575         * `lexical space` allows space.
                15576         */
                15577     } else {
                15578         /*
                15579         * This is the case if we have: <simpleType><restriction ...
                15580         * I.e. the variety of "list" is inherited.
                15581         */
                15582         /*
                15583         * 2.3.2
                15584         * 2.3.2.1 The {base type definition} must have a {variety} of list.
                15585         */
                15586         if (! WXS_IS_LIST(type->baseType)) {
                15587         xmlSchemaPCustomErr(pctxt,
                15588             XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
                15589             WXS_BASIC_CAST type, NULL,
                15590             "The base type '%s' must be a list type",
                15591             xmlSchemaGetComponentQName(&str, type->baseType));
                15592         FREE_AND_NULL(str)
                15593         return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
                15594         }
                15595         /*
                15596         * 2.3.2.2 The {final} of the {base type definition} must not
                15597         * contain restriction.
                15598         */
                15599         if (xmlSchemaTypeFinalContains(type->baseType,
                15600         XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
                15601         xmlSchemaPCustomErr(pctxt,
                15602             XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
                15603             WXS_BASIC_CAST type, NULL,
                15604             "The 'final' of the base type '%s' must not contain 'restriction'",
                15605             xmlSchemaGetComponentQName(&str, type->baseType));
                15606         FREE_AND_NULL(str)
                15607         return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
                15608         }
                15609         /*
                15610         * 2.3.2.3 The {item type definition} must be validly derived
                15611         * from the {base type definition}'s {item type definition} given
                15612         * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
                15613         */
                15614         {
                15615         xmlSchemaTypePtr baseItemType;
                15616 
                15617         baseItemType = type->baseType->subtypes;
                15618         if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
                15619             PERROR_INT("xmlSchemaCheckCOSSTRestricts",
                15620             "failed to eval the item type of a base type");
                15621             return (-1);
                15622         }
                15623         if ((itemType != baseItemType) &&
                15624             (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
                15625             baseItemType, 0) != 0)) {
                15626             xmlChar *strBIT = NULL, *strBT = NULL;
                15627             xmlSchemaPCustomErrExt(pctxt,
                15628             XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
                15629             WXS_BASIC_CAST type, NULL,
                15630             "The item type '%s' is not validly derived from "
                15631             "the item type '%s' of the base type '%s'",
                15632             xmlSchemaGetComponentQName(&str, itemType),
                15633             xmlSchemaGetComponentQName(&strBIT, baseItemType),
                15634             xmlSchemaGetComponentQName(&strBT, type->baseType));
                15635 
                15636             FREE_AND_NULL(str)
                15637             FREE_AND_NULL(strBIT)
                15638             FREE_AND_NULL(strBT)
                15639             return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
                15640         }
                15641         }
                15642 
                15643         if (type->facets != NULL) {
                15644         xmlSchemaFacetPtr facet;
                15645         int ok = 1;
                15646         /*
                15647         * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
                15648         * and enumeration facet components are allowed among the {facets}.
                15649         */
                15650         facet = type->facets;
                15651         do {
                15652             switch (facet->type) {
                15653             case XML_SCHEMA_FACET_LENGTH:
                15654             case XML_SCHEMA_FACET_MINLENGTH:
                15655             case XML_SCHEMA_FACET_MAXLENGTH:
                15656             case XML_SCHEMA_FACET_WHITESPACE:
                15657                 /*
                15658                 * TODO: 2.5.1.2 List datatypes
                15659                 * The value of `whiteSpace` is fixed to the value collapse.
                15660                 */
                15661             case XML_SCHEMA_FACET_PATTERN:
                15662             case XML_SCHEMA_FACET_ENUMERATION:
                15663                 break;
                15664             default: {
                15665                 xmlSchemaPIllegalFacetListUnionErr(pctxt,
                15666                 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
                15667                 type, facet);
                15668                 /*
                15669                 * We could return, but it's nicer to report all
                15670                 * invalid facets.
                15671                 */
                15672                 ok = 0;
                15673             }
                15674             }
                15675             facet = facet->next;
                15676         } while (facet != NULL);
                15677         if (ok == 0)
                15678             return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
                15679         /*
                15680         * SPEC (2.3.2.5) (same as 1.3.2)
                15681         *
                15682         * NOTE (2.3.2.5) This is currently done in
                15683         * xmlSchemaDeriveAndValidateFacets()
                15684         */
                15685         }
                15686     }
                15687     } else if (WXS_IS_UNION(type)) {
                15688     /*
                15689     * 3.1 The {member type definitions} must all have {variety} of
                15690     * atomic or list.
                15691     */
                15692     xmlSchemaTypeLinkPtr member;
                15693 
                15694     member = type->memberTypes;
                15695     while (member != NULL) {
                15696         if (WXS_IS_TYPE_NOT_FIXED(member->type))
                15697         xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
                15698 
                15699         if ((! WXS_IS_ATOMIC(member->type)) &&
                15700         (! WXS_IS_LIST(member->type))) {
                15701         xmlSchemaPCustomErr(pctxt,
                15702             XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
                15703             WXS_BASIC_CAST type, NULL,
                15704             "The member type '%s' is neither an atomic, nor a list type",
                15705             xmlSchemaGetComponentQName(&str, member->type));
                15706         FREE_AND_NULL(str)
                15707         return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
                15708         }
                15709         member = member->next;
                15710     }
                15711     /*
                15712     * 3.3.1 If the {base type definition} is the `simple ur-type
                15713     * definition`
                15714     */
                15715     if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
                15716         /*
                15717         * 3.3.1.1 All of the {member type definitions} must have a
                15718         * {final} which does not contain union.
                15719         */
                15720         member = type->memberTypes;
                15721         while (member != NULL) {
                15722         if (xmlSchemaTypeFinalContains(member->type,
                15723             XML_SCHEMAS_TYPE_FINAL_UNION)) {
                15724             xmlSchemaPCustomErr(pctxt,
                15725             XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
                15726             WXS_BASIC_CAST type, NULL,
                15727             "The 'final' of member type '%s' contains 'union'",
                15728             xmlSchemaGetComponentQName(&str, member->type));
                15729             FREE_AND_NULL(str)
                15730             return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
                15731         }
                15732         member = member->next;
                15733         }
                15734         /*
                15735         * 3.3.1.2 The {facets} must be empty.
                15736         */
                15737         if (type->facetSet != NULL) {
                15738         xmlSchemaPCustomErr(pctxt,
                15739             XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
                15740             WXS_BASIC_CAST type, NULL,
                15741             "No facets allowed", NULL);
                15742         return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
                15743         }
                15744     } else {
                15745         /*
                15746         * 3.3.2.1 The {base type definition} must have a {variety} of union.
                15747         * I.e. the variety of "list" is inherited.
                15748         */
                15749         if (! WXS_IS_UNION(type->baseType)) {
                15750         xmlSchemaPCustomErr(pctxt,
                15751             XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
                15752             WXS_BASIC_CAST type, NULL,
                15753             "The base type '%s' is not a union type",
                15754             xmlSchemaGetComponentQName(&str, type->baseType));
                15755         FREE_AND_NULL(str)
                15756         return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
                15757         }
                15758         /*
                15759         * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
                15760         */
                15761         if (xmlSchemaTypeFinalContains(type->baseType,
                15762         XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
                15763         xmlSchemaPCustomErr(pctxt,
                15764             XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
                15765             WXS_BASIC_CAST type, NULL,
                15766             "The 'final' of its base type '%s' must not contain 'restriction'",
                15767             xmlSchemaGetComponentQName(&str, type->baseType));
                15768         FREE_AND_NULL(str)
                15769         return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
                15770         }
                15771         /*
                15772         * 3.3.2.3 The {member type definitions}, in order, must be validly
                15773         * derived from the corresponding type definitions in the {base
                15774         * type definition}'s {member type definitions} given the empty set,
                15775         * as defined in Type Derivation OK (Simple) ($3.14.6).
                15776         */
                15777         {
                15778         xmlSchemaTypeLinkPtr baseMember;
                15779 
                15780         /*
                15781         * OPTIMIZE: if the type is restricting, it has no local defined
                15782         * member types and inherits the member types of the base type;
                15783         * thus a check for equality can be skipped.
                15784         */
                15785         /*
                15786         * Even worse: I cannot see a scenario where a restricting
                15787         * union simple type can have other member types as the member
                15788         * types of it's base type. This check seems not necessary with
                15789         * respect to the derivation process in libxml2.
                15790         * But necessary if constructing types with an API.
                15791         */
                15792         if (type->memberTypes != NULL) {
                15793             member = type->memberTypes;
                15794             baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
                15795             if ((member == NULL) && (baseMember != NULL)) {
                15796             PERROR_INT("xmlSchemaCheckCOSSTRestricts",
                15797                 "different number of member types in base");
                15798             }
                15799             while (member != NULL) {
                15800             if (baseMember == NULL) {
                15801                 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
                15802                 "different number of member types in base");
                15803             } else if ((member->type != baseMember->type) &&
                15804                 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
                15805                 member->type, baseMember->type, 0) != 0)) {
                15806                 xmlChar *strBMT = NULL, *strBT = NULL;
                15807 
                15808                 xmlSchemaPCustomErrExt(pctxt,
                15809                 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
                15810                 WXS_BASIC_CAST type, NULL,
                15811                 "The member type %s is not validly "
                15812                 "derived from its corresponding member "
                15813                 "type %s of the base type %s",
                15814                 xmlSchemaGetComponentQName(&str, member->type),
                15815                 xmlSchemaGetComponentQName(&strBMT, baseMember->type),
                15816                 xmlSchemaGetComponentQName(&strBT, type->baseType));
                15817                 FREE_AND_NULL(str)
                15818                 FREE_AND_NULL(strBMT)
                15819                 FREE_AND_NULL(strBT)
                15820                 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
                15821             }
                15822             member = member->next;
                15823                         if (baseMember != NULL)
                15824                             baseMember = baseMember->next;
                15825             }
                15826         }
                15827         }
                15828         /*
                15829         * 3.3.2.4 Only pattern and enumeration facet components are
                15830         * allowed among the {facets}.
                15831         */
                15832         if (type->facets != NULL) {
                15833         xmlSchemaFacetPtr facet;
                15834         int ok = 1;
                15835 
                15836         facet = type->facets;
                15837         do {
                15838             if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
                15839             (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
                15840             xmlSchemaPIllegalFacetListUnionErr(pctxt,
                15841                 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
                15842                 type, facet);
                15843             ok = 0;
                15844             }
                15845             facet = facet->next;
                15846         } while (facet != NULL);
                15847         if (ok == 0)
                15848             return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
                15849 
                15850         }
                15851         /*
                15852         * SPEC (3.3.2.5) (same as 1.3.2)
                15853         *
                15854         * NOTE (3.3.2.5) This is currently done in
                15855         * xmlSchemaDeriveAndValidateFacets()
                15856         */
                15857     }
                15858     }
                15859 
                15860     return (0);
                15861 }
                15862 
                15863 /**
                15864  * xmlSchemaCheckSRCSimpleType:
                15865  * @ctxt:  the schema parser context
                15866  * @type:  the simple type definition
                15867  *
                15868  * Checks crc-simple-type constraints.
                15869  *
                15870  * Returns 0 if the constraints are satisfied,
                15871  * if not a positive error code and -1 on internal
                15872  * errors.
                15873  */
                15874 #if 0
                15875 static int
                15876 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
                15877                 xmlSchemaTypePtr type)
                15878 {
                15879     /*
                15880     * src-simple-type.1 The corresponding simple type definition, if any,
                15881     * must satisfy the conditions set out in Constraints on Simple Type
                15882     * Definition Schema Components ($3.14.6).
                15883     */
                15884     if (WXS_IS_RESTRICTION(type)) {
                15885     /*
                15886     * src-simple-type.2 "If the <restriction> alternative is chosen,
                15887     * either it must have a base [attribute] or a <simpleType> among its
                15888     * [children], but not both."
                15889     * NOTE: This is checked in the parse function of <restriction>.
                15890     */
                15891     /*
                15892     *
                15893     */
                15894     } else if (WXS_IS_LIST(type)) {
                15895     /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
                15896     * an itemType [attribute] or a <simpleType> among its [children],
                15897     * but not both."
                15898     *
                15899     * NOTE: This is checked in the parse function of <list>.
                15900     */
                15901     } else if (WXS_IS_UNION(type)) {
                15902     /*
                15903     * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
                15904     */
                15905     }
                15906     return (0);
                15907 }
                15908 #endif
                15909 
                15910 static int
                15911 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
                15912 {
                15913    if (ctxt->vctxt == NULL) {
                15914     ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
                15915     if (ctxt->vctxt == NULL) {
                15916         xmlSchemaPErr(ctxt, NULL,
                15917         XML_SCHEMAP_INTERNAL,
                15918         "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
                15919         "failed to create a temp. validation context.\n",
                15920         NULL, NULL);
                15921         return (-1);
                15922     }
                15923     /* TODO: Pass user data. */
                15924     xmlSchemaSetValidErrors(ctxt->vctxt,
                15925         ctxt->error, ctxt->warning, ctxt->errCtxt);
                15926     xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
                15927         ctxt->serror, ctxt->errCtxt);
                15928     }
                15929     return (0);
                15930 }
                15931 
                15932 static int
                15933 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
                15934                  xmlNodePtr node,
                15935                  xmlSchemaTypePtr type,
                15936                  const xmlChar *value,
                15937                  xmlSchemaValPtr *retVal,
                15938                  int fireErrors,
                15939                  int normalize,
                15940                  int isNormalized);
                15941 
                15942 /**
                15943  * xmlSchemaParseCheckCOSValidDefault:
                15944  * @pctxt:  the schema parser context
                15945  * @type:  the simple type definition
                15946  * @value: the default value
                15947  * @node: an optional node (the holder of the value)
                15948  *
                15949  * Schema Component Constraint: Element Default Valid (Immediate)
                15950  * (cos-valid-default)
                15951  * This will be used by the parser only. For the validator there's
                15952  * an other version.
                15953  *
                15954  * Returns 0 if the constraints are satisfied,
                15955  * if not, a positive error code and -1 on internal
                15956  * errors.
                15957  */
                15958 static int
                15959 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
                15960                    xmlNodePtr node,
                15961                    xmlSchemaTypePtr type,
                15962                    const xmlChar *value,
                15963                    xmlSchemaValPtr *val)
                15964 {
                15965     int ret = 0;
                15966 
                15967     /*
                15968     * cos-valid-default:
                15969     * Schema Component Constraint: Element Default Valid (Immediate)
                15970     * For a string to be a valid default with respect to a type
                15971     * definition the appropriate case among the following must be true:
                15972     */
                15973     if WXS_IS_COMPLEX(type) {
                15974     /*
                15975     * Complex type.
                15976     *
                15977     * SPEC (2.1) "its {content type} must be a simple type definition
                15978     * or mixed."
                15979     * SPEC (2.2.2) "If the {content type} is mixed, then the {content
                15980     * type}'s particle must be `emptiable` as defined by
                15981     * Particle Emptiable ($3.9.6)."
                15982     */
                15983     if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
                15984         ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
                15985         /* NOTE that this covers (2.2.2) as well. */
                15986         xmlSchemaPCustomErr(pctxt,
                15987         XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
                15988         WXS_BASIC_CAST type, type->node,
                15989         "For a string to be a valid default, the type definition "
                15990         "must be a simple type or a complex type with mixed content "
                15991         "and a particle emptiable", NULL);
                15992         return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
                15993     }
                15994     }
                15995     /*
                15996     * 1 If the type definition is a simple type definition, then the string
                15997     * must be `valid` with respect to that definition as defined by String
                15998     * Valid ($3.14.4).
                15999     *
                16000     * AND
                16001     *
                16002     * 2.2.1 If the {content type} is a simple type definition, then the
                16003     * string must be `valid` with respect to that simple type definition
                16004     * as defined by String Valid ($3.14.4).
                16005     */
                16006     if (WXS_IS_SIMPLE(type))
                16007     ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
                16008         type, value, val, 1, 1, 0);
                16009     else if (WXS_HAS_SIMPLE_CONTENT(type))
                16010     ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
                16011         type->contentTypeDef, value, val, 1, 1, 0);
                16012     else
                16013     return (ret);
                16014 
                16015     if (ret < 0) {
                16016     PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
                16017         "calling xmlSchemaVCheckCVCSimpleType()");
                16018     }
                16019 
                16020     return (ret);
                16021 }
                16022 
                16023 /**
                16024  * xmlSchemaCheckCTPropsCorrect:
                16025  * @ctxt:  the schema parser context
                16026  * @type:  the complex type definition
                16027  *
                16028  *.(4.6) Constraints on Complex Type Definition Schema Components
                16029  * Schema Component Constraint:
                16030  * Complex Type Definition Properties Correct (ct-props-correct)
                16031  * STATUS: (seems) complete
                16032  *
                16033  * Returns 0 if the constraints are satisfied, a positive
                16034  * error code if not and -1 if an internal error occurred.
                16035  */
                16036 static int
                16037 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
                16038                  xmlSchemaTypePtr type)
                16039 {
                16040     /*
                16041     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
                16042     *
                16043     * SPEC (1) "The values of the properties of a complex type definition must
                16044     * be as described in the property tableau in The Complex Type Definition
                16045     * Schema Component ($3.4.1), modulo the impact of Missing
                16046     * Sub-components ($5.3)."
                16047     */
                16048     if ((type->baseType != NULL) &&
                16049     (WXS_IS_SIMPLE(type->baseType)) &&
                16050     (WXS_IS_EXTENSION(type) == 0)) {
                16051     /*
                16052     * SPEC (2) "If the {base type definition} is a simple type definition,
                16053     * the {derivation method} must be extension."
                16054     */
                16055     xmlSchemaCustomErr(ACTXT_CAST pctxt,
                16056         XML_SCHEMAP_SRC_CT_1,
                16057         NULL, WXS_BASIC_CAST type,
                16058         "If the base type is a simple type, the derivation method must be "
                16059         "'extension'", NULL, NULL);
                16060     return (XML_SCHEMAP_SRC_CT_1);
                16061     }
                16062     /*
                16063     * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
                16064     * definition`. That is, it must be possible to reach the `ur-type
                16065     * definition` by repeatedly following the {base type definition}."
                16066     *
                16067     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
                16068     */
                16069     /*
                16070     * NOTE that (4) and (5) need the following:
                16071     *   - attribute uses need to be already inherited (apply attr. prohibitions)
                16072     *   - attribute group references need to be expanded already
                16073     *   - simple types need to be typefixed already
                16074     */
                16075     if (type->attrUses &&
                16076     (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
                16077     {
                16078     xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
                16079     xmlSchemaAttributeUsePtr use, tmp;
                16080     int i, j, hasId = 0;
                16081 
                16082     for (i = uses->nbItems -1; i >= 0; i--) {
                16083         use = uses->items[i];
                16084 
                16085         /*
                16086         * SPEC ct-props-correct
                16087         * (4) "Two distinct attribute declarations in the
                16088         * {attribute uses} must not have identical {name}s and
                16089         * {target namespace}s."
                16090         */
                16091         if (i > 0) {
                16092         for (j = i -1; j >= 0; j--) {
                16093             tmp = uses->items[j];
                16094             if ((WXS_ATTRUSE_DECL_NAME(use) ==
                16095             WXS_ATTRUSE_DECL_NAME(tmp)) &&
                16096             (WXS_ATTRUSE_DECL_TNS(use) ==
                16097             WXS_ATTRUSE_DECL_TNS(tmp)))
                16098             {
                16099             xmlChar *str = NULL;
                16100 
                16101             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                16102                 XML_SCHEMAP_AG_PROPS_CORRECT,
                16103                 NULL, WXS_BASIC_CAST type,
                16104                 "Duplicate %s",
                16105                 xmlSchemaGetComponentDesignation(&str, use),
                16106                 NULL);
                16107             FREE_AND_NULL(str);
                16108             /*
                16109             * Remove the duplicate.
                16110             */
                16111             if (xmlSchemaItemListRemove(uses, i) == -1)
                16112                 goto exit_failure;
                16113             goto next_use;
                16114             }
                16115         }
                16116         }
                16117         /*
                16118         * SPEC ct-props-correct
                16119         * (5) "Two distinct attribute declarations in the
                16120         * {attribute uses} must not have {type definition}s which
                16121         * are or are derived from ID."
                16122         */
                16123         if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
                16124         if (xmlSchemaIsDerivedFromBuiltInType(
                16125             WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
                16126         {
                16127             if (hasId) {
                16128             xmlChar *str = NULL;
                16129 
                16130             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                16131                 XML_SCHEMAP_AG_PROPS_CORRECT,
                16132                 NULL, WXS_BASIC_CAST type,
                16133                 "There must not exist more than one attribute "
                16134                 "declaration of type 'xs:ID' "
                16135                 "(or derived from 'xs:ID'). The %s violates this "
                16136                 "constraint",
                16137                 xmlSchemaGetComponentDesignation(&str, use),
                16138                 NULL);
                16139             FREE_AND_NULL(str);
                16140             if (xmlSchemaItemListRemove(uses, i) == -1)
                16141                 goto exit_failure;
                16142             }
                16143 
                16144             hasId = 1;
                16145         }
                16146         }
                16147 next_use: {}
                16148     }
                16149     }
                16150     return (0);
                16151 exit_failure:
                16152     return(-1);
                16153 }
                16154 
                16155 static int
                16156 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
                16157                xmlSchemaTypePtr typeB)
                16158 {
                16159     /*
                16160     * TODO: This should implement component-identity
                16161     * in the future.
                16162     */
                16163     if ((typeA == NULL) || (typeB == NULL))
                16164     return (0);
                16165     return (typeA == typeB);
                16166 }
                16167 
                16168 /**
                16169  * xmlSchemaCheckCOSCTDerivedOK:
                16170  * @ctxt:  the schema parser context
                16171  * @type:  the to-be derived complex type definition
                16172  * @baseType:  the base complex type definition
                16173  * @set: the given set
                16174  *
                16175  * Schema Component Constraint:
                16176  * Type Derivation OK (Complex) (cos-ct-derived-ok)
                16177  *
                16178  * STATUS: completed
                16179  *
                16180  * Returns 0 if the constraints are satisfied, or 1
                16181  * if not.
                16182  */
                16183 static int
                16184 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
                16185                  xmlSchemaTypePtr type,
                16186                  xmlSchemaTypePtr baseType,
                16187                  int set)
                16188 {
                16189     int equal = xmlSchemaAreEqualTypes(type, baseType);
                16190     /* TODO: Error codes. */
                16191     /*
                16192     * SPEC "For a complex type definition (call it D, for derived)
                16193     * to be validly derived from a type definition (call this
                16194     * B, for base) given a subset of {extension, restriction}
                16195     * all of the following must be true:"
                16196     */
                16197     if (! equal) {
                16198     /*
                16199     * SPEC (1) "If B and D are not the same type definition, then the
                16200     * {derivation method} of D must not be in the subset."
                16201     */
                16202     if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
                16203         ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
                16204         return (1);
                16205     } else {
                16206     /*
                16207     * SPEC (2.1) "B and D must be the same type definition."
                16208     */
                16209     return (0);
                16210     }
                16211     /*
                16212     * SPEC (2.2) "B must be D's {base type definition}."
                16213     */
                16214     if (type->baseType == baseType)
                16215     return (0);
                16216     /*
                16217     * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
                16218     * definition`."
                16219     */
                16220     if (WXS_IS_ANYTYPE(type->baseType))
                16221     return (1);
                16222 
                16223     if (WXS_IS_COMPLEX(type->baseType)) {
                16224     /*
                16225     * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
                16226     * must be validly derived from B given the subset as defined by this
                16227     * constraint."
                16228     */
                16229     return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
                16230         baseType, set));
                16231     } else {
                16232     /*
                16233     * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
                16234     * must be validly derived from B given the subset as defined in Type
                16235     * Derivation OK (Simple) ($3.14.6).
                16236     */
                16237     return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
                16238         baseType, set));
                16239     }
                16240 }
                16241 
                16242 /**
                16243  * xmlSchemaCheckCOSDerivedOK:
                16244  * @type:  the derived simple type definition
                16245  * @baseType:  the base type definition
                16246  *
                16247  * Calls:
                16248  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
                16249  *
                16250  * Checks whether @type can be validly derived from @baseType.
                16251  *
                16252  * Returns 0 on success, an positive error code otherwise.
                16253  */
                16254 static int
                16255 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
                16256                xmlSchemaTypePtr type,
                16257                xmlSchemaTypePtr baseType,
                16258                int set)
                16259 {
                16260     if (WXS_IS_SIMPLE(type))
                16261     return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
                16262     else
                16263     return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
                16264 }
                16265 
                16266 /**
                16267  * xmlSchemaCheckCOSCTExtends:
                16268  * @ctxt:  the schema parser context
                16269  * @type:  the complex type definition
                16270  *
                16271  * (3.4.6) Constraints on Complex Type Definition Schema Components
                16272  * Schema Component Constraint:
                16273  * Derivation Valid (Extension) (cos-ct-extends)
                16274  *
                16275  * STATUS:
                16276  *   missing:
                16277  *     (1.5)
                16278  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
                16279  *
                16280  * Returns 0 if the constraints are satisfied, a positive
                16281  * error code if not and -1 if an internal error occurred.
                16282  */
                16283 static int
                16284 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
                16285                xmlSchemaTypePtr type)
                16286 {
                16287     xmlSchemaTypePtr base = type->baseType;
                16288     /*
                16289     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
                16290     * temporarily only.
                16291     */
                16292     /*
                16293     * SPEC (1) "If the {base type definition} is a complex type definition,
                16294     * then all of the following must be true:"
                16295     */
                16296     if (WXS_IS_COMPLEX(base)) {
                16297     /*
                16298     * SPEC (1.1) "The {final} of the {base type definition} must not
                16299     * contain extension."
                16300     */
                16301     if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
                16302         xmlSchemaPCustomErr(ctxt,
                16303         XML_SCHEMAP_COS_CT_EXTENDS_1_1,
                16304         WXS_BASIC_CAST type, NULL,
                16305         "The 'final' of the base type definition "
                16306         "contains 'extension'", NULL);
                16307         return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
                16308     }
                16309 
                16310     /*
                16311     * ATTENTION: The constrains (1.2) and (1.3) are not applied,
                16312     * since they are automatically satisfied through the
                16313     * inheriting mechanism.
                16314     * Note that even if redefining components, the inheriting mechanism
                16315     * is used.
                16316     */
                16317 #if 0
                16318     /*
                16319     * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
                16320     * uses}
                16321     * of the complex type definition itself, that is, for every attribute
                16322     * use in the {attribute uses} of the {base type definition}, there
                16323     * must be an attribute use in the {attribute uses} of the complex
                16324     * type definition itself whose {attribute declaration} has the same
                16325     * {name}, {target namespace} and {type definition} as its attribute
                16326     * declaration"
                16327     */
                16328     if (base->attrUses != NULL) {
                16329         int i, j, found;
                16330         xmlSchemaAttributeUsePtr use, buse;
                16331 
                16332         for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
                16333         buse = (WXS_LIST_CAST base->attrUses)->items[i];
                16334         found = 0;
                16335         if (type->attrUses != NULL) {
                16336             use = (WXS_LIST_CAST type->attrUses)->items[j];
                16337             for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
                16338             {
                16339             if ((WXS_ATTRUSE_DECL_NAME(use) ==
                16340                 WXS_ATTRUSE_DECL_NAME(buse)) &&
                16341                 (WXS_ATTRUSE_DECL_TNS(use) ==
                16342                 WXS_ATTRUSE_DECL_TNS(buse)) &&
                16343                 (WXS_ATTRUSE_TYPEDEF(use) ==
                16344                 WXS_ATTRUSE_TYPEDEF(buse))
                16345             {
                16346                 found = 1;
                16347                 break;
                16348             }
                16349             }
                16350         }
                16351         if (! found) {
                16352             xmlChar *str = NULL;
                16353 
                16354             xmlSchemaCustomErr(ACTXT_CAST ctxt,
                16355             XML_SCHEMAP_COS_CT_EXTENDS_1_2,
                16356             NULL, WXS_BASIC_CAST type,
                16357             /*
                16358             * TODO: The report does not indicate that also the
                16359             * type needs to be the same.
                16360             */
                16361             "This type is missing a matching correspondent "
                16362             "for its {base type}'s %s in its {attribute uses}",
                16363             xmlSchemaGetComponentDesignation(&str,
                16364                 buse->children),
                16365             NULL);
                16366             FREE_AND_NULL(str)
                16367         }
                16368         }
                16369     }
                16370     /*
                16371     * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
                16372     * definition must also have one, and the base type definition's
                16373     * {attribute  wildcard}'s {namespace constraint} must be a subset
                16374     * of the complex  type definition's {attribute wildcard}'s {namespace
                16375     * constraint}, as defined by Wildcard Subset ($3.10.6)."
                16376     */
                16377 
                16378     /*
                16379     * MAYBE TODO: Enable if ever needed. But this will be needed only
                16380     * if created the type via a schema construction API.
                16381     */
                16382     if (base->attributeWildcard != NULL) {
                16383         if (type->attributeWildcard == NULL) {
                16384         xmlChar *str = NULL;
                16385 
                16386         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                16387             XML_SCHEMAP_COS_CT_EXTENDS_1_3,
                16388             NULL, type,
                16389             "The base %s has an attribute wildcard, "
                16390             "but this type is missing an attribute wildcard",
                16391             xmlSchemaGetComponentDesignation(&str, base));
                16392         FREE_AND_NULL(str)
                16393 
                16394         } else if (xmlSchemaCheckCOSNSSubset(
                16395         base->attributeWildcard, type->attributeWildcard))
                16396         {
                16397         xmlChar *str = NULL;
                16398 
                16399         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                16400             XML_SCHEMAP_COS_CT_EXTENDS_1_3,
                16401             NULL, type,
                16402             "The attribute wildcard is not a valid "
                16403             "superset of the one in the base %s",
                16404             xmlSchemaGetComponentDesignation(&str, base));
                16405         FREE_AND_NULL(str)
                16406         }
                16407     }
                16408 #endif
                16409     /*
                16410     * SPEC (1.4) "One of the following must be true:"
                16411     */
                16412     if ((type->contentTypeDef != NULL) &&
                16413         (type->contentTypeDef == base->contentTypeDef)) {
                16414         /*
                16415         * SPEC (1.4.1) "The {content type} of the {base type definition}
                16416         * and the {content type} of the complex type definition itself
                16417         * must be the same simple type definition"
                16418         * PASS
                16419         */
                16420     } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
                16421         (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
                16422         /*
                16423         * SPEC (1.4.2) "The {content type} of both the {base type
                16424         * definition} and the complex type definition itself must
                16425         * be empty."
                16426         * PASS
                16427         */
                16428     } else {
                16429         /*
                16430         * SPEC (1.4.3) "All of the following must be true:"
                16431         */
                16432         if (type->subtypes == NULL) {
                16433         /*
                16434         * SPEC 1.4.3.1 The {content type} of the complex type
                16435         * definition itself must specify a particle.
                16436         */
                16437         xmlSchemaPCustomErr(ctxt,
                16438             XML_SCHEMAP_COS_CT_EXTENDS_1_1,
                16439             WXS_BASIC_CAST type, NULL,
                16440             "The content type must specify a particle", NULL);
                16441         return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
                16442         }
                16443         /*
                16444         * SPEC (1.4.3.2) "One of the following must be true:"
                16445         */
                16446         if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
                16447         /*
                16448         * SPEC (1.4.3.2.1) "The {content type} of the {base type
                16449         * definition} must be empty.
                16450         * PASS
                16451         */
                16452         } else {
                16453         /*
                16454         * SPEC (1.4.3.2.2) "All of the following must be true:"
                16455         */
                16456         if ((type->contentType != base->contentType) ||
                16457             ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
                16458             (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
                16459             /*
                16460             * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
                16461             * or both must be element-only."
                16462             */
                16463             xmlSchemaPCustomErr(ctxt,
                16464             XML_SCHEMAP_COS_CT_EXTENDS_1_1,
                16465             WXS_BASIC_CAST type, NULL,
                16466             "The content type of both, the type and its base "
                16467             "type, must either 'mixed' or 'element-only'", NULL);
                16468             return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
                16469         }
                16470         /*
                16471         * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
                16472         * complex type definition must be a `valid extension`
                16473         * of the {base type definition}'s particle, as defined
                16474         * in Particle Valid (Extension) ($3.9.6)."
                16475         *
                16476         * NOTE that we won't check "Particle Valid (Extension)",
                16477         * since it is ensured by the derivation process in
                16478         * xmlSchemaTypeFixup(). We need to implement this when heading
                16479         * for a construction API
                16480         * TODO: !! This is needed to be checked if redefining a type !!
                16481         */
                16482         }
                16483         /*
                16484         * URGENT TODO (1.5)
                16485         */
                16486     }
                16487     } else {
                16488     /*
                16489     * SPEC (2) "If the {base type definition} is a simple type definition,
                16490     * then all of the following must be true:"
                16491     */
                16492     if (type->contentTypeDef != base) {
                16493         /*
                16494         * SPEC (2.1) "The {content type} must be the same simple type
                16495         * definition."
                16496         */
                16497         xmlSchemaPCustomErr(ctxt,
                16498         XML_SCHEMAP_COS_CT_EXTENDS_1_1,
                16499         WXS_BASIC_CAST type, NULL,
                16500         "The content type must be the simple base type", NULL);
                16501         return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
                16502     }
                16503     if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
                16504         /*
                16505         * SPEC (2.2) "The {final} of the {base type definition} must not
                16506         * contain extension"
                16507         * NOTE that this is the same as (1.1).
                16508         */
                16509         xmlSchemaPCustomErr(ctxt,
                16510         XML_SCHEMAP_COS_CT_EXTENDS_1_1,
                16511         WXS_BASIC_CAST type, NULL,
                16512         "The 'final' of the base type definition "
                16513         "contains 'extension'", NULL);
                16514         return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
                16515     }
                16516     }
                16517     return (0);
                16518 }
                16519 
                16520 /**
                16521  * xmlSchemaCheckDerivationOKRestriction:
                16522  * @ctxt:  the schema parser context
                16523  * @type:  the complex type definition
                16524  *
                16525  * (3.4.6) Constraints on Complex Type Definition Schema Components
                16526  * Schema Component Constraint:
                16527  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
                16528  *
                16529  * STATUS:
                16530  *   missing:
                16531  *     (5.4.2) ???
                16532  *
                16533  * ATTENTION:
                16534  * In XML Schema 1.1 this will be:
                16535  * Validation Rule: Checking complex type subsumption
                16536  *
                16537  * Returns 0 if the constraints are satisfied, a positive
                16538  * error code if not and -1 if an internal error occurred.
                16539  */
                16540 static int
                16541 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
                16542                       xmlSchemaTypePtr type)
                16543 {
                16544     xmlSchemaTypePtr base;
                16545 
                16546     /*
                16547     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
                16548     * temporarily only.
                16549     */
                16550     base = type->baseType;
                16551     if (! WXS_IS_COMPLEX(base)) {
                16552     xmlSchemaCustomErr(ACTXT_CAST ctxt,
                16553         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16554         type->node, WXS_BASIC_CAST type,
                16555         "The base type must be a complex type", NULL, NULL);
                16556     return(ctxt->err);
                16557     }
                16558     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
                16559     /*
                16560     * SPEC (1) "The {base type definition} must be a complex type
                16561     * definition whose {final} does not contain restriction."
                16562     */
                16563     xmlSchemaCustomErr(ACTXT_CAST ctxt,
                16564         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16565         type->node, WXS_BASIC_CAST type,
                16566         "The 'final' of the base type definition "
                16567         "contains 'restriction'", NULL, NULL);
                16568     return (ctxt->err);
                16569     }
                16570     /*
                16571     * SPEC (2), (3) and (4)
                16572     * Those are handled in a separate function, since the
                16573     * same constraints are needed for redefinition of
                16574     * attribute groups as well.
                16575     */
                16576     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
                16577     XML_SCHEMA_ACTION_DERIVE,
                16578     WXS_BASIC_CAST type, WXS_BASIC_CAST base,
                16579     type->attrUses, base->attrUses,
                16580     type->attributeWildcard,
                16581     base->attributeWildcard) == -1)
                16582     {
                16583     return(-1);
                16584     }
                16585     /*
                16586     * SPEC (5) "One of the following must be true:"
                16587     */
                16588     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
                16589     /*
                16590     * SPEC (5.1) "The {base type definition} must be the
                16591     * `ur-type definition`."
                16592     * PASS
                16593     */
                16594     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
                16595         (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
                16596     /*
                16597     * SPEC (5.2.1) "The {content type} of the complex type definition
                16598     * must be a simple type definition"
                16599     *
                16600     * SPEC (5.2.2) "One of the following must be true:"
                16601     */
                16602     if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
                16603         (base->contentType == XML_SCHEMA_CONTENT_BASIC))
                16604     {
                16605         int err;
                16606         /*
                16607         * SPEC (5.2.2.1) "The {content type} of the {base type
                16608         * definition} must be a simple type definition from which
                16609         * the {content type} is validly derived given the empty
                16610         * set as defined in Type Derivation OK (Simple) ($3.14.6)."
                16611         *
                16612         * ATTENTION TODO: This seems not needed if the type implicitly
                16613         * derived from the base type.
                16614         *
                16615         */
                16616         err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
                16617         type->contentTypeDef, base->contentTypeDef, 0);
                16618         if (err != 0) {
                16619         xmlChar *strA = NULL, *strB = NULL;
                16620 
                16621         if (err == -1)
                16622             return(-1);
                16623         xmlSchemaCustomErr(ACTXT_CAST ctxt,
                16624             XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16625             NULL, WXS_BASIC_CAST type,
                16626             "The {content type} %s is not validly derived from the "
                16627             "base type's {content type} %s",
                16628             xmlSchemaGetComponentDesignation(&strA,
                16629             type->contentTypeDef),
                16630             xmlSchemaGetComponentDesignation(&strB,
                16631             base->contentTypeDef));
                16632         FREE_AND_NULL(strA);
                16633         FREE_AND_NULL(strB);
                16634         return(ctxt->err);
                16635         }
                16636     } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
                16637         (xmlSchemaIsParticleEmptiable(
                16638         (xmlSchemaParticlePtr) base->subtypes))) {
                16639         /*
                16640         * SPEC (5.2.2.2) "The {base type definition} must be mixed
                16641         * and have a particle which is `emptiable` as defined in
                16642         * Particle Emptiable ($3.9.6)."
                16643         * PASS
                16644         */
                16645     } else {
                16646         xmlSchemaPCustomErr(ctxt,
                16647         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16648         WXS_BASIC_CAST type, NULL,
                16649         "The content type of the base type must be either "
                16650         "a simple type or 'mixed' and an emptiable particle", NULL);
                16651         return (ctxt->err);
                16652     }
                16653     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
                16654     /*
                16655     * SPEC (5.3.1) "The {content type} of the complex type itself must
                16656     * be empty"
                16657     */
                16658     if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
                16659         /*
                16660         * SPEC (5.3.2.1) "The {content type} of the {base type
                16661         * definition} must also be empty."
                16662         * PASS
                16663         */
                16664     } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
                16665         (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
                16666         xmlSchemaIsParticleEmptiable(
                16667         (xmlSchemaParticlePtr) base->subtypes)) {
                16668         /*
                16669         * SPEC (5.3.2.2) "The {content type} of the {base type
                16670         * definition} must be elementOnly or mixed and have a particle
                16671         * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
                16672         * PASS
                16673         */
                16674     } else {
                16675         xmlSchemaPCustomErr(ctxt,
                16676         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16677         WXS_BASIC_CAST type, NULL,
                16678         "The content type of the base type must be either "
                16679         "empty or 'mixed' (or 'elements-only') and an emptiable "
                16680         "particle", NULL);
                16681         return (ctxt->err);
                16682     }
                16683     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
                16684     WXS_HAS_MIXED_CONTENT(type)) {
                16685     /*
                16686     * SPEC (5.4.1.1) "The {content type} of the complex type definition
                16687     * itself must be element-only"
                16688     */
                16689     if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
                16690         /*
                16691         * SPEC (5.4.1.2) "The {content type} of the complex type
                16692         * definition itself and of the {base type definition} must be
                16693         * mixed"
                16694         */
                16695         xmlSchemaPCustomErr(ctxt,
                16696         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16697         WXS_BASIC_CAST type, NULL,
                16698         "If the content type is 'mixed', then the content type of the "
                16699         "base type must also be 'mixed'", NULL);
                16700         return (ctxt->err);
                16701     }
                16702     /*
                16703     * SPEC (5.4.2) "The particle of the complex type definition itself
                16704     * must be a `valid restriction` of the particle of the {content
                16705     * type} of the {base type definition} as defined in Particle Valid
                16706     * (Restriction) ($3.9.6).
                16707     *
                16708     * URGENT TODO: (5.4.2)
                16709     */
                16710     } else {
                16711     xmlSchemaPCustomErr(ctxt,
                16712         XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
                16713         WXS_BASIC_CAST type, NULL,
                16714         "The type is not a valid restriction of its base type", NULL);
                16715     return (ctxt->err);
                16716     }
                16717     return (0);
                16718 }
                16719 
                16720 /**
                16721  * xmlSchemaCheckCTComponent:
                16722  * @ctxt:  the schema parser context
                16723  * @type:  the complex type definition
                16724  *
                16725  * (3.4.6) Constraints on Complex Type Definition Schema Components
                16726  *
                16727  * Returns 0 if the constraints are satisfied, a positive
                16728  * error code if not and -1 if an internal error occurred.
                16729  */
                16730 static int
                16731 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
                16732               xmlSchemaTypePtr type)
                16733 {
                16734     int ret;
                16735     /*
                16736     * Complex Type Definition Properties Correct
                16737     */
                16738     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
                16739     if (ret != 0)
                16740     return (ret);
                16741     if (WXS_IS_EXTENSION(type))
                16742     ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
                16743     else
                16744     ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
                16745     return (ret);
                16746 }
                16747 
                16748 /**
                16749  * xmlSchemaCheckSRCCT:
                16750  * @ctxt:  the schema parser context
                16751  * @type:  the complex type definition
                16752  *
                16753  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
                16754  * Schema Representation Constraint:
                16755  * Complex Type Definition Representation OK (src-ct)
                16756  *
                16757  * Returns 0 if the constraints are satisfied, a positive
                16758  * error code if not and -1 if an internal error occurred.
                16759  */
                16760 static int
                16761 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
                16762             xmlSchemaTypePtr type)
                16763 {
                16764     xmlSchemaTypePtr base;
                16765     int ret = 0;
                16766 
                16767     /*
                16768     * TODO: Adjust the error codes here, as I used
                16769     * XML_SCHEMAP_SRC_CT_1 only yet.
                16770     */
                16771     base = type->baseType;
                16772     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
                16773     /*
                16774     * 1 If the <complexContent> alternative is chosen, the type definition
                16775     * `resolved` to by the `actual value` of the base [attribute]
                16776     * must be a complex type definition;
                16777     */
                16778     if (! WXS_IS_COMPLEX(base)) {
                16779         xmlChar *str = NULL;
                16780         xmlSchemaPCustomErr(ctxt,
                16781         XML_SCHEMAP_SRC_CT_1,
                16782         WXS_BASIC_CAST type, type->node,
                16783         "If using <complexContent>, the base type is expected to be "
                16784         "a complex type. The base type '%s' is a simple type",
                16785         xmlSchemaFormatQName(&str, base->targetNamespace,
                16786         base->name));
                16787         FREE_AND_NULL(str)
                16788         return (XML_SCHEMAP_SRC_CT_1);
                16789     }
                16790     } else {
                16791     /*
                16792     * SPEC
                16793     * 2 If the <simpleContent> alternative is chosen, all of the
                16794     * following must be true:
                16795     * 2.1 The type definition `resolved` to by the `actual value` of the
                16796     * base [attribute] must be one of the following:
                16797     */
                16798     if (WXS_IS_SIMPLE(base)) {
                16799         if (WXS_IS_EXTENSION(type) == 0) {
                16800         xmlChar *str = NULL;
                16801         /*
                16802         * 2.1.3 only if the <extension> alternative is also
                16803         * chosen, a simple type definition.
                16804         */
                16805         /* TODO: Change error code to ..._SRC_CT_2_1_3. */
                16806         xmlSchemaPCustomErr(ctxt,
                16807             XML_SCHEMAP_SRC_CT_1,
                16808             WXS_BASIC_CAST type, NULL,
                16809             "If using <simpleContent> and <restriction>, the base "
                16810             "type must be a complex type. The base type '%s' is "
                16811             "a simple type",
                16812             xmlSchemaFormatQName(&str, base->targetNamespace,
                16813             base->name));
                16814         FREE_AND_NULL(str)
                16815         return (XML_SCHEMAP_SRC_CT_1);
                16816         }
                16817     } else {
                16818         /* Base type is a complex type. */
                16819         if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
                16820         (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
                16821         /*
                16822         * 2.1.1 a complex type definition whose {content type} is a
                16823         * simple type definition;
                16824         * PASS
                16825         */
                16826         if (base->contentTypeDef == NULL) {
                16827             xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
                16828             WXS_BASIC_CAST type, NULL,
                16829             "Internal error: xmlSchemaCheckSRCCT, "
                16830             "'%s', base type has no content type",
                16831             type->name);
                16832             return (-1);
                16833         }
                16834         } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
                16835         (WXS_IS_RESTRICTION(type))) {
                16836 
                16837         /*
                16838         * 2.1.2 only if the <restriction> alternative is also
                16839         * chosen, a complex type definition whose {content type}
                16840         * is mixed and a particle emptiable.
                16841         */
                16842         if (! xmlSchemaIsParticleEmptiable(
                16843             (xmlSchemaParticlePtr) base->subtypes)) {
                16844             ret = XML_SCHEMAP_SRC_CT_1;
                16845         } else
                16846             /*
                16847             * Attention: at this point the <simpleType> child is in
                16848             * ->contentTypeDef (put there during parsing).
                16849             */
                16850             if (type->contentTypeDef == NULL) {
                16851             xmlChar *str = NULL;
                16852             /*
                16853             * 2.2 If clause 2.1.2 above is satisfied, then there
                16854             * must be a <simpleType> among the [children] of
                16855             * <restriction>.
                16856             */
                16857             /* TODO: Change error code to ..._SRC_CT_2_2. */
                16858             xmlSchemaPCustomErr(ctxt,
                16859             XML_SCHEMAP_SRC_CT_1,
                16860             WXS_BASIC_CAST type, NULL,
                16861             "A <simpleType> is expected among the children "
                16862             "of <restriction>, if <simpleContent> is used and "
                16863             "the base type '%s' is a complex type",
                16864             xmlSchemaFormatQName(&str, base->targetNamespace,
                16865             base->name));
                16866             FREE_AND_NULL(str)
                16867             return (XML_SCHEMAP_SRC_CT_1);
                16868         }
                16869         } else {
                16870         ret = XML_SCHEMAP_SRC_CT_1;
                16871         }
                16872     }
                16873     if (ret > 0) {
                16874         xmlChar *str = NULL;
                16875         if (WXS_IS_RESTRICTION(type)) {
                16876         xmlSchemaPCustomErr(ctxt,
                16877             XML_SCHEMAP_SRC_CT_1,
                16878             WXS_BASIC_CAST type, NULL,
                16879             "If <simpleContent> and <restriction> is used, the "
                16880             "base type must be a simple type or a complex type with "
                16881             "mixed content and particle emptiable. The base type "
                16882             "'%s' is none of those",
                16883             xmlSchemaFormatQName(&str, base->targetNamespace,
                16884             base->name));
                16885         } else {
                16886         xmlSchemaPCustomErr(ctxt,
                16887             XML_SCHEMAP_SRC_CT_1,
                16888             WXS_BASIC_CAST type, NULL,
                16889             "If <simpleContent> and <extension> is used, the "
                16890             "base type must be a simple type. The base type '%s' "
                16891             "is a complex type",
                16892             xmlSchemaFormatQName(&str, base->targetNamespace,
                16893             base->name));
                16894         }
                16895         FREE_AND_NULL(str)
                16896     }
                16897     }
                16898     /*
                16899     * SPEC (3) "The corresponding complex type definition component must
                16900     * satisfy the conditions set out in Constraints on Complex Type
                16901     * Definition Schema Components ($3.4.6);"
                16902     * NOTE (3) will be done in xmlSchemaTypeFixup().
                16903     */
                16904     /*
                16905     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
                16906     * above for {attribute wildcard} is satisfied, the intensional
                16907     * intersection must be expressible, as defined in Attribute Wildcard
                16908     * Intersection ($3.10.6).
                16909     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
                16910     */
                16911     return (ret);
                16912 }
                16913 
                16914 #ifdef ENABLE_PARTICLE_RESTRICTION
                16915 /**
                16916  * xmlSchemaCheckParticleRangeOK:
                16917  * @ctxt:  the schema parser context
                16918  * @type:  the complex type definition
                16919  *
                16920  * (3.9.6) Constraints on Particle Schema Components
                16921  * Schema Component Constraint:
                16922  * Occurrence Range OK (range-ok)
                16923  *
                16924  * STATUS: complete
                16925  *
                16926  * Returns 0 if the constraints are satisfied, a positive
                16927  * error code if not and -1 if an internal error occurred.
                16928  */
                16929 static int
                16930 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
                16931                   int bmin, int bmax)
                16932 {
                16933     if (rmin < bmin)
                16934     return (1);
                16935     if ((bmax != UNBOUNDED) &&
                16936     (rmax > bmax))
                16937     return (1);
                16938     return (0);
                16939 }
                16940 
                16941 /**
                16942  * xmlSchemaCheckRCaseNameAndTypeOK:
                16943  * @ctxt:  the schema parser context
                16944  * @r: the restricting element declaration particle
                16945  * @b: the base element declaration particle
                16946  *
                16947  * (3.9.6) Constraints on Particle Schema Components
                16948  * Schema Component Constraint:
                16949  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
                16950  * (rcase-NameAndTypeOK)
                16951  *
                16952  * STATUS:
                16953  *   MISSING (3.2.3)
                16954  *   CLARIFY: (3.2.2)
                16955  *
                16956  * Returns 0 if the constraints are satisfied, a positive
                16957  * error code if not and -1 if an internal error occurred.
                16958  */
                16959 static int
                16960 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
                16961                  xmlSchemaParticlePtr r,
                16962                  xmlSchemaParticlePtr b)
                16963 {
                16964     xmlSchemaElementPtr elemR, elemB;
                16965 
                16966     /* TODO: Error codes (rcase-NameAndTypeOK). */
                16967     elemR = (xmlSchemaElementPtr) r->children;
                16968     elemB = (xmlSchemaElementPtr) b->children;
                16969     /*
                16970     * SPEC (1) "The declarations' {name}s and {target namespace}s are
                16971     * the same."
                16972     */
                16973     if ((elemR != elemB) &&
                16974     ((! xmlStrEqual(elemR->name, elemB->name)) ||
                16975     (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
                16976     return (1);
                16977     /*
                16978     * SPEC (2) "R's occurrence range is a valid restriction of B's
                16979     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
                16980     */
                16981     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
                16982         b->minOccurs, b->maxOccurs) != 0)
                16983     return (1);
                16984     /*
                16985     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
                16986     * {scope} are global."
                16987     */
                16988     if (elemR == elemB)
                16989     return (0);
                16990     /*
                16991     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
                16992     */
                16993     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
                16994     (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
                16995      return (1);
                16996     /*
                16997     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
                16998     * or is not fixed, or R's declaration's {value constraint} is fixed
                16999     * with the same value."
                17000     */
                17001     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
                17002     ((elemR->value == NULL) ||
                17003      ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
                17004      /* TODO: Equality of the initial value or normalized or canonical? */
                17005      (! xmlStrEqual(elemR->value, elemB->value))))
                17006      return (1);
                17007     /*
                17008     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
                17009     * definitions} is a subset of B's declaration's {identity-constraint
                17010     * definitions}, if any."
                17011     */
                17012     if (elemB->idcs != NULL) {
                17013     /* TODO */
                17014     }
                17015     /*
                17016     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
                17017     * superset of B's declaration's {disallowed substitutions}."
                17018     */
                17019     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
                17020      ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
                17021     ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
                17022      ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
                17023     ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
                17024      ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
                17025      return (1);
                17026     /*
                17027     * SPEC (3.2.5) "R's {type definition} is validly derived given
                17028     * {extension, list, union} from B's {type definition}"
                17029     *
                17030     * BADSPEC TODO: What's the point of adding "list" and "union" to the
                17031     * set, if the corresponding constraints handle "restriction" and
                17032     * "extension" only?
                17033     *
                17034     */
                17035     {
                17036     int set = 0;
                17037 
                17038     set |= SUBSET_EXTENSION;
                17039     set |= SUBSET_LIST;
                17040     set |= SUBSET_UNION;
                17041     if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
                17042         elemB->subtypes, set) != 0)
                17043         return (1);
                17044     }
                17045     return (0);
                17046 }
                17047 
                17048 /**
                17049  * xmlSchemaCheckRCaseNSCompat:
                17050  * @ctxt:  the schema parser context
                17051  * @r: the restricting element declaration particle
                17052  * @b: the base wildcard particle
                17053  *
                17054  * (3.9.6) Constraints on Particle Schema Components
                17055  * Schema Component Constraint:
                17056  * Particle Derivation OK (Elt:Any -- NSCompat)
                17057  * (rcase-NSCompat)
                17058  *
                17059  * STATUS: complete
                17060  *
                17061  * Returns 0 if the constraints are satisfied, a positive
                17062  * error code if not and -1 if an internal error occurred.
                17063  */
                17064 static int
                17065 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
                17066                 xmlSchemaParticlePtr r,
                17067                 xmlSchemaParticlePtr b)
                17068 {
                17069     /* TODO:Error codes (rcase-NSCompat). */
                17070     /*
                17071     * SPEC "For an element declaration particle to be a `valid restriction`
                17072     * of a wildcard particle all of the following must be true:"
                17073     *
                17074     * SPEC (1) "The element declaration's {target namespace} is `valid`
                17075     * with respect to the wildcard's {namespace constraint} as defined by
                17076     * Wildcard allows Namespace Name ($3.10.4)."
                17077     */
                17078     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
                17079     ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
                17080     return (1);
                17081     /*
                17082     * SPEC (2) "R's occurrence range is a valid restriction of B's
                17083     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
                17084     */
                17085     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
                17086         b->minOccurs, b->maxOccurs) != 0)
                17087     return (1);
                17088 
                17089     return (0);
                17090 }
                17091 
                17092 /**
                17093  * xmlSchemaCheckRCaseRecurseAsIfGroup:
                17094  * @ctxt:  the schema parser context
                17095  * @r: the restricting element declaration particle
                17096  * @b: the base model group particle
                17097  *
                17098  * (3.9.6) Constraints on Particle Schema Components
                17099  * Schema Component Constraint:
                17100  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
                17101  * (rcase-RecurseAsIfGroup)
                17102  *
                17103  * STATUS: TODO
                17104  *
                17105  * Returns 0 if the constraints are satisfied, a positive
                17106  * error code if not and -1 if an internal error occurred.
                17107  */
                17108 static int
                17109 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
                17110                     xmlSchemaParticlePtr r,
                17111                     xmlSchemaParticlePtr b)
                17112 {
                17113     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
                17114     TODO
                17115     return (0);
                17116 }
                17117 
                17118 /**
                17119  * xmlSchemaCheckRCaseNSSubset:
                17120  * @ctxt:  the schema parser context
                17121  * @r: the restricting wildcard particle
                17122  * @b: the base wildcard particle
                17123  *
                17124  * (3.9.6) Constraints on Particle Schema Components
                17125  * Schema Component Constraint:
                17126  * Particle Derivation OK (Any:Any -- NSSubset)
                17127  * (rcase-NSSubset)
                17128  *
                17129  * STATUS: complete
                17130  *
                17131  * Returns 0 if the constraints are satisfied, a positive
                17132  * error code if not and -1 if an internal error occurred.
                17133  */
                17134 static int
                17135 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
                17136                     xmlSchemaParticlePtr r,
                17137                     xmlSchemaParticlePtr b,
                17138                     int isAnyTypeBase)
                17139 {
                17140     /* TODO: Error codes (rcase-NSSubset). */
                17141     /*
                17142     * SPEC (1) "R's occurrence range is a valid restriction of B's
                17143     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
                17144     */
                17145     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
                17146         b->minOccurs, b->maxOccurs))
                17147     return (1);
                17148     /*
                17149     * SPEC (2) "R's {namespace constraint} must be an intensional subset
                17150     * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
                17151     */
                17152     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
                17153     (xmlSchemaWildcardPtr) b->children))
                17154     return (1);
                17155     /*
                17156     * SPEC (3) "Unless B is the content model wildcard of the `ur-type
                17157     * definition`, R's {process contents} must be identical to or stronger
                17158     * than B's {process contents}, where strict is stronger than lax is
                17159     * stronger than skip."
                17160     */
                17161     if (! isAnyTypeBase) {
                17162     if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
                17163         ((xmlSchemaWildcardPtr) b->children)->processContents)
                17164         return (1);
                17165     }
                17166 
                17167     return (0);
                17168 }
                17169 
                17170 /**
                17171  * xmlSchemaCheckCOSParticleRestrict:
                17172  * @ctxt:  the schema parser context
                17173  * @type:  the complex type definition
                17174  *
                17175  * (3.9.6) Constraints on Particle Schema Components
                17176  * Schema Component Constraint:
                17177  * Particle Valid (Restriction) (cos-particle-restrict)
                17178  *
                17179  * STATUS: TODO
                17180  *
                17181  * Returns 0 if the constraints are satisfied, a positive
                17182  * error code if not and -1 if an internal error occurred.
                17183  */
                17184 static int
                17185 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
                17186                   xmlSchemaParticlePtr r,
                17187                   xmlSchemaParticlePtr b)
                17188 {
                17189     int ret = 0;
                17190 
                17191     /*part = WXS_TYPE_PARTICLE(type);
                17192     basePart = WXS_TYPE_PARTICLE(base);
                17193     */
                17194 
                17195     TODO
                17196 
                17197     /*
                17198     * SPEC (1) "They are the same particle."
                17199     */
                17200     if (r == b)
                17201     return (0);
                17202 
                17203 
                17204     return (0);
                17205 }
                17206 
                17207 #if 0
                17208 /**
                17209  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
                17210  * @ctxt:  the schema parser context
                17211  * @r: the model group particle
                17212  * @b: the base wildcard particle
                17213  *
                17214  * (3.9.6) Constraints on Particle Schema Components
                17215  * Schema Component Constraint:
                17216  * Particle Derivation OK (All/Choice/Sequence:Any --
                17217  *                         NSRecurseCheckCardinality)
                17218  * (rcase-NSRecurseCheckCardinality)
                17219  *
                17220  * STATUS: TODO: subst-groups
                17221  *
                17222  * Returns 0 if the constraints are satisfied, a positive
                17223  * error code if not and -1 if an internal error occurred.
                17224  */
                17225 static int
                17226 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
                17227                          xmlSchemaParticlePtr r,
                17228                          xmlSchemaParticlePtr b)
                17229 {
                17230     xmlSchemaParticlePtr part;
                17231     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
                17232     if ((r->children == NULL) || (r->children->children == NULL))
                17233     return (-1);
                17234     /*
                17235     * SPEC "For a group particle to be a `valid restriction` of a
                17236     * wildcard particle..."
                17237     *
                17238     * SPEC (1) "Every member of the {particles} of the group is a `valid
                17239     * restriction` of the wildcard as defined by
                17240     * Particle Valid (Restriction) ($3.9.6)."
                17241     */
                17242     part = (xmlSchemaParticlePtr) r->children->children;
                17243     do {
                17244     if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
                17245         return (1);
                17246     part = (xmlSchemaParticlePtr) part->next;
                17247     } while (part != NULL);
                17248     /*
                17249     * SPEC (2) "The effective total range of the group [...] is a
                17250     * valid restriction of B's occurrence range as defined by
                17251     * Occurrence Range OK ($3.9.6)."
                17252     */
                17253     if (xmlSchemaCheckParticleRangeOK(
                17254         xmlSchemaGetParticleTotalRangeMin(r),
                17255         xmlSchemaGetParticleTotalRangeMax(r),
                17256         b->minOccurs, b->maxOccurs) != 0)
                17257     return (1);
                17258     return (0);
                17259 }
                17260 #endif
                17261 
                17262 /**
                17263  * xmlSchemaCheckRCaseRecurse:
                17264  * @ctxt:  the schema parser context
                17265  * @r: the <all> or <sequence> model group particle
                17266  * @b: the base <all> or <sequence> model group particle
                17267  *
                17268  * (3.9.6) Constraints on Particle Schema Components
                17269  * Schema Component Constraint:
                17270  * Particle Derivation OK (All:All,Sequence:Sequence --
                17271                            Recurse)
                17272  * (rcase-Recurse)
                17273  *
                17274  * STATUS:  ?
                17275  * TODO: subst-groups
                17276  *
                17277  * Returns 0 if the constraints are satisfied, a positive
                17278  * error code if not and -1 if an internal error occurred.
                17279  */
                17280 static int
                17281 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
                17282                xmlSchemaParticlePtr r,
                17283                xmlSchemaParticlePtr b)
                17284 {
                17285     /* xmlSchemaParticlePtr part; */
                17286     /* TODO: Error codes (rcase-Recurse). */
                17287     if ((r->children == NULL) || (b->children == NULL) ||
                17288     (r->children->type != b->children->type))
                17289     return (-1);
                17290     /*
                17291     * SPEC "For an all or sequence group particle to be a `valid
                17292     * restriction` of another group particle with the same {compositor}..."
                17293     *
                17294     * SPEC (1) "R's occurrence range is a valid restriction of B's
                17295     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
                17296     */
                17297     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
                17298         b->minOccurs, b->maxOccurs))
                17299     return (1);
                17300 
                17301 
                17302     return (0);
                17303 }
                17304 
                17305 #endif
                17306 
                17307 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
                17308     xmlSchemaPCustomErrExt(pctxt,      \
                17309     XML_SCHEMAP_INVALID_FACET_VALUE, \
                17310     WXS_BASIC_CAST fac1, fac1->node, \
                17311     "It is an error for both '%s' and '%s' to be specified on the "\
                17312     "same type definition", \
                17313     BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
                17314     BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
                17315 
                17316 #define FACET_RESTR_ERR(fac1, msg) \
                17317     xmlSchemaPCustomErr(pctxt,      \
                17318     XML_SCHEMAP_INVALID_FACET_VALUE, \
                17319     WXS_BASIC_CAST fac1, fac1->node, \
                17320     msg, NULL);
                17321 
                17322 #define FACET_RESTR_FIXED_ERR(fac) \
                17323     xmlSchemaPCustomErr(pctxt, \
                17324     XML_SCHEMAP_INVALID_FACET_VALUE, \
                17325     WXS_BASIC_CAST fac, fac->node, \
                17326     "The base type's facet is 'fixed', thus the value must not " \
                17327     "differ", NULL);
                17328 
                17329 static void
                17330 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
                17331             xmlSchemaFacetPtr facet1,
                17332             xmlSchemaFacetPtr facet2,
                17333             int lessGreater,
                17334             int orEqual,
                17335             int ofBase)
                17336 {
                17337     xmlChar *msg = NULL;
                17338 
                17339     msg = xmlStrdup(BAD_CAST "'");
                17340     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
                17341     msg = xmlStrcat(msg, BAD_CAST "' has to be");
                17342     if (lessGreater == 0)
                17343     msg = xmlStrcat(msg, BAD_CAST " equal to");
                17344     if (lessGreater == 1)
                17345     msg = xmlStrcat(msg, BAD_CAST " greater than");
                17346     else
                17347     msg = xmlStrcat(msg, BAD_CAST " less than");
                17348 
                17349     if (orEqual)
                17350     msg = xmlStrcat(msg, BAD_CAST " or equal to");
                17351     msg = xmlStrcat(msg, BAD_CAST " '");
                17352     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
                17353     if (ofBase)
                17354     msg = xmlStrcat(msg, BAD_CAST "' of the base type");
                17355     else
                17356     msg = xmlStrcat(msg, BAD_CAST "'");
                17357 
                17358     xmlSchemaPCustomErr(pctxt,
                17359     XML_SCHEMAP_INVALID_FACET_VALUE,
                17360     WXS_BASIC_CAST facet1, NULL,
                17361     (const char *) msg, NULL);
                17362 
                17363     if (msg != NULL)
                17364     xmlFree(msg);
                17365 }
                17366 
                17367 /*
                17368 * xmlSchemaDeriveAndValidateFacets:
                17369 *
                17370 * Schema Component Constraint: Simple Type Restriction (Facets)
                17371 * (st-restrict-facets)
                17372 */
                17373 static int
                17374 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
                17375                  xmlSchemaTypePtr type)
                17376 {
                17377     xmlSchemaTypePtr base = type->baseType;
                17378     xmlSchemaFacetLinkPtr link, cur, last = NULL;
                17379     xmlSchemaFacetPtr facet, bfacet,
                17380     flength = NULL, ftotdig = NULL, ffracdig = NULL,
                17381     fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
                17382     fmininc = NULL, fmaxinc = NULL,
                17383     fminexc = NULL, fmaxexc = NULL,
                17384     bflength = NULL, bftotdig = NULL, bffracdig = NULL,
                17385     bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
                17386     bfmininc = NULL, bfmaxinc = NULL,
                17387     bfminexc = NULL, bfmaxexc = NULL;
                17388     int res; /* err = 0, fixedErr; */
                17389 
                17390     /*
                17391     * SPEC st-restrict-facets 1:
                17392     * "The {variety} of R is the same as that of B."
                17393     */
                17394     /*
                17395     * SPEC st-restrict-facets 2:
                17396     * "If {variety} is atomic, the {primitive type definition}
                17397     * of R is the same as that of B."
                17398     *
                17399     * NOTE: we leave 1 & 2 out for now, since this will be
                17400     * satisfied by the derivation process.
                17401     * CONSTRUCTION TODO: Maybe needed if using a construction API.
                17402     */
                17403     /*
                17404     * SPEC st-restrict-facets 3:
                17405     * "The {facets} of R are the union of S and the {facets}
                17406     * of B, eliminating duplicates. To eliminate duplicates,
                17407     * when a facet of the same kind occurs in both S and the
                17408     * {facets} of B, the one in the {facets} of B is not
                17409     * included, with the exception of enumeration and pattern
                17410     * facets, for which multiple occurrences with distinct values
                17411     * are allowed."
                17412     */
                17413 
                17414     if ((type->facetSet == NULL) && (base->facetSet == NULL))
                17415     return (0);
                17416 
                17417     last = type->facetSet;
                17418     if (last != NULL)
                17419     while (last->next != NULL)
                17420         last = last->next;
                17421 
                17422     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
                17423     facet = cur->facet;
                17424     switch (facet->type) {
                17425         case XML_SCHEMA_FACET_LENGTH:
                17426         flength = facet; break;
                17427         case XML_SCHEMA_FACET_MINLENGTH:
                17428         fminlen = facet; break;
                17429         case XML_SCHEMA_FACET_MININCLUSIVE:
                17430         fmininc = facet; break;
                17431         case XML_SCHEMA_FACET_MINEXCLUSIVE:
                17432         fminexc = facet; break;
                17433         case XML_SCHEMA_FACET_MAXLENGTH:
                17434         fmaxlen = facet; break;
                17435         case XML_SCHEMA_FACET_MAXINCLUSIVE:
                17436         fmaxinc = facet; break;
                17437         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
                17438         fmaxexc = facet; break;
                17439         case XML_SCHEMA_FACET_TOTALDIGITS:
                17440         ftotdig = facet; break;
                17441         case XML_SCHEMA_FACET_FRACTIONDIGITS:
                17442         ffracdig = facet; break;
                17443         default:
                17444         break;
                17445     }
                17446     }
                17447     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
                17448     facet = cur->facet;
                17449     switch (facet->type) {
                17450         case XML_SCHEMA_FACET_LENGTH:
                17451         bflength = facet; break;
                17452         case XML_SCHEMA_FACET_MINLENGTH:
                17453         bfminlen = facet; break;
                17454         case XML_SCHEMA_FACET_MININCLUSIVE:
                17455         bfmininc = facet; break;
                17456         case XML_SCHEMA_FACET_MINEXCLUSIVE:
                17457         bfminexc = facet; break;
                17458         case XML_SCHEMA_FACET_MAXLENGTH:
                17459         bfmaxlen = facet; break;
                17460         case XML_SCHEMA_FACET_MAXINCLUSIVE:
                17461         bfmaxinc = facet; break;
                17462         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
                17463         bfmaxexc = facet; break;
                17464         case XML_SCHEMA_FACET_TOTALDIGITS:
                17465         bftotdig = facet; break;
                17466         case XML_SCHEMA_FACET_FRACTIONDIGITS:
                17467         bffracdig = facet; break;
                17468         default:
                17469         break;
                17470     }
                17471     }
                17472     /*
                17473     * length and minLength or maxLength (2.2) + (3.2)
                17474     */
                17475     if (flength && (fminlen || fmaxlen)) {
                17476     FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
                17477         "either of 'minLength' or 'maxLength' to be specified on "
                17478         "the same type definition")
                17479     }
                17480     /*
                17481     * Mutual exclusions in the same derivation step.
                17482     */
                17483     if ((fmaxinc) && (fmaxexc)) {
                17484     /*
                17485     * SCC "maxInclusive and maxExclusive"
                17486     */
                17487     FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
                17488     }
                17489     if ((fmininc) && (fminexc)) {
                17490     /*
                17491     * SCC "minInclusive and minExclusive"
                17492     */
                17493     FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
                17494     }
                17495 
                17496     if (flength && bflength) {
                17497     /*
                17498     * SCC "length valid restriction"
                17499     * The values have to be equal.
                17500     */
                17501     res = xmlSchemaCompareValues(flength->val, bflength->val);
                17502     if (res == -2)
                17503         goto internal_error;
                17504     if (res != 0)
                17505         xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
                17506     if ((res != 0) && (bflength->fixed)) {
                17507         FACET_RESTR_FIXED_ERR(flength)
                17508     }
                17509 
                17510     }
                17511     if (fminlen && bfminlen) {
                17512     /*
                17513     * SCC "minLength valid restriction"
                17514     * minLength >= BASE minLength
                17515     */
                17516     res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
                17517     if (res == -2)
                17518         goto internal_error;
                17519     if (res == -1)
                17520         xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
                17521     if ((res != 0) && (bfminlen->fixed)) {
                17522         FACET_RESTR_FIXED_ERR(fminlen)
                17523     }
                17524     }
                17525     if (fmaxlen && bfmaxlen) {
                17526     /*
                17527     * SCC "maxLength valid restriction"
                17528     * maxLength <= BASE minLength
                17529     */
                17530     res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
                17531     if (res == -2)
                17532         goto internal_error;
                17533     if (res == 1)
                17534         xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
                17535     if ((res != 0) && (bfmaxlen->fixed)) {
                17536         FACET_RESTR_FIXED_ERR(fmaxlen)
                17537     }
                17538     }
                17539     /*
                17540     * SCC "length and minLength or maxLength"
                17541     */
                17542     if (! flength)
                17543     flength = bflength;
                17544     if (flength) {
                17545     if (! fminlen)
                17546         fminlen = bfminlen;
                17547     if (fminlen) {
                17548         /* (1.1) length >= minLength */
                17549         res = xmlSchemaCompareValues(flength->val, fminlen->val);
                17550         if (res == -2)
                17551         goto internal_error;
                17552         if (res == -1)
                17553         xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
                17554     }
                17555     if (! fmaxlen)
                17556         fmaxlen = bfmaxlen;
                17557     if (fmaxlen) {
                17558         /* (2.1) length <= maxLength */
                17559         res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
                17560         if (res == -2)
                17561         goto internal_error;
                17562         if (res == 1)
                17563         xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
                17564     }
                17565     }
                17566     if (fmaxinc) {
                17567     /*
                17568     * "maxInclusive"
                17569     */
                17570     if (fmininc) {
                17571         /* SCC "maxInclusive >= minInclusive" */
                17572         res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
                17573         if (res == -2)
                17574         goto internal_error;
                17575         if (res == -1) {
                17576         xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
                17577         }
                17578     }
                17579     /*
                17580     * SCC "maxInclusive valid restriction"
                17581     */
                17582     if (bfmaxinc) {
                17583         /* maxInclusive <= BASE maxInclusive */
                17584         res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
                17585         if (res == -2)
                17586         goto internal_error;
                17587         if (res == 1)
                17588         xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
                17589         if ((res != 0) && (bfmaxinc->fixed)) {
                17590         FACET_RESTR_FIXED_ERR(fmaxinc)
                17591         }
                17592     }
                17593     if (bfmaxexc) {
                17594         /* maxInclusive < BASE maxExclusive */
                17595         res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
                17596         if (res == -2)
                17597         goto internal_error;
                17598         if (res != -1) {
                17599         xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
                17600         }
                17601     }
                17602     if (bfmininc) {
                17603         /* maxInclusive >= BASE minInclusive */
                17604         res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
                17605         if (res == -2)
                17606         goto internal_error;
                17607         if (res == -1) {
                17608         xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
                17609         }
                17610     }
                17611     if (bfminexc) {
                17612         /* maxInclusive > BASE minExclusive */
                17613         res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
                17614         if (res == -2)
                17615         goto internal_error;
                17616         if (res != 1) {
                17617         xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
                17618         }
                17619     }
                17620     }
                17621     if (fmaxexc) {
                17622     /*
                17623     * "maxExclusive >= minExclusive"
                17624     */
                17625     if (fminexc) {
                17626         res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
                17627         if (res == -2)
                17628         goto internal_error;
                17629         if (res == -1) {
                17630         xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
                17631         }
                17632     }
                17633     /*
                17634     * "maxExclusive valid restriction"
                17635     */
                17636     if (bfmaxexc) {
                17637         /* maxExclusive <= BASE maxExclusive */
                17638         res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
                17639         if (res == -2)
                17640         goto internal_error;
                17641         if (res == 1) {
                17642         xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
                17643         }
                17644         if ((res != 0) && (bfmaxexc->fixed)) {
                17645         FACET_RESTR_FIXED_ERR(fmaxexc)
                17646         }
                17647     }
                17648     if (bfmaxinc) {
                17649         /* maxExclusive <= BASE maxInclusive */
                17650         res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
                17651         if (res == -2)
                17652         goto internal_error;
                17653         if (res == 1) {
                17654         xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
                17655         }
                17656     }
                17657     if (bfmininc) {
                17658         /* maxExclusive > BASE minInclusive */
                17659         res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
                17660         if (res == -2)
                17661         goto internal_error;
                17662         if (res != 1) {
                17663         xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
                17664         }
                17665     }
                17666     if (bfminexc) {
                17667         /* maxExclusive > BASE minExclusive */
                17668         res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
                17669         if (res == -2)
                17670         goto internal_error;
                17671         if (res != 1) {
                17672         xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
                17673         }
                17674     }
                17675     }
                17676     if (fminexc) {
                17677     /*
                17678     * "minExclusive < maxInclusive"
                17679     */
                17680     if (fmaxinc) {
                17681         res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
                17682         if (res == -2)
                17683         goto internal_error;
                17684         if (res != -1) {
                17685         xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
                17686         }
                17687     }
                17688     /*
                17689     * "minExclusive valid restriction"
                17690     */
                17691     if (bfminexc) {
                17692         /* minExclusive >= BASE minExclusive */
                17693         res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
                17694         if (res == -2)
                17695         goto internal_error;
                17696         if (res == -1) {
                17697         xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
                17698         }
                17699         if ((res != 0) && (bfminexc->fixed)) {
                17700         FACET_RESTR_FIXED_ERR(fminexc)
                17701         }
                17702     }
                17703     if (bfmaxinc) {
                17704         /* minExclusive <= BASE maxInclusive */
                17705         res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
                17706         if (res == -2)
                17707         goto internal_error;
                17708         if (res == 1) {
                17709         xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
                17710         }
                17711     }
                17712     if (bfmininc) {
                17713         /* minExclusive >= BASE minInclusive */
                17714         res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
                17715         if (res == -2)
                17716         goto internal_error;
                17717         if (res == -1) {
                17718         xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
                17719         }
                17720     }
                17721     if (bfmaxexc) {
                17722         /* minExclusive < BASE maxExclusive */
                17723         res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
                17724         if (res == -2)
                17725         goto internal_error;
                17726         if (res != -1) {
                17727         xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
                17728         }
                17729     }
                17730     }
                17731     if (fmininc) {
                17732     /*
                17733     * "minInclusive < maxExclusive"
                17734     */
                17735     if (fmaxexc) {
                17736         res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
                17737         if (res == -2)
                17738         goto internal_error;
                17739         if (res != -1) {
                17740         xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
                17741         }
                17742     }
                17743     /*
                17744     * "minExclusive valid restriction"
                17745     */
                17746     if (bfmininc) {
                17747         /* minInclusive >= BASE minInclusive */
                17748         res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
                17749         if (res == -2)
                17750         goto internal_error;
                17751         if (res == -1) {
                17752         xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
                17753         }
                17754         if ((res != 0) && (bfmininc->fixed)) {
                17755         FACET_RESTR_FIXED_ERR(fmininc)
                17756         }
                17757     }
                17758     if (bfmaxinc) {
                17759         /* minInclusive <= BASE maxInclusive */
                17760         res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
                17761         if (res == -2)
                17762         goto internal_error;
                17763         if (res == 1) {
                17764         xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
                17765         }
                17766     }
                17767     if (bfminexc) {
                17768         /* minInclusive > BASE minExclusive */
                17769         res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
                17770         if (res == -2)
                17771         goto internal_error;
                17772         if (res != 1)
                17773         xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
                17774     }
                17775     if (bfmaxexc) {
                17776         /* minInclusive < BASE maxExclusive */
                17777         res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
                17778         if (res == -2)
                17779         goto internal_error;
                17780         if (res != -1)
                17781         xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
                17782     }
                17783     }
                17784     if (ftotdig && bftotdig) {
                17785     /*
                17786     * SCC " totalDigits valid restriction"
                17787     * totalDigits <= BASE totalDigits
                17788     */
                17789     res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
                17790     if (res == -2)
                17791         goto internal_error;
                17792     if (res == 1)
                17793         xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
                17794         -1, 1, 1);
                17795     if ((res != 0) && (bftotdig->fixed)) {
                17796         FACET_RESTR_FIXED_ERR(ftotdig)
                17797     }
                17798     }
                17799     if (ffracdig && bffracdig) {
                17800     /*
                17801     * SCC  "fractionDigits valid restriction"
                17802     * fractionDigits <= BASE fractionDigits
                17803     */
                17804     res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
                17805     if (res == -2)
                17806         goto internal_error;
                17807     if (res == 1)
                17808         xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
                17809         -1, 1, 1);
                17810     if ((res != 0) && (bffracdig->fixed)) {
                17811         FACET_RESTR_FIXED_ERR(ffracdig)
                17812     }
                17813     }
                17814     /*
                17815     * SCC "fractionDigits less than or equal to totalDigits"
                17816     */
                17817     if (! ftotdig)
                17818     ftotdig = bftotdig;
                17819     if (! ffracdig)
                17820     ffracdig = bffracdig;
                17821     if (ftotdig && ffracdig) {
                17822     res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
                17823     if (res == -2)
                17824         goto internal_error;
                17825     if (res == 1)
                17826         xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
                17827         -1, 1, 0);
                17828     }
                17829     /*
                17830     * *Enumerations* won' be added here, since only the first set
                17831     * of enumerations in the ancestor-or-self axis is used
                17832     * for validation, plus we need to use the base type of those
                17833     * enumerations for whitespace.
                17834     *
                17835     * *Patterns*: won't be add here, since they are ORed at
                17836     * type level and ANDed at ancestor level. This will
                17837     * happen during validation by walking the base axis
                17838     * of the type.
                17839     */
                17840     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
                17841     bfacet = cur->facet;
                17842     /*
                17843     * Special handling of enumerations and patterns.
                17844     * TODO: hmm, they should not appear in the set, so remove this.
                17845     */
                17846     if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
                17847         (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
                17848         continue;
                17849     /*
                17850     * Search for a duplicate facet in the current type.
                17851     */
                17852     link = type->facetSet;
                17853     /* err = 0; */
                17854     /* fixedErr = 0; */
                17855     while (link != NULL) {
                17856         facet = link->facet;
                17857         if (facet->type == bfacet->type) {
                17858         switch (facet->type) {
                17859             case XML_SCHEMA_FACET_WHITESPACE:
                17860             /*
                17861             * The whitespace must be stronger.
                17862             */
                17863             if (facet->whitespace < bfacet->whitespace) {
                17864                 FACET_RESTR_ERR(facet,
                17865                 "The 'whitespace' value has to be equal to "
                17866                 "or stronger than the 'whitespace' value of "
                17867                 "the base type")
                17868             }
                17869             if ((bfacet->fixed) &&
                17870                 (facet->whitespace != bfacet->whitespace)) {
                17871                 FACET_RESTR_FIXED_ERR(facet)
                17872             }
                17873             break;
                17874             default:
                17875             break;
                17876         }
                17877         /* Duplicate found. */
                17878         break;
                17879         }
                17880         link = link->next;
                17881     }
                17882     /*
                17883     * If no duplicate was found: add the base types's facet
                17884     * to the set.
                17885     */
                17886     if (link == NULL) {
                17887         link = (xmlSchemaFacetLinkPtr)
                17888         xmlMalloc(sizeof(xmlSchemaFacetLink));
                17889         if (link == NULL) {
                17890         xmlSchemaPErrMemory(pctxt,
                17891             "deriving facets, creating a facet link", NULL);
                17892         return (-1);
                17893         }
                17894         link->facet = cur->facet;
                17895         link->next = NULL;
                17896         if (last == NULL)
                17897         type->facetSet = link;
                17898         else
                17899         last->next = link;
                17900         last = link;
                17901     }
                17902 
                17903     }
                17904 
                17905     return (0);
                17906 internal_error:
                17907     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
                17908     "an error occurred");
                17909     return (-1);
                17910 }
                17911 
                17912 static int
                17913 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
                17914                          xmlSchemaTypePtr type)
                17915 {
                17916     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
                17917     /*
                17918     * The actual value is then formed by replacing any union type
                17919     * definition in the `explicit members` with the members of their
                17920     * {member type definitions}, in order.
                17921     *
                17922     * TODO: There's a bug entry at
                17923     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
                17924     * which indicates that we'll keep the union types the future.
                17925     */
                17926     link = type->memberTypes;
                17927     while (link != NULL) {
                17928 
                17929     if (WXS_IS_TYPE_NOT_FIXED(link->type))
                17930         xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
                17931 
                17932     if (WXS_IS_UNION(link->type)) {
                17933         subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
                17934         if (subLink != NULL) {
                17935         link->type = subLink->type;
                17936         if (subLink->next != NULL) {
                17937             lastLink = link->next;
                17938             subLink = subLink->next;
                17939             prevLink = link;
                17940             while (subLink != NULL) {
                17941             newLink = (xmlSchemaTypeLinkPtr)
                17942                 xmlMalloc(sizeof(xmlSchemaTypeLink));
                17943             if (newLink == NULL) {
                17944                 xmlSchemaPErrMemory(pctxt, "allocating a type link",
                17945                 NULL);
                17946                 return (-1);
                17947             }
                17948             newLink->type = subLink->type;
                17949             prevLink->next = newLink;
                17950             prevLink = newLink;
                17951             newLink->next = lastLink;
                17952 
                17953             subLink = subLink->next;
                17954             }
                17955         }
                17956         }
                17957     }
                17958     link = link->next;
                17959     }
                17960     return (0);
                17961 }
                17962 
                17963 static void
                17964 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
                17965 {
                17966     int has = 0, needVal = 0, normVal = 0;
                17967 
                17968     has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
                17969     if (has) {
                17970     needVal = (type->baseType->flags &
                17971         XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
                17972     normVal = (type->baseType->flags &
                17973         XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
                17974     }
                17975     if (type->facets != NULL) {
                17976     xmlSchemaFacetPtr fac;
                17977 
                17978     for (fac = type->facets; fac != NULL; fac = fac->next) {
                17979         switch (fac->type) {
                17980         case XML_SCHEMA_FACET_WHITESPACE:
                17981             break;
                17982         case XML_SCHEMA_FACET_PATTERN:
                17983             normVal = 1;
                17984             has = 1;
                17985             break;
                17986         case XML_SCHEMA_FACET_ENUMERATION:
                17987             needVal = 1;
                17988             normVal = 1;
                17989             has = 1;
                17990             break;
                17991         default:
                17992             has = 1;
                17993             break;
                17994         }
                17995     }
                17996     }
                17997     if (normVal)
                17998     type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
                17999     if (needVal)
                18000     type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
                18001     if (has)
                18002     type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
                18003 
                18004     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
                18005     xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
                18006     /*
                18007     * OPTIMIZE VAL TODO: Some facets need a computed value.
                18008     */
                18009     if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
                18010         (prim->builtInType != XML_SCHEMAS_STRING)) {
                18011         type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
                18012     }
                18013     }
                18014 }
                18015 
                18016 static int
                18017 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
                18018 {
                18019 
                18020 
                18021     /*
                18022     * Evaluate the whitespace-facet value.
                18023     */
                18024     if (WXS_IS_LIST(type)) {
                18025     type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
                18026     return (0);
                18027     } else if (WXS_IS_UNION(type))
                18028     return (0);
                18029 
                18030     if (type->facetSet != NULL) {
                18031     xmlSchemaFacetLinkPtr lin;
                18032 
                18033     for (lin = type->facetSet; lin != NULL; lin = lin->next) {
                18034         if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
                18035         switch (lin->facet->whitespace) {
                18036         case XML_SCHEMAS_FACET_PRESERVE:
                18037             type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
                18038             break;
                18039         case XML_SCHEMAS_FACET_REPLACE:
                18040             type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
                18041             break;
                18042         case XML_SCHEMAS_FACET_COLLAPSE:
                18043             type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
                18044             break;
                18045         default:
                18046             return (-1);
                18047         }
                18048         return (0);
                18049         }
                18050     }
                18051     }
                18052     /*
                18053     * For all `atomic` datatypes other than string (and types `derived`
                18054     * by `restriction` from it) the value of whiteSpace is fixed to
                18055     * collapse
                18056     */
                18057     {
                18058     xmlSchemaTypePtr anc;
                18059 
                18060     for (anc = type->baseType; anc != NULL &&
                18061         anc->builtInType != XML_SCHEMAS_ANYTYPE;
                18062         anc = anc->baseType) {
                18063 
                18064         if (anc->type == XML_SCHEMA_TYPE_BASIC) {
                18065         if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
                18066             type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
                18067 
                18068         } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
                18069             (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
                18070             type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
                18071 
                18072         } else
                18073             type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
                18074         break;
                18075         }
                18076     }
                18077     }
                18078     return (0);
                18079 }
                18080 
                18081 static int
                18082 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
                18083               xmlSchemaTypePtr type)
                18084 {
                18085     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
                18086     return(0);
                18087     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
                18088     return(0);
                18089     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
                18090 
                18091     if (WXS_IS_LIST(type)) {
                18092     /*
                18093     * Corresponds to <simpleType><list>...
                18094     */
                18095     if (type->subtypes == NULL) {
                18096         /*
                18097         * This one is really needed, so get out.
                18098         */
                18099         PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
                18100         "list type has no item-type assigned");
                18101         return(-1);
                18102     }
                18103     } else if (WXS_IS_UNION(type)) {
                18104     /*
                18105     * Corresponds to <simpleType><union>...
                18106     */
                18107     if (type->memberTypes == NULL) {
                18108         /*
                18109         * This one is really needed, so get out.
                18110         */
                18111         PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
                18112         "union type has no member-types assigned");
                18113         return(-1);
                18114     }
                18115     } else {
                18116     /*
                18117     * Corresponds to <simpleType><restriction>...
                18118     */
                18119     if (type->baseType == NULL) {
                18120         PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
                18121         "type has no base-type assigned");
                18122         return(-1);
                18123     }
                18124     if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
                18125         if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
                18126         return(-1);
                18127     /*
                18128     * Variety
                18129     * If the <restriction> alternative is chosen, then the
                18130     * {variety} of the {base type definition}.
                18131     */
                18132     if (WXS_IS_ATOMIC(type->baseType))
                18133         type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
                18134     else if (WXS_IS_LIST(type->baseType)) {
                18135         type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
                18136         /*
                18137         * Inherit the itemType.
                18138         */
                18139         type->subtypes = type->baseType->subtypes;
                18140     } else if (WXS_IS_UNION(type->baseType)) {
                18141         type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
                18142         /*
                18143         * NOTE that we won't assign the memberTypes of the base,
                18144         * since this will make trouble when freeing them; we will
                18145         * use a lookup function to access them instead.
                18146         */
                18147     }
                18148     }
                18149     return(0);
                18150 }
                18151 
                18152 #ifdef DEBUG_TYPE
                18153 static void
                18154 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
                18155                xmlSchemaTypePtr type)
                18156 {
                18157     if (type->node != NULL) {
                18158         xmlGenericError(xmlGenericErrorContext,
                18159                         "Type of %s : %s:%d :", name,
                18160                         type->node->doc->URL,
                18161                         xmlGetLineNo(type->node));
                18162     } else {
                18163         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
                18164     }
                18165     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
                18166     switch (type->contentType) {
                18167         case XML_SCHEMA_CONTENT_SIMPLE:
                18168         xmlGenericError(xmlGenericErrorContext, "simple\n");
                18169         break;
                18170         case XML_SCHEMA_CONTENT_ELEMENTS:
                18171         xmlGenericError(xmlGenericErrorContext, "elements\n");
                18172         break;
                18173         case XML_SCHEMA_CONTENT_UNKNOWN:
                18174         xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
                18175         break;
                18176         case XML_SCHEMA_CONTENT_EMPTY:
                18177         xmlGenericError(xmlGenericErrorContext, "empty\n");
                18178         break;
                18179         case XML_SCHEMA_CONTENT_MIXED:
                18180         if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
                18181             type->subtypes))
                18182             xmlGenericError(xmlGenericErrorContext,
                18183             "mixed as emptiable particle\n");
                18184         else
                18185             xmlGenericError(xmlGenericErrorContext, "mixed\n");
                18186         break;
                18187         /* Removed, since not used. */
                18188         /*
                18189         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
                18190         xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
                18191         break;
                18192         */
                18193         case XML_SCHEMA_CONTENT_BASIC:
                18194         xmlGenericError(xmlGenericErrorContext, "basic\n");
                18195         break;
                18196         default:
                18197         xmlGenericError(xmlGenericErrorContext,
                18198             "not registered !!!\n");
                18199         break;
                18200     }
                18201     }
                18202 }
                18203 #endif
                18204 
                18205 /*
                18206 * 3.14.6 Constraints on Simple Type Definition Schema Components
                18207 */
                18208 static int
                18209 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
                18210                  xmlSchemaTypePtr type)
                18211 {
                18212     int res, olderrs = pctxt->nberrors;
                18213 
                18214     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
                18215     return(-1);
                18216 
                18217     if (! WXS_IS_TYPE_NOT_FIXED(type))
                18218     return(0);
                18219 
                18220     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
                18221     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
                18222 
                18223     if (type->baseType == NULL) {
                18224     PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
                18225         "missing baseType");
                18226     goto exit_failure;
                18227     }
                18228     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
                18229     xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
                18230     /*
                18231     * If a member type of a union is a union itself, we need to substitute
                18232     * that member type for its member types.
                18233     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
                18234     * types in WXS 1.1.
                18235     */
                18236     if ((type->memberTypes != NULL) &&
                18237     (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
                18238     return(-1);
                18239     /*
                18240     * SPEC src-simple-type 1
                18241     * "The corresponding simple type definition, if any, must satisfy
                18242     * the conditions set out in Constraints on Simple Type Definition
                18243     * Schema Components ($3.14.6)."
                18244     */
                18245     /*
                18246     * Schema Component Constraint: Simple Type Definition Properties Correct
                18247     * (st-props-correct)
                18248     */
                18249     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
                18250     HFAILURE HERROR
                18251     /*
                18252     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
                18253     * (cos-st-restricts)
                18254     */
                18255     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
                18256     HFAILURE HERROR
                18257     /*
                18258     * TODO: Removed the error report, since it got annoying to get an
                18259     * extra error report, if anything failed until now.
                18260     * Enable this if needed.
                18261     *
                18262     * xmlSchemaPErr(ctxt, type->node,
                18263     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
                18264     *    "Simple type '%s' does not satisfy the constraints "
                18265     *    "on simple type definitions.\n",
                18266     *    type->name, NULL);
                18267     */
                18268     /*
                18269     * Schema Component Constraint: Simple Type Restriction (Facets)
                18270     * (st-restrict-facets)
                18271     */
                18272     res = xmlSchemaCheckFacetValues(type, pctxt);
                18273     HFAILURE HERROR
                18274     if ((type->facetSet != NULL) ||
                18275     (type->baseType->facetSet != NULL)) {
                18276     res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
                18277     HFAILURE HERROR
                18278     }
                18279     /*
                18280     * Whitespace value.
                18281     */
                18282     res = xmlSchemaTypeFixupWhitespace(type);
                18283     HFAILURE HERROR
                18284     xmlSchemaTypeFixupOptimFacets(type);
                18285 
                18286 exit_error:
                18287 #ifdef DEBUG_TYPE
                18288     xmlSchemaDebugFixedType(pctxt, type);
                18289 #endif
                18290     if (olderrs != pctxt->nberrors)
                18291     return(pctxt->err);
                18292     return(0);
                18293 
                18294 exit_failure:
                18295 #ifdef DEBUG_TYPE
                18296     xmlSchemaDebugFixedType(pctxt, type);
                18297 #endif
                18298     return(-1);
                18299 }
                18300 
                18301 static int
                18302 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
                18303               xmlSchemaTypePtr type)
                18304 {
                18305     int res = 0, olderrs = pctxt->nberrors;
                18306     xmlSchemaTypePtr baseType = type->baseType;
                18307 
                18308     if (! WXS_IS_TYPE_NOT_FIXED(type))
                18309     return(0);
                18310     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
                18311     if (baseType == NULL) {
                18312     PERROR_INT("xmlSchemaFixupComplexType",
                18313         "missing baseType");
                18314     goto exit_failure;
                18315     }
                18316     /*
                18317     * Fixup the base type.
                18318     */
                18319     if (WXS_IS_TYPE_NOT_FIXED(baseType))
                18320     xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
                18321     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
                18322     /*
                18323     * Skip fixup if the base type is invalid.
                18324     * TODO: Generate a warning!
                18325     */
                18326     return(0);
                18327     }
                18328     /*
                18329     * This basically checks if the base type can be derived.
                18330     */
                18331     res = xmlSchemaCheckSRCCT(pctxt, type);
                18332     HFAILURE HERROR
                18333     /*
                18334     * Fixup the content type.
                18335     */
                18336     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
                18337     /*
                18338     * Corresponds to <complexType><simpleContent>...
                18339     */
                18340     if ((WXS_IS_COMPLEX(baseType)) &&
                18341         (baseType->contentTypeDef != NULL) &&
                18342         (WXS_IS_RESTRICTION(type))) {
                18343         xmlSchemaTypePtr contentBase, content;
                18344 #ifdef ENABLE_NAMED_LOCALS
                18345         char buf[30];
                18346         const xmlChar *tmpname;
                18347 #endif
                18348         /*
                18349         * SPEC (1) If <restriction> + base type is <complexType>,
                18350         * "whose own {content type} is a simple type..."
                18351         */
                18352         if (type->contentTypeDef != NULL) {
                18353         /*
                18354         * SPEC (1.1) "the simple type definition corresponding to the
                18355         * <simpleType> among the [children] of <restriction> if there
                18356         * is one;"
                18357         * Note that this "<simpleType> among the [children]" was put
                18358         * into ->contentTypeDef during parsing.
                18359         */
                18360         contentBase = type->contentTypeDef;
                18361         type->contentTypeDef = NULL;
                18362         } else {
                18363         /*
                18364         * (1.2) "...otherwise (<restriction> has no <simpleType>
                18365         * among its [children]), the simple type definition which
                18366         * is the {content type} of the ... base type."
                18367         */
                18368         contentBase = baseType->contentTypeDef;
                18369         }
                18370         /*
                18371         * SPEC
                18372         * "... a simple type definition which restricts the simple
                18373         * type definition identified in clause 1.1 or clause 1.2
                18374         * with a set of facet components"
                18375         *
                18376         * Create the anonymous simple type, which will be the content
                18377         * type of the complex type.
                18378         */
                18379 #ifdef ENABLE_NAMED_LOCALS
                18380         snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
                18381         tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
                18382         content = xmlSchemaAddType(pctxt, pctxt->schema,
                18383         XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
                18384         type->node, 0);
                18385 #else
                18386         content = xmlSchemaAddType(pctxt, pctxt->schema,
                18387         XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
                18388         type->node, 0);
                18389 #endif
                18390         if (content == NULL)
                18391         goto exit_failure;
                18392         /*
                18393         * We will use the same node as for the <complexType>
                18394         * to have it somehow anchored in the schema doc.
                18395         */
                18396         content->type = XML_SCHEMA_TYPE_SIMPLE;
                18397         content->baseType = contentBase;
                18398         /*
                18399         * Move the facets, previously anchored on the
                18400         * complexType during parsing.
                18401         */
                18402         content->facets = type->facets;
                18403         type->facets = NULL;
                18404         content->facetSet = type->facetSet;
                18405         type->facetSet = NULL;
                18406 
                18407         type->contentTypeDef = content;
                18408         if (WXS_IS_TYPE_NOT_FIXED(contentBase))
                18409         xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
                18410         /*
                18411         * Fixup the newly created type. We don't need to check
                18412         * for circularity here.
                18413         */
                18414         res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
                18415         HFAILURE HERROR
                18416         res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
                18417         HFAILURE HERROR
                18418 
                18419     } else if ((WXS_IS_COMPLEX(baseType)) &&
                18420         (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
                18421         (WXS_IS_RESTRICTION(type))) {
                18422         /*
                18423         * SPEC (2) If <restriction> + base is a mixed <complexType> with
                18424         * an emptiable particle, then a simple type definition which
                18425         * restricts the <restriction>'s <simpleType> child.
                18426         */
                18427         if ((type->contentTypeDef == NULL) ||
                18428         (type->contentTypeDef->baseType == NULL)) {
                18429         /*
                18430         * TODO: Check if this ever happens.
                18431         */
                18432         xmlSchemaPCustomErr(pctxt,
                18433             XML_SCHEMAP_INTERNAL,
                18434             WXS_BASIC_CAST type, NULL,
                18435             "Internal error: xmlSchemaTypeFixup, "
                18436             "complex type '%s': the <simpleContent><restriction> "
                18437             "is missing a <simpleType> child, but was not caught "
                18438             "by xmlSchemaCheckSRCCT()", type->name);
                18439         goto exit_failure;
                18440         }
                18441     } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
                18442         /*
                18443         * SPEC (3) If <extension> + base is <complexType> with
                18444         * <simpleType> content, "...then the {content type} of that
                18445         * complex type definition"
                18446         */
                18447         if (baseType->contentTypeDef == NULL) {
                18448         /*
                18449         * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
                18450         * should have caught this already.
                18451         */
                18452         xmlSchemaPCustomErr(pctxt,
                18453             XML_SCHEMAP_INTERNAL,
                18454             WXS_BASIC_CAST type, NULL,
                18455             "Internal error: xmlSchemaTypeFixup, "
                18456             "complex type '%s': the <extension>ed base type is "
                18457             "a complex type with no simple content type",
                18458             type->name);
                18459         goto exit_failure;
                18460         }
                18461         type->contentTypeDef = baseType->contentTypeDef;
                18462     } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
                18463         /*
                18464         * SPEC (4) <extension> + base is <simpleType>
                18465         * "... then that simple type definition"
                18466         */
                18467         type->contentTypeDef = baseType;
                18468     } else {
                18469         /*
                18470         * TODO: Check if this ever happens.
                18471         */
                18472         xmlSchemaPCustomErr(pctxt,
                18473         XML_SCHEMAP_INTERNAL,
                18474         WXS_BASIC_CAST type, NULL,
                18475         "Internal error: xmlSchemaTypeFixup, "
                18476         "complex type '%s' with <simpleContent>: unhandled "
                18477         "derivation case", type->name);
                18478         goto exit_failure;
                18479     }
                18480     } else {
                18481     int dummySequence = 0;
                18482     xmlSchemaParticlePtr particle =
                18483         (xmlSchemaParticlePtr) type->subtypes;
                18484     /*
                18485     * Corresponds to <complexType><complexContent>...
                18486     *
                18487     * NOTE that the effective mixed was already set during parsing of
                18488     * <complexType> and <complexContent>; its flag value is
                18489     * XML_SCHEMAS_TYPE_MIXED.
                18490     *
                18491     * Compute the "effective content":
                18492     * (2.1.1) + (2.1.2) + (2.1.3)
                18493     */
                18494     if ((particle == NULL) ||
                18495         ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
                18496         ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
                18497         (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
                18498         ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
                18499         (particle->minOccurs == 0))) &&
                18500         ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
                18501         if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
                18502         /*
                18503         * SPEC (2.1.4) "If the `effective mixed` is true, then
                18504         * a particle whose properties are as follows:..."
                18505         *
                18506         * Empty sequence model group with
                18507         * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
                18508         * NOTE that we sill assign it the <complexType> node to
                18509         * somehow anchor it in the doc.
                18510         */
                18511         if ((particle == NULL) ||
                18512             (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
                18513             /*
                18514             * Create the particle.
                18515             */
                18516             particle = xmlSchemaAddParticle(pctxt,
                18517             type->node, 1, 1);
                18518             if (particle == NULL)
                18519             goto exit_failure;
                18520             /*
                18521             * Create the model group.
                18522             */ /* URGENT TODO: avoid adding to pending items. */
                18523             particle->children = (xmlSchemaTreeItemPtr)
                18524             xmlSchemaAddModelGroup(pctxt, pctxt->schema,
                18525             XML_SCHEMA_TYPE_SEQUENCE, type->node);
                18526             if (particle->children == NULL)
                18527             goto exit_failure;
                18528 
                18529             type->subtypes = (xmlSchemaTypePtr) particle;
                18530         }
                18531         dummySequence = 1;
                18532         type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
                18533         } else {
                18534         /*
                18535         * SPEC (2.1.5) "otherwise empty"
                18536         */
                18537         type->contentType = XML_SCHEMA_CONTENT_EMPTY;
                18538         }
                18539     } else {
                18540         /*
                18541         * SPEC (2.2) "otherwise the particle corresponding to the
                18542         * <all>, <choice>, <group> or <sequence> among the
                18543         * [children]."
                18544         */
                18545         type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
                18546     }
                18547     /*
                18548     * Compute the "content type".
                18549     */
                18550     if (WXS_IS_RESTRICTION(type)) {
                18551         /*
                18552         * SPEC (3.1) "If <restriction>..."
                18553         * (3.1.1) + (3.1.2) */
                18554         if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
                18555         if (type->flags & XML_SCHEMAS_TYPE_MIXED)
                18556             type->contentType = XML_SCHEMA_CONTENT_MIXED;
                18557         }
                18558     } else {
                18559         /*
                18560         * SPEC (3.2) "If <extension>..."
                18561         */
                18562         if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
                18563         /*
                18564         * SPEC (3.2.1)
                18565         * "If the `effective content` is empty, then the
                18566         *  {content type} of the [...] base ..."
                18567         */
                18568         type->contentType = baseType->contentType;
                18569         type->subtypes = baseType->subtypes;
                18570         /*
                18571         * Fixes bug #347316:
                18572         * This is the case when the base type has a simple
                18573         * type definition as content.
                18574         */
                18575         type->contentTypeDef = baseType->contentTypeDef;
                18576         /*
                18577         * NOTE that the effective mixed is ignored here.
                18578         */
                18579         } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
                18580         /*
                18581         * SPEC (3.2.2)
                18582         */
                18583         if (type->flags & XML_SCHEMAS_TYPE_MIXED)
                18584             type->contentType = XML_SCHEMA_CONTENT_MIXED;
                18585         } else {
                18586         /*
                18587         * SPEC (3.2.3)
                18588         */
                18589         if (type->flags & XML_SCHEMAS_TYPE_MIXED)
                18590             type->contentType = XML_SCHEMA_CONTENT_MIXED;
                18591             /*
                18592             * "A model group whose {compositor} is sequence and whose
                18593             * {particles} are..."
                18594             */
                18595         if ((WXS_TYPE_PARTICLE(type) != NULL) &&
                18596             (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
                18597             ((WXS_TYPE_PARTICLE_TERM(type))->type ==
                18598             XML_SCHEMA_TYPE_ALL))
                18599         {
                18600             /*
                18601             * SPEC cos-all-limited (1)
                18602             */
                18603             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                18604             /* TODO: error code */
                18605             XML_SCHEMAP_COS_ALL_LIMITED,
                18606             WXS_ITEM_NODE(type), NULL,
                18607             "The type has an 'all' model group in its "
                18608             "{content type} and thus cannot be derived from "
                18609             "a non-empty type, since this would produce a "
                18610             "'sequence' model group containing the 'all' "
                18611             "model group; 'all' model groups are not "
                18612             "allowed to appear inside other model groups",
                18613             NULL, NULL);
                18614 
                18615         } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
                18616             (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
                18617             ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
                18618             XML_SCHEMA_TYPE_ALL))
                18619         {
                18620             /*
                18621             * SPEC cos-all-limited (1)
                18622             */
                18623             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                18624             /* TODO: error code */
                18625             XML_SCHEMAP_COS_ALL_LIMITED,
                18626             WXS_ITEM_NODE(type), NULL,
                18627             "A type cannot be derived by extension from a type "
                18628             "which has an 'all' model group in its "
                18629             "{content type}, since this would produce a "
                18630             "'sequence' model group containing the 'all' "
                18631             "model group; 'all' model groups are not "
                18632             "allowed to appear inside other model groups",
                18633             NULL, NULL);
                18634 
ad7b9726c Alex*18635         } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
9d9d4fcc3 Alex*18636             xmlSchemaTreeItemPtr effectiveContent =
                18637             (xmlSchemaTreeItemPtr) type->subtypes;
                18638             /*
                18639             * Create the particle.
                18640             */
                18641             particle = xmlSchemaAddParticle(pctxt,
                18642             type->node, 1, 1);
                18643             if (particle == NULL)
                18644             goto exit_failure;
                18645             /*
                18646             * Create the "sequence" model group.
                18647             */
                18648             particle->children = (xmlSchemaTreeItemPtr)
                18649             xmlSchemaAddModelGroup(pctxt, pctxt->schema,
                18650             XML_SCHEMA_TYPE_SEQUENCE, type->node);
                18651             if (particle->children == NULL)
                18652             goto exit_failure;
                18653             WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
                18654             /*
                18655             * SPEC "the particle of the {content type} of
                18656             * the ... base ..."
                18657             * Create a duplicate of the base type's particle
                18658             * and assign its "term" to it.
                18659             */
                18660             particle->children->children =
                18661             (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
                18662             type->node,
                18663             ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
                18664             ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
                18665             if (particle->children->children == NULL)
                18666             goto exit_failure;
                18667             particle = (xmlSchemaParticlePtr)
                18668             particle->children->children;
                18669             particle->children =
                18670             ((xmlSchemaParticlePtr) baseType->subtypes)->children;
                18671             /*
                18672             * SPEC "followed by the `effective content`."
                18673             */
                18674             particle->next = effectiveContent;
                18675             /*
                18676             * This all will result in:
                18677             * new-particle
                18678             *   --> new-sequence(
                18679             *         new-particle
                18680             *           --> base-model,
                18681             *         this-particle
                18682             *           --> this-model
                18683             *       )
                18684             */
                18685         } else {
                18686             /*
                18687             * This is the case when there is already an empty
                18688             * <sequence> with minOccurs==maxOccurs==1.
                18689             * Just add the base types's content type.
                18690             * NOTE that, although we miss to add an intermediate
                18691             * <sequence>, this should produce no difference to
                18692             * neither the regex compilation of the content model,
                18693             * nor to the complex type constraints.
                18694             */
                18695             particle->children->children =
                18696             (xmlSchemaTreeItemPtr) baseType->subtypes;
                18697         }
                18698         }
                18699     }
                18700     }
                18701     /*
                18702     * Now fixup attribute uses:
                18703     *   - expand attr. group references
                18704     *     - intersect attribute wildcards
                18705     *   - inherit attribute uses of the base type
                18706     *   - inherit or union attr. wildcards if extending
                18707     *   - apply attr. use prohibitions if restricting
                18708     */
                18709     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
                18710     HFAILURE HERROR
                18711     /*
                18712     * Apply the complex type component constraints; this will not
                18713     * check attributes, since this is done in
                18714     * xmlSchemaFixupTypeAttributeUses().
                18715     */
                18716     res = xmlSchemaCheckCTComponent(pctxt, type);
                18717     HFAILURE HERROR
                18718 
                18719 #ifdef DEBUG_TYPE
                18720     xmlSchemaDebugFixedType(pctxt, type);
                18721 #endif
                18722     if (olderrs != pctxt->nberrors)
                18723     return(pctxt->err);
                18724     else
                18725     return(0);
                18726 
                18727 exit_error:
                18728     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
                18729 #ifdef DEBUG_TYPE
                18730     xmlSchemaDebugFixedType(pctxt, type);
                18731 #endif
                18732     return(pctxt->err);
                18733 
                18734 exit_failure:
                18735     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
                18736 #ifdef DEBUG_TYPE
                18737     xmlSchemaDebugFixedType(pctxt, type);
                18738 #endif
                18739     return(-1);
                18740 }
                18741 
                18742 
                18743 /**
                18744  * xmlSchemaTypeFixup:
                18745  * @typeDecl:  the schema type definition
                18746  * @ctxt:  the schema parser context
                18747  *
                18748  * Fixes the content model of the type.
                18749  * URGENT TODO: We need an int result!
                18750  */
                18751 static int
                18752 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
                18753                    xmlSchemaAbstractCtxtPtr actxt)
                18754 {
                18755     if (type == NULL)
                18756         return(0);
                18757     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
                18758     AERROR_INT("xmlSchemaTypeFixup",
                18759         "this function needs a parser context");
                18760     return(-1);
                18761     }
                18762     if (! WXS_IS_TYPE_NOT_FIXED(type))
                18763     return(0);
                18764     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
                18765     return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
                18766     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
                18767     return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
                18768     return(0);
                18769 }
                18770 
                18771 /**
                18772  * xmlSchemaCheckFacet:
                18773  * @facet:  the facet
                18774  * @typeDecl:  the schema type definition
                18775  * @pctxt:  the schema parser context or NULL
                18776  * @name: the optional name of the type
                18777  *
                18778  * Checks and computes the values of facets.
                18779  *
                18780  * Returns 0 if valid, a positive error code if not valid and
                18781  *         -1 in case of an internal or API error.
                18782  */
                18783 int
                18784 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
                18785                     xmlSchemaTypePtr typeDecl,
                18786                     xmlSchemaParserCtxtPtr pctxt,
                18787             const xmlChar * name ATTRIBUTE_UNUSED)
                18788 {
                18789     int ret = 0, ctxtGiven;
                18790 
                18791     if ((facet == NULL) || (typeDecl == NULL))
                18792         return(-1);
                18793     /*
                18794     * TODO: will the parser context be given if used from
                18795     * the relaxNG module?
                18796     */
                18797     if (pctxt == NULL)
                18798     ctxtGiven = 0;
                18799     else
                18800     ctxtGiven = 1;
                18801 
                18802     switch (facet->type) {
                18803         case XML_SCHEMA_FACET_MININCLUSIVE:
                18804         case XML_SCHEMA_FACET_MINEXCLUSIVE:
                18805         case XML_SCHEMA_FACET_MAXINCLUSIVE:
                18806         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
                18807     case XML_SCHEMA_FACET_ENUMERATION: {
                18808                 /*
                18809                  * Okay we need to validate the value
                18810                  * at that point.
                18811                  */
                18812         xmlSchemaTypePtr base;
                18813 
                18814         /* 4.3.5.5 Constraints on enumeration Schema Components
                18815         * Schema Component Constraint: enumeration valid restriction
                18816         * It is an `error` if any member of {value} is not in the
                18817         * `value space` of {base type definition}.
                18818         *
                18819         * minInclusive, maxInclusive, minExclusive, maxExclusive:
                18820         * The value `must` be in the
                18821         * `value space` of the `base type`.
                18822         */
                18823         /*
                18824         * This function is intended to deliver a compiled value
                18825         * on the facet. In this implementation of XML Schemata the
                18826         * type holding a facet, won't be a built-in type.
                18827         * Thus to ensure that other API
                18828         * calls (relaxng) do work, if the given type is a built-in
                18829         * type, we will assume that the given built-in type *is
                18830         * already* the base type.
                18831         */
                18832         if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
                18833             base = typeDecl->baseType;
                18834             if (base == NULL) {
                18835             PERROR_INT("xmlSchemaCheckFacet",
                18836                 "a type user derived type has no base type");
                18837             return (-1);
                18838             }
                18839         } else
                18840             base = typeDecl;
                18841 
                18842         if (! ctxtGiven) {
                18843             /*
                18844             * A context is needed if called from RelaxNG.
                18845             */
                18846             pctxt = xmlSchemaNewParserCtxt("*");
                18847             if (pctxt == NULL)
                18848             return (-1);
                18849         }
                18850         /*
                18851         * NOTE: This call does not check the content nodes,
                18852         * since they are not available:
                18853         * facet->node is just the node holding the facet
                18854         * definition, *not* the attribute holding the *value*
                18855         * of the facet.
                18856         */
                18857         ret = xmlSchemaVCheckCVCSimpleType(
                18858             ACTXT_CAST pctxt, facet->node, base,
                18859             facet->value, &(facet->val), 1, 1, 0);
                18860                 if (ret != 0) {
                18861             if (ret < 0) {
                18862             /* No error message for RelaxNG. */
                18863             if (ctxtGiven) {
                18864                 xmlSchemaCustomErr(ACTXT_CAST pctxt,
                18865                 XML_SCHEMAP_INTERNAL, facet->node, NULL,
                18866                 "Internal error: xmlSchemaCheckFacet, "
                18867                 "failed to validate the value '%s' of the "
                18868                 "facet '%s' against the base type",
                18869                 facet->value, xmlSchemaFacetTypeToString(facet->type));
                18870             }
                18871             goto internal_error;
                18872             }
                18873             ret = XML_SCHEMAP_INVALID_FACET_VALUE;
                18874             /* No error message for RelaxNG. */
                18875             if (ctxtGiven) {
                18876             xmlChar *str = NULL;
                18877 
                18878             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                18879                 ret, facet->node, WXS_BASIC_CAST facet,
                18880                 "The value '%s' of the facet does not validate "
                18881                 "against the base type '%s'",
                18882                 facet->value,
                18883                 xmlSchemaFormatQName(&str,
                18884                 base->targetNamespace, base->name));
                18885             FREE_AND_NULL(str);
                18886             }
                18887             goto exit;
                18888                 } else if (facet->val == NULL) {
                18889             if (ctxtGiven) {
                18890             PERROR_INT("xmlSchemaCheckFacet",
                18891                 "value was not computed");
                18892             }
                18893             TODO
                18894         }
                18895                 break;
                18896             }
                18897         case XML_SCHEMA_FACET_PATTERN:
                18898             facet->regexp = xmlRegexpCompile(facet->value);
                18899             if (facet->regexp == NULL) {
                18900         ret = XML_SCHEMAP_REGEXP_INVALID;
                18901         /* No error message for RelaxNG. */
                18902         if (ctxtGiven) {
                18903             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                18904             ret, facet->node, WXS_BASIC_CAST typeDecl,
                18905             "The value '%s' of the facet 'pattern' is not a "
                18906             "valid regular expression",
                18907             facet->value, NULL);
                18908         }
                18909             }
                18910             break;
                18911         case XML_SCHEMA_FACET_TOTALDIGITS:
                18912         case XML_SCHEMA_FACET_FRACTIONDIGITS:
                18913         case XML_SCHEMA_FACET_LENGTH:
                18914         case XML_SCHEMA_FACET_MAXLENGTH:
                18915         case XML_SCHEMA_FACET_MINLENGTH:
                18916 
                18917         if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
                18918         ret = xmlSchemaValidatePredefinedType(
                18919             xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
                18920             facet->value, &(facet->val));
                18921         } else {
                18922         ret = xmlSchemaValidatePredefinedType(
                18923             xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
                18924             facet->value, &(facet->val));
                18925         }
                18926         if (ret != 0) {
                18927         if (ret < 0) {
                18928             /* No error message for RelaxNG. */
                18929             if (ctxtGiven) {
                18930             PERROR_INT("xmlSchemaCheckFacet",
                18931                 "validating facet value");
                18932             }
                18933             goto internal_error;
                18934         }
                18935         ret = XML_SCHEMAP_INVALID_FACET_VALUE;
                18936         /* No error message for RelaxNG. */
                18937         if (ctxtGiven) {
                18938             /* error code */
                18939             xmlSchemaCustomErr4(ACTXT_CAST pctxt,
                18940             ret, facet->node, WXS_BASIC_CAST typeDecl,
                18941             "The value '%s' of the facet '%s' is not a valid '%s'",
                18942             facet->value,
                18943             xmlSchemaFacetTypeToString(facet->type),
                18944             (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
                18945                 BAD_CAST "nonNegativeInteger" :
                18946                 BAD_CAST "positiveInteger",
                18947             NULL);
                18948         }
                18949         }
                18950         break;
                18951 
                18952         case XML_SCHEMA_FACET_WHITESPACE:{
                18953                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
                18954                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
                18955                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
                18956                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
                18957                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
                18958                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
                18959                 } else {
                18960             ret = XML_SCHEMAP_INVALID_FACET_VALUE;
                18961                     /* No error message for RelaxNG. */
                18962             if (ctxtGiven) {
                18963             /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
                18964             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                18965                 ret, facet->node, WXS_BASIC_CAST typeDecl,
                18966                 "The value '%s' of the facet 'whitespace' is not "
                18967                 "valid", facet->value, NULL);
                18968                     }
                18969                 }
                18970             }
                18971         default:
                18972             break;
                18973     }
                18974 exit:
                18975     if ((! ctxtGiven) && (pctxt != NULL))
                18976     xmlSchemaFreeParserCtxt(pctxt);
                18977     return (ret);
                18978 internal_error:
                18979     if ((! ctxtGiven) && (pctxt != NULL))
                18980     xmlSchemaFreeParserCtxt(pctxt);
                18981     return (-1);
                18982 }
                18983 
                18984 /**
                18985  * xmlSchemaCheckFacetValues:
                18986  * @typeDecl:  the schema type definition
                18987  * @ctxt:  the schema parser context
                18988  *
                18989  * Checks the default values types, especially for facets
                18990  */
                18991 static int
                18992 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
                18993               xmlSchemaParserCtxtPtr pctxt)
                18994 {
                18995     int res, olderrs = pctxt->nberrors;
                18996     const xmlChar *name = typeDecl->name;
                18997     /*
                18998     * NOTE: It is intended to use the facets list, instead
                18999     * of facetSet.
                19000     */
                19001     if (typeDecl->facets != NULL) {
                19002     xmlSchemaFacetPtr facet = typeDecl->facets;
                19003 
                19004     /*
                19005     * Temporarily assign the "schema" to the validation context
                19006     * of the parser context. This is needed for NOTATION validation.
                19007     */
                19008     if (pctxt->vctxt == NULL) {
                19009         if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
                19010         return(-1);
                19011     }
                19012     pctxt->vctxt->schema = pctxt->schema;
                19013     while (facet != NULL) {
                19014         res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
                19015         HFAILURE
                19016         facet = facet->next;
                19017     }
                19018     pctxt->vctxt->schema = NULL;
                19019     }
                19020     if (olderrs != pctxt->nberrors)
                19021     return(pctxt->err);
                19022     return(0);
                19023 exit_failure:
                19024     return(-1);
                19025 }
                19026 
                19027 /**
                19028  * xmlSchemaGetCircModelGrDefRef:
                19029  * @ctxtMGroup: the searched model group
                19030  * @selfMGroup: the second searched model group
                19031  * @particle: the first particle
                19032  *
                19033  * This one is intended to be used by
                19034  * xmlSchemaCheckGroupDefCircular only.
                19035  *
                19036  * Returns the particle with the circular model group definition reference,
                19037  * otherwise NULL.
                19038  */
                19039 static xmlSchemaTreeItemPtr
                19040 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
                19041                   xmlSchemaTreeItemPtr particle)
                19042 {
                19043     xmlSchemaTreeItemPtr circ = NULL;
                19044     xmlSchemaTreeItemPtr term;
                19045     xmlSchemaModelGroupDefPtr gdef;
                19046 
                19047     for (; particle != NULL; particle = particle->next) {
                19048     term = particle->children;
                19049     if (term == NULL)
                19050         continue;
                19051     switch (term->type) {
                19052         case XML_SCHEMA_TYPE_GROUP:
                19053         gdef = (xmlSchemaModelGroupDefPtr) term;
                19054         if (gdef == groupDef)
                19055             return (particle);
                19056         /*
                19057         * Mark this model group definition to avoid infinite
                19058         * recursion on circular references not yet examined.
                19059         */
                19060         if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
                19061             continue;
                19062         if (gdef->children != NULL) {
                19063             gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
                19064             circ = xmlSchemaGetCircModelGrDefRef(groupDef,
                19065             gdef->children->children);
                19066             gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
                19067             if (circ != NULL)
                19068             return (circ);
                19069         }
                19070         break;
                19071         case XML_SCHEMA_TYPE_SEQUENCE:
                19072         case XML_SCHEMA_TYPE_CHOICE:
                19073         case XML_SCHEMA_TYPE_ALL:
                19074         circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
                19075         if (circ != NULL)
                19076             return (circ);
                19077         break;
                19078         default:
                19079         break;
                19080     }
                19081     }
                19082     return (NULL);
                19083 }
                19084 
                19085 /**
                19086  * xmlSchemaCheckGroupDefCircular:
                19087  * @item:  the model group definition
                19088  * @ctxt:  the parser context
                19089  * @name:  the name
                19090  *
                19091  * Checks for circular references to model group definitions.
                19092  */
                19093 static void
                19094 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
                19095                    xmlSchemaParserCtxtPtr ctxt)
                19096 {
                19097     /*
                19098     * Schema Component Constraint: Model Group Correct
                19099     * 2 Circular groups are disallowed. That is, within the {particles}
                19100     * of a group there must not be at any depth a particle whose {term}
                19101     * is the group itself.
                19102     */
                19103     if ((item == NULL) ||
                19104     (item->type != XML_SCHEMA_TYPE_GROUP) ||
                19105     (item->children == NULL))
                19106     return;
                19107     {
                19108     xmlSchemaTreeItemPtr circ;
                19109 
                19110     circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
                19111     if (circ != NULL) {
                19112         xmlChar *str = NULL;
                19113         /*
                19114         * TODO: The error report is not adequate: this constraint
                19115         * is defined for model groups but not definitions, but since
                19116         * there cannot be any circular model groups without a model group
                19117         * definition (if not using a construction API), we check those
                19118         * definitions only.
                19119         */
                19120         xmlSchemaPCustomErr(ctxt,
                19121         XML_SCHEMAP_MG_PROPS_CORRECT_2,
                19122         NULL, WXS_ITEM_NODE(circ),
                19123         "Circular reference to the model group definition '%s' "
                19124         "defined", xmlSchemaFormatQName(&str,
                19125             item->targetNamespace, item->name));
                19126         FREE_AND_NULL(str)
                19127         /*
                19128         * NOTE: We will cut the reference to avoid further
                19129         * confusion of the processor. This is a fatal error.
                19130         */
                19131         circ->children = NULL;
                19132     }
                19133     }
                19134 }
                19135 
                19136 /**
                19137  * xmlSchemaModelGroupToModelGroupDefFixup:
                19138  * @ctxt:  the parser context
                19139  * @mg:  the model group
                19140  *
                19141  * Assigns the model group of model group definitions to the "term"
                19142  * of the referencing particle.
                19143  * In xmlSchemaResolveModelGroupParticleReferences the model group
                19144  * definitions were assigned to the "term", since needed for the
                19145  * circularity check.
                19146  *
                19147  * Schema Component Constraint:
                19148  *     All Group Limited (cos-all-limited) (1.2)
                19149  */
                19150 static void
                19151 xmlSchemaModelGroupToModelGroupDefFixup(
                19152     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                19153     xmlSchemaModelGroupPtr mg)
                19154 {
                19155     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
                19156 
                19157     while (particle != NULL) {
                19158     if ((WXS_PARTICLE_TERM(particle) == NULL) ||
                19159         ((WXS_PARTICLE_TERM(particle))->type !=
                19160         XML_SCHEMA_TYPE_GROUP))
                19161     {
                19162         particle = WXS_PTC_CAST particle->next;
                19163         continue;
                19164     }
                19165     if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
                19166         /*
                19167         * TODO: Remove the particle.
                19168         */
                19169         WXS_PARTICLE_TERM(particle) = NULL;
                19170         particle = WXS_PTC_CAST particle->next;
                19171         continue;
                19172     }
                19173     /*
                19174     * Assign the model group to the {term} of the particle.
                19175     */
                19176     WXS_PARTICLE_TERM(particle) =
                19177         WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
                19178 
                19179     particle = WXS_PTC_CAST particle->next;
                19180     }
                19181 }
                19182 
                19183 /**
                19184  * xmlSchemaCheckAttrGroupCircularRecur:
                19185  * @ctxtGr: the searched attribute group
                19186  * @attr: the current attribute list to be processed
                19187  *
                19188  * This one is intended to be used by
                19189  * xmlSchemaCheckAttrGroupCircular only.
                19190  *
                19191  * Returns the circular attribute group reference, otherwise NULL.
                19192  */
                19193 static xmlSchemaQNameRefPtr
                19194 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
                19195                      xmlSchemaItemListPtr list)
                19196 {
                19197     xmlSchemaAttributeGroupPtr gr;
                19198     xmlSchemaQNameRefPtr ref, circ;
                19199     int i;
                19200     /*
                19201     * We will search for an attribute group reference which
                19202     * references the context attribute group.
                19203     */
                19204     for (i = 0; i < list->nbItems; i++) {
                19205     ref = list->items[i];
                19206     if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
                19207         (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
                19208         (ref->item != NULL))
                19209     {
                19210         gr = WXS_ATTR_GROUP_CAST ref->item;
                19211         if (gr == ctxtGr)
                19212         return(ref);
                19213         if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
                19214         continue;
                19215         /*
                19216         * Mark as visited to avoid infinite recursion on
                19217         * circular references not yet examined.
                19218         */
                19219         if ((gr->attrUses) &&
                19220         (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
                19221         {
                19222         gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
                19223         circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
                19224             (xmlSchemaItemListPtr) gr->attrUses);
                19225         gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
                19226         if (circ != NULL)
                19227             return (circ);
                19228         }
                19229 
                19230     }
                19231     }
                19232     return (NULL);
                19233 }
                19234 
                19235 /**
                19236  * xmlSchemaCheckAttrGroupCircular:
                19237  * attrGr:  the attribute group definition
                19238  * @ctxt:  the parser context
                19239  * @name:  the name
                19240  *
                19241  * Checks for circular references of attribute groups.
                19242  */
                19243 static int
                19244 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
                19245                 xmlSchemaParserCtxtPtr ctxt)
                19246 {
                19247     /*
                19248     * Schema Representation Constraint:
                19249     * Attribute Group Definition Representation OK
                19250     * 3 Circular group reference is disallowed outside <redefine>.
                19251     * That is, unless this element information item's parent is
                19252     * <redefine>, then among the [children], if any, there must
                19253     * not be an <attributeGroup> with ref [attribute] which resolves
                19254     * to the component corresponding to this <attributeGroup>. Indirect
                19255     * circularity is also ruled out. That is, when QName resolution
                19256     * (Schema Document) ($3.15.3) is applied to a `QName` arising from
                19257     * any <attributeGroup>s with a ref [attribute] among the [children],
                19258     * it must not be the case that a `QName` is encountered at any depth
                19259     * which resolves to the component corresponding to this <attributeGroup>.
                19260     */
                19261     if (attrGr->attrUses == NULL)
                19262     return(0);
                19263     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
                19264     return(0);
                19265     else {
                19266     xmlSchemaQNameRefPtr circ;
                19267 
                19268     circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
                19269         (xmlSchemaItemListPtr) attrGr->attrUses);
                19270     if (circ != NULL) {
                19271         xmlChar *str = NULL;
                19272         /*
                19273         * TODO: Report the referenced attr group as QName.
                19274         */
                19275         xmlSchemaPCustomErr(ctxt,
                19276         XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
                19277         NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
                19278         "Circular reference to the attribute group '%s' "
                19279         "defined", xmlSchemaGetComponentQName(&str, attrGr));
                19280         FREE_AND_NULL(str);
                19281         /*
                19282         * NOTE: We will cut the reference to avoid further
                19283         * confusion of the processor.
                19284         * BADSPEC TODO: The spec should define how to process in this case.
                19285         */
                19286         circ->item = NULL;
                19287         return(ctxt->err);
                19288     }
                19289     }
                19290     return(0);
                19291 }
                19292 
                19293 static int
                19294 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
                19295                   xmlSchemaAttributeGroupPtr attrGr);
                19296 
                19297 /**
                19298  * xmlSchemaExpandAttributeGroupRefs:
                19299  * @pctxt: the parser context
                19300  * @node: the node of the component holding the attribute uses
                19301  * @completeWild: the intersected wildcard to be returned
                19302  * @list: the attribute uses
                19303  *
                19304  * Substitutes contained attribute group references
                19305  * for their attribute uses. Wildcards are intersected.
                19306  * Attribute use prohibitions are removed from the list
                19307  * and returned via the @prohibs list.
                19308  * Pointlessness of attr. prohibs, if a matching attr. decl
                19309  * is existent a well, are checked.
                19310  */
                19311 static int
                19312 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
                19313                   xmlSchemaBasicItemPtr item,
                19314                   xmlSchemaWildcardPtr *completeWild,
                19315                   xmlSchemaItemListPtr list,
                19316                   xmlSchemaItemListPtr prohibs)
                19317 {
                19318     xmlSchemaAttributeGroupPtr gr;
                19319     xmlSchemaAttributeUsePtr use;
                19320     xmlSchemaItemListPtr sublist;
                19321     int i, j;
                19322     int created = (*completeWild == NULL) ? 0 : 1;
                19323 
                19324     if (prohibs)
                19325     prohibs->nbItems = 0;
                19326 
                19327     for (i = 0; i < list->nbItems; i++) {
                19328     use = list->items[i];
                19329 
                19330     if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
                19331         if (prohibs == NULL) {
                19332         PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
                19333             "unexpected attr prohibition found");
                19334         return(-1);
                19335         }
                19336         /*
                19337         * Remove from attribute uses.
                19338         */
                19339         if (xmlSchemaItemListRemove(list, i) == -1)
                19340         return(-1);
                19341         i--;
                19342         /*
                19343         * Note that duplicate prohibitions were already
                19344         * handled at parsing time.
                19345         */
                19346         /*
                19347         * Add to list of prohibitions.
                19348         */
                19349         xmlSchemaItemListAddSize(prohibs, 2, use);
                19350         continue;
                19351     }
                19352     if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
                19353         ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
                19354     {
                19355         if ((WXS_QNAME_CAST use)->item == NULL)
                19356         return(-1);
                19357         gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
                19358         /*
                19359         * Expand the referenced attr. group.
                19360         * TODO: remove this, this is done in a previous step, so
                19361         * already done here.
                19362         */
                19363         if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
                19364         if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
                19365             return(-1);
                19366         }
                19367         /*
                19368         * Build the 'complete' wildcard; i.e. intersect multiple
                19369         * wildcards.
                19370         */
                19371         if (gr->attributeWildcard != NULL) {
                19372         if (*completeWild == NULL) {
                19373             *completeWild = gr->attributeWildcard;
                19374         } else {
                19375             if (! created) {
                19376             xmlSchemaWildcardPtr tmpWild;
                19377 
                19378              /*
                19379             * Copy the first encountered wildcard as context,
                19380             * except for the annotation.
                19381             *
                19382             * Although the complete wildcard might not correspond
                19383             * to any node in the schema, we will anchor it on
                19384             * the node of the owner component.
                19385             */
                19386             tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
                19387                 XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
                19388                 WXS_ITEM_NODE(item));
                19389             if (tmpWild == NULL)
                19390                 return(-1);
                19391             if (xmlSchemaCloneWildcardNsConstraints(pctxt,
                19392                 tmpWild, *completeWild) == -1)
                19393                 return (-1);
                19394             tmpWild->processContents = (*completeWild)->processContents;
                19395             *completeWild = tmpWild;
                19396             created = 1;
                19397             }
                19398 
                19399             if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
                19400             gr->attributeWildcard) == -1)
                19401             return(-1);
                19402         }
                19403         }
                19404         /*
                19405         * Just remove the reference if the referenced group does not
                19406         * contain any attribute uses.
                19407         */
                19408         sublist = ((xmlSchemaItemListPtr) gr->attrUses);
                19409         if ((sublist == NULL) || sublist->nbItems == 0) {
                19410         if (xmlSchemaItemListRemove(list, i) == -1)
                19411             return(-1);
                19412         i--;
                19413         continue;
                19414         }
                19415         /*
                19416         * Add the attribute uses.
                19417         */
                19418         list->items[i] = sublist->items[0];
                19419         if (sublist->nbItems != 1) {
                19420         for (j = 1; j < sublist->nbItems; j++) {
                19421             i++;
                19422             if (xmlSchemaItemListInsert(list,
                19423                 sublist->items[j], i) == -1)
                19424             return(-1);
                19425         }
                19426         }
                19427     }
                19428 
                19429     }
                19430     /*
                19431     * Handle pointless prohibitions of declared attributes.
                19432     */
                19433     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
                19434     xmlSchemaAttributeUseProhibPtr prohib;
                19435 
                19436     for (i = prohibs->nbItems -1; i >= 0; i--) {
                19437         prohib = prohibs->items[i];
                19438         for (j = 0; j < list->nbItems; j++) {
                19439         use = list->items[j];
                19440 
                19441         if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
                19442             (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
                19443         {
                19444             xmlChar *str = NULL;
                19445 
                19446             xmlSchemaCustomWarning(ACTXT_CAST pctxt,
                19447             XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
                19448             prohib->node, NULL,
                19449             "Skipping pointless attribute use prohibition "
                19450             "'%s', since a corresponding attribute use "
                19451             "exists already in the type definition",
                19452             xmlSchemaFormatQName(&str,
                19453                 prohib->targetNamespace, prohib->name),
                19454             NULL, NULL);
                19455             FREE_AND_NULL(str);
                19456             /*
                19457             * Remove the prohibition.
                19458             */
                19459             if (xmlSchemaItemListRemove(prohibs, i) == -1)
                19460             return(-1);
                19461             break;
                19462         }
                19463         }
                19464     }
                19465     }
                19466     return(0);
                19467 }
                19468 
                19469 /**
                19470  * xmlSchemaAttributeGroupExpandRefs:
                19471  * @pctxt:  the parser context
                19472  * @attrGr:  the attribute group definition
                19473  *
                19474  * Computation of:
                19475  * {attribute uses} property
                19476  * {attribute wildcard} property
                19477  *
                19478  * Substitutes contained attribute group references
                19479  * for their attribute uses. Wildcards are intersected.
                19480  */
                19481 static int
                19482 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
                19483                   xmlSchemaAttributeGroupPtr attrGr)
                19484 {
                19485     if ((attrGr->attrUses == NULL) ||
                19486     (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
                19487     return(0);
                19488 
                19489     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
                19490     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
                19491     &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
                19492     return(-1);
                19493     return(0);
                19494 }
                19495 
                19496 /**
                19497  * xmlSchemaAttributeGroupExpandRefs:
                19498  * @pctxt:  the parser context
                19499  * @attrGr:  the attribute group definition
                19500  *
                19501  * Substitutes contained attribute group references
                19502  * for their attribute uses. Wildcards are intersected.
                19503  *
                19504  * Schema Component Constraint:
                19505  *    Attribute Group Definition Properties Correct (ag-props-correct)
                19506  */
                19507 static int
                19508 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
                19509                   xmlSchemaAttributeGroupPtr attrGr)
                19510 {
                19511     /*
                19512     * SPEC ag-props-correct
                19513     * (1) "The values of the properties of an attribute group definition
                19514     * must be as described in the property tableau in The Attribute
                19515     * Group Definition Schema Component ($3.6.1), modulo the impact of
                19516     * Missing Sub-components ($5.3);"
                19517     */
                19518 
                19519     if ((attrGr->attrUses != NULL) &&
                19520     (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
                19521     {
                19522     xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
                19523     xmlSchemaAttributeUsePtr use, tmp;
                19524     int i, j, hasId = 0;
                19525 
                19526     for (i = uses->nbItems -1; i >= 0; i--) {
                19527         use = uses->items[i];
                19528         /*
                19529         * SPEC ag-props-correct
                19530         * (2) "Two distinct members of the {attribute uses} must not have
                19531         * {attribute declaration}s both of whose {name}s match and whose
                19532         * {target namespace}s are identical."
                19533         */
                19534         if (i > 0) {
                19535         for (j = i -1; j >= 0; j--) {
                19536             tmp = uses->items[j];
                19537             if ((WXS_ATTRUSE_DECL_NAME(use) ==
                19538             WXS_ATTRUSE_DECL_NAME(tmp)) &&
                19539             (WXS_ATTRUSE_DECL_TNS(use) ==
                19540             WXS_ATTRUSE_DECL_TNS(tmp)))
                19541             {
                19542             xmlChar *str = NULL;
                19543 
                19544             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                19545                 XML_SCHEMAP_AG_PROPS_CORRECT,
                19546                 attrGr->node, WXS_BASIC_CAST attrGr,
                19547                 "Duplicate %s",
                19548                 xmlSchemaGetComponentDesignation(&str, use),
                19549                 NULL);
                19550             FREE_AND_NULL(str);
                19551             /*
                19552             * Remove the duplicate.
                19553             */
                19554             if (xmlSchemaItemListRemove(uses, i) == -1)
                19555                 return(-1);
                19556             goto next_use;
                19557             }
                19558         }
                19559         }
                19560         /*
                19561         * SPEC ag-props-correct
                19562         * (3) "Two distinct members of the {attribute uses} must not have
                19563         * {attribute declaration}s both of whose {type definition}s are or
                19564         * are derived from ID."
                19565         * TODO: Does 'derived' include member-types of unions?
                19566         */
                19567         if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
                19568         if (xmlSchemaIsDerivedFromBuiltInType(
                19569             WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
                19570         {
                19571             if (hasId) {
                19572             xmlChar *str = NULL;
                19573 
                19574             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                19575                 XML_SCHEMAP_AG_PROPS_CORRECT,
                19576                 attrGr->node, WXS_BASIC_CAST attrGr,
                19577                 "There must not exist more than one attribute "
                19578                 "declaration of type 'xs:ID' "
                19579                 "(or derived from 'xs:ID'). The %s violates this "
                19580                 "constraint",
                19581                 xmlSchemaGetComponentDesignation(&str, use),
                19582                 NULL);
                19583             FREE_AND_NULL(str);
                19584             if (xmlSchemaItemListRemove(uses, i) == -1)
                19585                 return(-1);
                19586             }
                19587             hasId = 1;
                19588         }
                19589         }
                19590 next_use: {}
                19591     }
                19592     }
                19593     return(0);
                19594 }
                19595 
                19596 /**
                19597  * xmlSchemaResolveAttrGroupReferences:
                19598  * @attrgrpDecl:  the schema attribute definition
                19599  * @ctxt:  the schema parser context
                19600  * @name:  the attribute name
                19601  *
                19602  * Resolves references to attribute group definitions.
                19603  */
                19604 static int
                19605 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
                19606                     xmlSchemaParserCtxtPtr ctxt)
                19607 {
                19608     xmlSchemaAttributeGroupPtr group;
                19609 
                19610     if (ref->item != NULL)
                19611         return(0);
                19612     group = xmlSchemaGetAttributeGroup(ctxt->schema,
                19613     ref->name,
                19614     ref->targetNamespace);
                19615     if (group == NULL) {
                19616     xmlSchemaPResCompAttrErr(ctxt,
                19617         XML_SCHEMAP_SRC_RESOLVE,
                19618         NULL, ref->node,
                19619         "ref", ref->name, ref->targetNamespace,
                19620         ref->itemType, NULL);
                19621     return(ctxt->err);
                19622     }
                19623     ref->item = WXS_BASIC_CAST group;
                19624     return(0);
                19625 }
                19626 
                19627 /**
                19628  * xmlSchemaCheckAttrPropsCorrect:
                19629  * @item:  an schema attribute declaration/use
                19630  * @ctxt:  a schema parser context
                19631  * @name:  the name of the attribute
                19632  *
                19633  *
                19634  * Schema Component Constraint:
                19635  *    Attribute Declaration Properties Correct (a-props-correct)
                19636  *
                19637  * Validates the value constraints of an attribute declaration/use.
                19638  * NOTE that this needs the simple type definitions to be already
                19639  *   built and checked.
                19640  */
                19641 static int
                19642 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
                19643                    xmlSchemaAttributePtr attr)
                19644 {
                19645 
                19646     /*
                19647     * SPEC a-props-correct (1)
                19648     * "The values of the properties of an attribute declaration must
                19649     * be as described in the property tableau in The Attribute
                19650     * Declaration Schema Component ($3.2.1), modulo the impact of
                19651     * Missing Sub-components ($5.3)."
                19652     */
                19653 
                19654     if (WXS_ATTR_TYPEDEF(attr) == NULL)
                19655     return(0);
                19656 
                19657     if (attr->defValue != NULL) {
                19658     int ret;
                19659 
                19660     /*
                19661     * SPEC a-props-correct (3)
                19662     * "If the {type definition} is or is derived from ID then there
                19663     * must not be a {value constraint}."
                19664     */
                19665     if (xmlSchemaIsDerivedFromBuiltInType(
                19666         WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
                19667     {
                19668         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                19669         XML_SCHEMAP_A_PROPS_CORRECT_3,
                19670         NULL, WXS_BASIC_CAST attr,
                19671         "Value constraints are not allowed if the type definition "
                19672         "is or is derived from xs:ID",
                19673         NULL, NULL);
                19674         return(pctxt->err);
                19675     }
                19676     /*
                19677     * SPEC a-props-correct (2)
                19678     * "if there is a {value constraint}, the canonical lexical
                19679     * representation of its value must be `valid` with respect
                19680     * to the {type definition} as defined in String Valid ($3.14.4)."
                19681     * TODO: Don't care about the *canonical* stuff here, this requirement
                19682     * will be removed in WXS 1.1 anyway.
                19683     */
                19684     ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
                19685         attr->node, WXS_ATTR_TYPEDEF(attr),
                19686         attr->defValue, &(attr->defVal),
                19687         1, 1, 0);
                19688     if (ret != 0) {
                19689         if (ret < 0) {
                19690         PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
                19691             "calling xmlSchemaVCheckCVCSimpleType()");
                19692         return(-1);
                19693         }
                19694         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                19695         XML_SCHEMAP_A_PROPS_CORRECT_2,
                19696         NULL, WXS_BASIC_CAST attr,
                19697         "The value of the value constraint is not valid",
                19698         NULL, NULL);
                19699         return(pctxt->err);
                19700     }
                19701     }
                19702 
                19703     return(0);
                19704 }
                19705 
                19706 static xmlSchemaElementPtr
                19707 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
                19708                  xmlSchemaElementPtr ancestor)
                19709 {
                19710     xmlSchemaElementPtr ret;
                19711 
                19712     if (WXS_SUBST_HEAD(ancestor) == NULL)
                19713     return (NULL);
                19714     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
                19715     return (ancestor);
                19716 
                19717     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
                19718     return (NULL);
                19719     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
                19720     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
                19721     WXS_SUBST_HEAD(ancestor));
                19722     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
                19723 
                19724     return (ret);
                19725 }
                19726 
                19727 /**
                19728  * xmlSchemaCheckElemPropsCorrect:
                19729  * @ctxt:  a schema parser context
                19730  * @decl: the element declaration
                19731  * @name:  the name of the attribute
                19732  *
                19733  * Schema Component Constraint:
                19734  * Element Declaration Properties Correct (e-props-correct)
                19735  *
                19736  * STATUS:
                19737  *   missing: (6)
                19738  */
                19739 static int
                19740 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
                19741                    xmlSchemaElementPtr elemDecl)
                19742 {
                19743     int ret = 0;
                19744     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
                19745     /*
                19746     * SPEC (1) "The values of the properties of an element declaration
                19747     * must be as described in the property tableau in The Element
                19748     * Declaration Schema Component ($3.3.1), modulo the impact of Missing
                19749     * Sub-components ($5.3)."
                19750     */
                19751     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
                19752     xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
                19753 
                19754     xmlSchemaCheckElementDeclComponent(head, pctxt);
                19755     /*
                19756     * SPEC (3) "If there is a non-`absent` {substitution group
                19757     * affiliation}, then {scope} must be global."
                19758     */
                19759     if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
                19760         xmlSchemaPCustomErr(pctxt,
                19761         XML_SCHEMAP_E_PROPS_CORRECT_3,
                19762         WXS_BASIC_CAST elemDecl, NULL,
                19763         "Only global element declarations can have a "
                19764         "substitution group affiliation", NULL);
                19765         ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
                19766     }
                19767     /*
                19768     * TODO: SPEC (6) "Circular substitution groups are disallowed.
                19769     * That is, it must not be possible to return to an element declaration
                19770     * by repeatedly following the {substitution group affiliation}
                19771     * property."
                19772     */
                19773     if (head == elemDecl)
                19774         circ = head;
                19775     else if (WXS_SUBST_HEAD(head) != NULL)
                19776         circ = xmlSchemaCheckSubstGroupCircular(head, head);
                19777     else
                19778         circ = NULL;
                19779     if (circ != NULL) {
                19780         xmlChar *strA = NULL, *strB = NULL;
                19781 
                19782         xmlSchemaPCustomErrExt(pctxt,
                19783         XML_SCHEMAP_E_PROPS_CORRECT_6,
                19784         WXS_BASIC_CAST circ, NULL,
                19785         "The element declaration '%s' defines a circular "
                19786         "substitution group to element declaration '%s'",
                19787         xmlSchemaGetComponentQName(&strA, circ),
                19788         xmlSchemaGetComponentQName(&strB, head),
                19789         NULL);
                19790         FREE_AND_NULL(strA)
                19791         FREE_AND_NULL(strB)
                19792         ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
                19793     }
                19794     /*
                19795     * SPEC (4) "If there is a {substitution group affiliation},
                19796     * the {type definition}
                19797     * of the element declaration must be validly derived from the {type
                19798     * definition} of the {substitution group affiliation}, given the value
                19799     * of the {substitution group exclusions} of the {substitution group
                19800     * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
                19801     * (if the {type definition} is complex) or as defined in
                19802     * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
                19803     * simple)."
                19804     *
                19805     * NOTE: {substitution group exclusions} means the values of the
                19806     * attribute "final".
                19807     */
                19808 
                19809     if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
                19810         int set = 0;
                19811 
                19812         if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
                19813         set |= SUBSET_EXTENSION;
                19814         if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
                19815         set |= SUBSET_RESTRICTION;
                19816 
                19817         if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
                19818         WXS_ELEM_TYPEDEF(head), set) != 0) {
                19819         xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
                19820 
                19821         ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
                19822         xmlSchemaPCustomErrExt(pctxt,
                19823             XML_SCHEMAP_E_PROPS_CORRECT_4,
                19824             WXS_BASIC_CAST elemDecl, NULL,
                19825             "The type definition '%s' was "
                19826             "either rejected by the substitution group "
                19827             "affiliation '%s', or not validly derived from its type "
                19828             "definition '%s'",
                19829             xmlSchemaGetComponentQName(&strA, typeDef),
                19830             xmlSchemaGetComponentQName(&strB, head),
                19831             xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
                19832         FREE_AND_NULL(strA)
                19833         FREE_AND_NULL(strB)
                19834         FREE_AND_NULL(strC)
                19835         }
                19836     }
                19837     }
                19838     /*
                19839     * SPEC (5) "If the {type definition} or {type definition}'s
                19840     * {content type}
                19841     * is or is derived from ID then there must not be a {value constraint}.
                19842     * Note: The use of ID as a type definition for elements goes beyond
                19843     * XML 1.0, and should be avoided if backwards compatibility is desired"
                19844     */
                19845     if ((elemDecl->value != NULL) &&
                19846     ((WXS_IS_SIMPLE(typeDef) &&
                19847       xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
                19848      (WXS_IS_COMPLEX(typeDef) &&
                19849       WXS_HAS_SIMPLE_CONTENT(typeDef) &&
                19850       xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
                19851         XML_SCHEMAS_ID)))) {
                19852 
                19853     ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
                19854     xmlSchemaPCustomErr(pctxt,
                19855         XML_SCHEMAP_E_PROPS_CORRECT_5,
                19856         WXS_BASIC_CAST elemDecl, NULL,
                19857         "The type definition (or type definition's content type) is or "
                19858         "is derived from ID; value constraints are not allowed in "
                19859         "conjunction with such a type definition", NULL);
                19860     } else if (elemDecl->value != NULL) {
                19861     int vcret;
                19862     xmlNodePtr node = NULL;
                19863 
                19864     /*
                19865     * SPEC (2) "If there is a {value constraint}, the canonical lexical
                19866     * representation of its value must be `valid` with respect to the
                19867     * {type definition} as defined in Element Default Valid (Immediate)
                19868     * ($3.3.6)."
                19869     */
                19870     if (typeDef == NULL) {
                19871         xmlSchemaPErr(pctxt, elemDecl->node,
                19872         XML_SCHEMAP_INTERNAL,
                19873         "Internal error: xmlSchemaCheckElemPropsCorrect, "
                19874         "type is missing... skipping validation of "
                19875         "the value constraint", NULL, NULL);
                19876         return (-1);
                19877     }
                19878     if (elemDecl->node != NULL) {
                19879         if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
                19880         node = (xmlNodePtr) xmlHasProp(elemDecl->node,
                19881             BAD_CAST "fixed");
                19882         else
                19883         node = (xmlNodePtr) xmlHasProp(elemDecl->node,
                19884             BAD_CAST "default");
                19885     }
                19886     vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
                19887         typeDef, elemDecl->value, &(elemDecl->defVal));
                19888     if (vcret != 0) {
                19889         if (vcret < 0) {
                19890         PERROR_INT("xmlSchemaElemCheckValConstr",
                19891             "failed to validate the value constraint of an "
                19892             "element declaration");
                19893         return (-1);
                19894         }
                19895         return (vcret);
                19896     }
                19897     }
                19898 
                19899     return (ret);
                19900 }
                19901 
                19902 /**
                19903  * xmlSchemaCheckElemSubstGroup:
                19904  * @ctxt:  a schema parser context
                19905  * @decl: the element declaration
                19906  * @name:  the name of the attribute
                19907  *
                19908  * Schema Component Constraint:
                19909  * Substitution Group (cos-equiv-class)
                19910  *
                19911  * In Libxml2 the subst. groups will be precomputed, in terms of that
                19912  * a list will be built for each subst. group head, holding all direct
                19913  * referents to this head.
                19914  * NOTE that this function needs:
                19915  *   1. circular subst. groups to be checked beforehand
                19916  *   2. the declaration's type to be derived from the head's type
                19917  *
                19918  * STATUS:
                19919  *
                19920  */
                19921 static void
                19922 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
                19923                  xmlSchemaElementPtr elemDecl)
                19924 {
                19925     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
                19926     /* SPEC (1) "Its {abstract} is false." */
                19927     (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
                19928     return;
                19929     {
                19930     xmlSchemaElementPtr head;
                19931     xmlSchemaTypePtr headType, type;
                19932     int set, methSet;
                19933     /*
                19934     * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
                19935     * {disallowed substitutions} as the blocking constraint, as defined in
                19936     * Substitution Group OK (Transitive) ($3.3.6)."
                19937     */
                19938     for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
                19939         head = WXS_SUBST_HEAD(head)) {
                19940         set = 0;
                19941         methSet = 0;
                19942         /*
                19943         * The blocking constraints.
                19944         */
                19945         if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
                19946         continue;
                19947         headType = head->subtypes;
                19948         type = elemDecl->subtypes;
                19949         if (headType == type)
                19950         goto add_member;
                19951         if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
                19952         set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
                19953         if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
                19954         set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
                19955         /*
                19956         * SPEC: Substitution Group OK (Transitive) (2.3)
                19957         * "The set of all {derivation method}s involved in the
                19958         * derivation of D's {type definition} from C's {type definition}
                19959         * does not intersect with the union of the blocking constraint,
                19960         * C's {prohibited substitutions} (if C is complex, otherwise the
                19961         * empty set) and the {prohibited substitutions} (respectively the
                19962         * empty set) of any intermediate {type definition}s in the
                19963         * derivation of D's {type definition} from C's {type definition}."
                19964         */
                19965         /*
                19966         * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
                19967         * subst.head axis, the methSet does not need to be computed for
                19968         * the full depth over and over.
                19969         */
                19970         /*
                19971         * The set of all {derivation method}s involved in the derivation
                19972         */
ad7b9726c Alex*19973         while ((type != NULL) && (type != headType) &&
                19974                    (type != type->baseType)) {
9d9d4fcc3 Alex*19975         if ((WXS_IS_EXTENSION(type)) &&
                19976             ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
                19977             methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
                19978 
                19979         if (WXS_IS_RESTRICTION(type) &&
                19980             ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
                19981             methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
                19982 
                19983         type = type->baseType;
                19984         }
                19985         /*
                19986         * The {prohibited substitutions} of all intermediate types +
                19987         * the head's type.
                19988         */
                19989         type = elemDecl->subtypes->baseType;
                19990         while (type != NULL) {
                19991         if (WXS_IS_COMPLEX(type)) {
                19992             if ((type->flags &
                19993                 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
                19994             ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
                19995             set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
                19996             if ((type->flags &
                19997                 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
                19998             ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
                19999             set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
                20000         } else
                20001             break;
                20002         if (type == headType)
                20003             break;
                20004         type = type->baseType;
                20005         }
                20006         if ((set != 0) &&
                20007         (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
                20008         (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
                20009         ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
                20010         (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
                20011         continue;
                20012         }
                20013 add_member:
                20014         xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
                20015         if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
                20016         head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
                20017     }
                20018     }
                20019 }
                20020 
                20021 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
                20022 /**
                20023  * xmlSchemaCheckElementDeclComponent
                20024  * @pctxt: the schema parser context
                20025  * @ctxtComponent: the context component (an element declaration)
                20026  * @ctxtParticle: the first particle of the context component
                20027  * @searchParticle: the element declaration particle to be analysed
                20028  *
                20029  * Schema Component Constraint: Element Declarations Consistent
                20030  */
                20031 static int
                20032 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
                20033                     xmlSchemaBasicItemPtr ctxtComponent,
                20034                     xmlSchemaParticlePtr ctxtParticle,
                20035                     xmlSchemaParticlePtr searchParticle,
                20036                     xmlSchemaParticlePtr curParticle,
                20037                     int search)
                20038 {
                20039     return(0);
                20040 
                20041     int ret = 0;
                20042     xmlSchemaParticlePtr cur = curParticle;
                20043     if (curParticle == NULL) {
                20044     return(0);
                20045     }
                20046     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
                20047     /*
                20048     * Just return in this case. A missing "term" of the particle
                20049     * might arise due to an invalid "term" component.
                20050     */
                20051     return(0);
                20052     }
                20053     while (cur != NULL) {
                20054     switch (WXS_PARTICLE_TERM(cur)->type) {
                20055         case XML_SCHEMA_TYPE_ANY:
                20056         break;
                20057         case XML_SCHEMA_TYPE_ELEMENT:
                20058         if (search == 0) {
                20059             ret = xmlSchemaCheckElementDeclConsistent(pctxt,
                20060             ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
                20061             if (ret != 0)
                20062             return(ret);
                20063         } else {
                20064             xmlSchemaElementPtr elem =
                20065             WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
                20066             /*
                20067             * SPEC Element Declarations Consistent:
                20068             * "If the {particles} contains, either directly,
                20069             * indirectly (that is, within the {particles} of a
                20070             * contained model group, recursively) or `implicitly`
                20071             * two or more element declaration particles with
                20072             * the same {name} and {target namespace}, then
                20073             * all their type definitions must be the same
                20074             * top-level definition [...]"
                20075             */
                20076             if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
                20077                 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
                20078             xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
                20079                 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
                20080             {
                20081             xmlChar *strA = NULL, *strB = NULL;
                20082 
                20083             xmlSchemaCustomErr(ACTXT_CAST pctxt,
                20084                 /* TODO: error code */
                20085                 XML_SCHEMAP_COS_NONAMBIG,
                20086                 WXS_ITEM_NODE(cur), NULL,
                20087                 "In the content model of %s, there are multiple "
                20088                 "element declarations for '%s' with different "
                20089                 "type definitions",
                20090                 xmlSchemaGetComponentDesignation(&strA,
                20091                 ctxtComponent),
                20092                 xmlSchemaFormatQName(&strB,
                20093                 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
                20094                 WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
                20095             FREE_AND_NULL(strA);
                20096             FREE_AND_NULL(strB);
                20097             return(XML_SCHEMAP_COS_NONAMBIG);
                20098             }
                20099         }
                20100         break;
                20101         case XML_SCHEMA_TYPE_SEQUENCE: {
                20102         break;
                20103         }
                20104         case XML_SCHEMA_TYPE_CHOICE:{
                20105         /*
                20106         xmlSchemaTreeItemPtr sub;
                20107 
                20108         sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
                20109         while (sub != NULL) {
                20110             ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
                20111             ctxtParticle, ctxtElem);
                20112             if (ret != 0)
                20113             return(ret);
                20114             sub = sub->next;
                20115         }
                20116         */
                20117         break;
                20118         }
                20119         case XML_SCHEMA_TYPE_ALL:
                20120         break;
                20121         case XML_SCHEMA_TYPE_GROUP:
                20122         break;
                20123         default:
                20124         xmlSchemaInternalErr2(ACTXT_CAST pctxt,
                20125             "xmlSchemaCheckElementDeclConsistent",
                20126             "found unexpected term of type '%s' in content model",
                20127             WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
                20128         return(-1);
                20129     }
                20130     cur = (xmlSchemaParticlePtr) cur->next;
                20131     }
                20132 
                20133 exit:
                20134     return(ret);
                20135 }
                20136 #endif
                20137 
                20138 /**
                20139  * xmlSchemaCheckElementDeclComponent
                20140  * @item:  an schema element declaration/particle
                20141  * @ctxt:  a schema parser context
                20142  * @name:  the name of the attribute
                20143  *
                20144  * Validates the value constraints of an element declaration.
                20145  * Adds substitution group members.
                20146  */
                20147 static void
                20148 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
                20149                    xmlSchemaParserCtxtPtr ctxt)
                20150 {
                20151     if (elemDecl == NULL)
                20152     return;
                20153     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
                20154     return;
                20155     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
                20156     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
                20157     /*
                20158     * Adds substitution group members.
                20159     */
                20160     xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
                20161     }
                20162 }
                20163 
                20164 /**
                20165  * xmlSchemaResolveModelGroupParticleReferences:
                20166  * @particle:  a particle component
                20167  * @ctxt:  a parser context
                20168  *
                20169  * Resolves references of a model group's {particles} to
                20170  * model group definitions and to element declarations.
                20171  */
                20172 static void
                20173 xmlSchemaResolveModelGroupParticleReferences(
                20174     xmlSchemaParserCtxtPtr ctxt,
                20175     xmlSchemaModelGroupPtr mg)
                20176 {
                20177     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
                20178     xmlSchemaQNameRefPtr ref;
                20179     xmlSchemaBasicItemPtr refItem;
                20180 
                20181     /*
                20182     * URGENT TODO: Test this.
                20183     */
                20184     while (particle != NULL) {
                20185     if ((WXS_PARTICLE_TERM(particle) == NULL) ||
                20186         ((WXS_PARTICLE_TERM(particle))->type !=
                20187         XML_SCHEMA_EXTRA_QNAMEREF))
                20188     {
                20189         goto next_particle;
                20190     }
                20191     ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
                20192     /*
                20193     * Resolve the reference.
                20194     * NULL the {term} by default.
                20195     */
                20196     particle->children = NULL;
                20197 
                20198     refItem = xmlSchemaGetNamedComponent(ctxt->schema,
                20199         ref->itemType, ref->name, ref->targetNamespace);
                20200     if (refItem == NULL) {
                20201         xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
                20202         NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
                20203         ref->targetNamespace, ref->itemType, NULL);
                20204         /* TODO: remove the particle. */
                20205         goto next_particle;
                20206     }
                20207     if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
                20208         if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
                20209         /* TODO: remove the particle. */
                20210         goto next_particle;
                20211         /*
                20212         * NOTE that we will assign the model group definition
                20213         * itself to the "term" of the particle. This will ease
                20214         * the check for circular model group definitions. After
                20215         * that the "term" will be assigned the model group of the
                20216         * model group definition.
                20217         */
                20218         if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
                20219             XML_SCHEMA_TYPE_ALL) {
                20220         /*
                20221         * SPEC cos-all-limited (1)
                20222         * SPEC cos-all-limited (1.2)
                20223         * "It appears only as the value of one or both of the
                20224         * following properties:"
                20225         * (1.1) "the {model group} property of a model group
                20226         *        definition."
                20227         * (1.2) "the {term} property of a particle [... of] the "
                20228         * {content type} of a complex type definition."
                20229         */
                20230         xmlSchemaCustomErr(ACTXT_CAST ctxt,
                20231             /* TODO: error code */
                20232             XML_SCHEMAP_COS_ALL_LIMITED,
                20233             WXS_ITEM_NODE(particle), NULL,
                20234             "A model group definition is referenced, but "
                20235             "it contains an 'all' model group, which "
                20236             "cannot be contained by model groups",
                20237             NULL, NULL);
                20238         /* TODO: remove the particle. */
                20239         goto next_particle;
                20240         }
                20241         particle->children = (xmlSchemaTreeItemPtr) refItem;
                20242     } else {
                20243         /*
                20244         * TODO: Are referenced element declarations the only
                20245         * other components we expect here?
                20246         */
                20247         particle->children = (xmlSchemaTreeItemPtr) refItem;
                20248     }
                20249 next_particle:
                20250     particle = WXS_PTC_CAST particle->next;
                20251     }
                20252 }
                20253 
                20254 static int
                20255 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
                20256                xmlSchemaValPtr y)
                20257 {
                20258     xmlSchemaTypePtr tx, ty, ptx, pty;
                20259     int ret;
                20260 
                20261     while (x != NULL) {
                20262     /* Same types. */
                20263     tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
                20264     ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
                20265     ptx = xmlSchemaGetPrimitiveType(tx);
                20266     pty = xmlSchemaGetPrimitiveType(ty);
                20267     /*
                20268     * (1) if a datatype T' is `derived` by `restriction` from an
                20269     * atomic datatype T then the `value space` of T' is a subset of
                20270     * the `value space` of T. */
                20271     /*
                20272     * (2) if datatypes T' and T'' are `derived` by `restriction`
                20273     * from a common atomic ancestor T then the `value space`s of T'
                20274     * and T'' may overlap.
                20275     */
                20276     if (ptx != pty)
                20277         return(0);
                20278     /*
                20279     * We assume computed values to be normalized, so do a fast
                20280     * string comparison for string based types.
                20281     */
                20282     if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
                20283         WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
                20284         if (! xmlStrEqual(
                20285         xmlSchemaValueGetAsString(x),
                20286         xmlSchemaValueGetAsString(y)))
                20287         return (0);
                20288     } else {
                20289         ret = xmlSchemaCompareValuesWhtsp(
                20290         x, XML_SCHEMA_WHITESPACE_PRESERVE,
                20291         y, XML_SCHEMA_WHITESPACE_PRESERVE);
                20292         if (ret == -2)
                20293         return(-1);
                20294         if (ret != 0)
                20295         return(0);
                20296     }
                20297     /*
                20298     * Lists.
                20299     */
                20300     x = xmlSchemaValueGetNext(x);
                20301     if (x != NULL) {
                20302         y = xmlSchemaValueGetNext(y);
                20303         if (y == NULL)
                20304         return (0);
                20305     } else if (xmlSchemaValueGetNext(y) != NULL)
                20306         return (0);
                20307     else
                20308         return (1);
                20309     }
                20310     return (0);
                20311 }
                20312 
                20313 /**
                20314  * xmlSchemaResolveAttrUseReferences:
                20315  * @item:  an attribute use
                20316  * @ctxt:  a parser context
                20317  *
                20318  * Resolves the referenced attribute declaration.
                20319  */
                20320 static int
                20321 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
                20322                   xmlSchemaParserCtxtPtr ctxt)
                20323 {
                20324     if ((ctxt == NULL) || (ause == NULL))
                20325     return(-1);
                20326     if ((ause->attrDecl == NULL) ||
                20327     (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
                20328     return(0);
                20329 
                20330     {
                20331     xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
                20332 
                20333     /*
                20334     * TODO: Evaluate, what errors could occur if the declaration is not
                20335     * found.
                20336     */
                20337     ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
                20338         ref->name, ref->targetNamespace);
                20339         if (ause->attrDecl == NULL) {
                20340         xmlSchemaPResCompAttrErr(ctxt,
                20341         XML_SCHEMAP_SRC_RESOLVE,
                20342         WXS_BASIC_CAST ause, ause->node,
                20343         "ref", ref->name, ref->targetNamespace,
                20344         XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
da6279058 Alex*20345             return(ctxt->err);
9d9d4fcc3 Alex*20346         }
                20347     }
                20348     return(0);
                20349 }
                20350 
                20351 /**
                20352  * xmlSchemaCheckAttrUsePropsCorrect:
                20353  * @ctxt:  a parser context
                20354  * @use:  an attribute use
                20355  *
                20356  * Schema Component Constraint:
                20357  * Attribute Use Correct (au-props-correct)
                20358  *
                20359  */
                20360 static int
                20361 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
                20362                  xmlSchemaAttributeUsePtr use)
                20363 {
                20364     if ((ctxt == NULL) || (use == NULL))
                20365     return(-1);
                20366     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
                20367     ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
                20368     return(0);
                20369 
                20370     /*
                20371     * SPEC au-props-correct (1)
                20372     * "The values of the properties of an attribute use must be as
                20373     * described in the property tableau in The Attribute Use Schema
                20374     * Component ($3.5.1), modulo the impact of Missing
                20375     * Sub-components ($5.3)."
                20376     */
                20377 
                20378     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
                20379     ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
                20380         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
                20381     {
                20382     xmlSchemaPCustomErr(ctxt,
                20383         XML_SCHEMAP_AU_PROPS_CORRECT_2,
                20384         WXS_BASIC_CAST use, NULL,
                20385         "The attribute declaration has a 'fixed' value constraint "
                20386         ", thus the attribute use must also have a 'fixed' value "
                20387         "constraint",
                20388         NULL);
                20389     return(ctxt->err);
                20390     }
                20391     /*
                20392     * Compute and check the value constraint's value.
                20393     */
                20394     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
                20395     int ret;
                20396     /*
                20397     * TODO: The spec seems to be missing a check of the
                20398     * value constraint of the attribute use. We will do it here.
                20399     */
                20400     /*
                20401     * SPEC a-props-correct (3)
                20402     */
                20403     if (xmlSchemaIsDerivedFromBuiltInType(
                20404         WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
                20405     {
                20406         xmlSchemaCustomErr(ACTXT_CAST ctxt,
                20407         XML_SCHEMAP_AU_PROPS_CORRECT,
                20408         NULL, WXS_BASIC_CAST use,
                20409         "Value constraints are not allowed if the type definition "
                20410         "is or is derived from xs:ID",
                20411         NULL, NULL);
                20412         return(ctxt->err);
                20413     }
                20414 
                20415     ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
                20416         use->node, WXS_ATTRUSE_TYPEDEF(use),
                20417         use->defValue, &(use->defVal),
                20418         1, 1, 0);
                20419     if (ret != 0) {
                20420         if (ret < 0) {
                20421         PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
                20422             "calling xmlSchemaVCheckCVCSimpleType()");
                20423         return(-1);
                20424         }
                20425         xmlSchemaCustomErr(ACTXT_CAST ctxt,
                20426         XML_SCHEMAP_AU_PROPS_CORRECT,
                20427         NULL, WXS_BASIC_CAST use,
                20428         "The value of the value constraint is not valid",
                20429         NULL, NULL);
                20430         return(ctxt->err);
                20431     }
                20432     }
                20433     /*
                20434     * SPEC au-props-correct (2)
                20435     * "If the {attribute declaration} has a fixed
                20436     * {value constraint}, then if the attribute use itself has a
                20437     * {value constraint}, it must also be fixed and its value must match
                20438     * that of the {attribute declaration}'s {value constraint}."
                20439     */
                20440     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
                20441     (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
                20442     {
                20443     if (! xmlSchemaAreValuesEqual(use->defVal,
                20444         (WXS_ATTRUSE_DECL(use))->defVal))
                20445     {
                20446         xmlSchemaPCustomErr(ctxt,
                20447         XML_SCHEMAP_AU_PROPS_CORRECT_2,
                20448         WXS_BASIC_CAST use, NULL,
                20449         "The 'fixed' value constraint of the attribute use "
                20450         "must match the attribute declaration's value "
                20451         "constraint '%s'",
                20452         (WXS_ATTRUSE_DECL(use))->defValue);
                20453     }
                20454     return(ctxt->err);
                20455     }
                20456     return(0);
                20457 }
                20458 
                20459 
                20460 
                20461 
                20462 /**
                20463  * xmlSchemaResolveAttrTypeReferences:
                20464  * @item:  an attribute declaration
                20465  * @ctxt:  a parser context
                20466  *
                20467  * Resolves the referenced type definition component.
                20468  */
                20469 static int
                20470 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
                20471                    xmlSchemaParserCtxtPtr ctxt)
                20472 {
                20473     /*
                20474     * The simple type definition corresponding to the <simpleType> element
                20475     * information item in the [children], if present, otherwise the simple
                20476     * type definition `resolved` to by the `actual value` of the type
                20477     * [attribute], if present, otherwise the `simple ur-type definition`.
                20478     */
                20479     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
                20480     return(0);
                20481     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
                20482     if (item->subtypes != NULL)
                20483         return(0);
                20484     if (item->typeName != NULL) {
                20485         xmlSchemaTypePtr type;
                20486 
                20487     type = xmlSchemaGetType(ctxt->schema, item->typeName,
                20488         item->typeNs);
                20489     if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
                20490         xmlSchemaPResCompAttrErr(ctxt,
                20491         XML_SCHEMAP_SRC_RESOLVE,
                20492         WXS_BASIC_CAST item, item->node,
                20493         "type", item->typeName, item->typeNs,
                20494         XML_SCHEMA_TYPE_SIMPLE, NULL);
                20495         return(ctxt->err);
                20496     } else
                20497         item->subtypes = type;
                20498 
                20499     } else {
                20500     /*
                20501     * The type defaults to the xs:anySimpleType.
                20502     */
                20503     item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
                20504     }
                20505     return(0);
                20506 }
                20507 
                20508 /**
                20509  * xmlSchemaResolveIDCKeyReferences:
                20510  * @idc:  the identity-constraint definition
                20511  * @ctxt:  the schema parser context
                20512  * @name:  the attribute name
                20513  *
                20514  * Resolve keyRef references to key/unique IDCs.
                20515  * Schema Component Constraint:
                20516  *   Identity-constraint Definition Properties Correct (c-props-correct)
                20517  */
                20518 static int
                20519 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
                20520               xmlSchemaParserCtxtPtr pctxt)
                20521 {
                20522     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
                20523         return(0);
                20524     if (idc->ref->name != NULL) {
                20525     idc->ref->item = (xmlSchemaBasicItemPtr)
                20526         xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
                20527         idc->ref->targetNamespace);
                20528         if (idc->ref->item == NULL) {
                20529         /*
                20530         * TODO: It is actually not an error to fail to resolve
                20531         * at this stage. BUT we need to be that strict!
                20532         */
                20533         xmlSchemaPResCompAttrErr(pctxt,
                20534         XML_SCHEMAP_SRC_RESOLVE,
                20535         WXS_BASIC_CAST idc, idc->node,
                20536         "refer", idc->ref->name,
                20537         idc->ref->targetNamespace,
                20538         XML_SCHEMA_TYPE_IDC_KEY, NULL);
                20539             return(pctxt->err);
                20540     } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
                20541         /*
                20542         * SPEC c-props-correct (1)
                20543         */
                20544         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                20545         XML_SCHEMAP_C_PROPS_CORRECT,
                20546         NULL, WXS_BASIC_CAST idc,
                20547         "The keyref references a keyref",
                20548         NULL, NULL);
                20549         idc->ref->item = NULL;
                20550         return(pctxt->err);
                20551     } else {
                20552         if (idc->nbFields !=
                20553         ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
                20554         xmlChar *str = NULL;
                20555         xmlSchemaIDCPtr refer;
                20556 
                20557         refer = (xmlSchemaIDCPtr) idc->ref->item;
                20558         /*
                20559         * SPEC c-props-correct(2)
                20560         * "If the {identity-constraint category} is keyref,
                20561         * the cardinality of the {fields} must equal that of
                20562         * the {fields} of the {referenced key}.
                20563         */
                20564         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                20565             XML_SCHEMAP_C_PROPS_CORRECT,
                20566             NULL, WXS_BASIC_CAST idc,
                20567             "The cardinality of the keyref differs from the "
                20568             "cardinality of the referenced key/unique '%s'",
                20569             xmlSchemaFormatQName(&str, refer->targetNamespace,
                20570             refer->name),
                20571             NULL);
                20572         FREE_AND_NULL(str)
                20573         return(pctxt->err);
                20574         }
                20575     }
                20576     }
                20577     return(0);
                20578 }
                20579 
                20580 static int
                20581 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
                20582                        xmlSchemaParserCtxtPtr pctxt)
                20583 {
                20584     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
                20585     prohib->targetNamespace) == NULL) {
                20586 
                20587     xmlSchemaPResCompAttrErr(pctxt,
                20588         XML_SCHEMAP_SRC_RESOLVE,
                20589         NULL, prohib->node,
                20590         "ref", prohib->name, prohib->targetNamespace,
                20591         XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
                20592     return(XML_SCHEMAP_SRC_RESOLVE);
                20593     }
                20594     return(0);
                20595 }
                20596 
                20597 #define WXS_REDEFINED_TYPE(c) \
                20598 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
                20599 
                20600 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
                20601 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
                20602 
                20603 #define WXS_REDEFINED_ATTR_GROUP(c) \
                20604 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
                20605 
                20606 static int
                20607 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
                20608 {
                20609     int err = 0;
                20610     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
                20611     xmlSchemaBasicItemPtr prev, item;
                20612     int wasRedefined;
                20613 
                20614     if (redef == NULL)
                20615     return(0);
                20616 
                20617     do {
                20618     item = redef->item;
                20619     /*
                20620     * First try to locate the redefined component in the
                20621     * schema graph starting with the redefined schema.
                20622     * NOTE: According to this schema bug entry:
                20623     *   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
                20624     *   it's not clear if the referenced component needs to originate
                20625     *   from the <redefine>d schema _document_ or the schema; the latter
                20626     *   would include all imported and included sub-schemas of the
                20627     *   <redefine>d schema. Currently the latter approach is used.
                20628     *   SUPPLEMENT: It seems that the WG moves towards the latter
                20629     *   approach, so we are doing it right.
                20630     *
                20631     */
                20632     prev = xmlSchemaFindRedefCompInGraph(
                20633         redef->targetBucket, item->type,
                20634         redef->refName, redef->refTargetNs);
                20635     if (prev == NULL) {
                20636         xmlChar *str = NULL;
                20637         xmlNodePtr node;
                20638 
                20639         /*
                20640         * SPEC src-redefine:
                20641         * (6.2.1) "The `actual value` of its own name attribute plus
                20642         * target namespace must successfully `resolve` to a model
                20643         * group definition in I."
                20644         * (7.2.1) "The `actual value` of its own name attribute plus
                20645         * target namespace must successfully `resolve` to an attribute
                20646         * group definition in I."
                20647 
                20648         *
                20649         * Note that, if we are redefining with the use of references
                20650         * to components, the spec assumes the src-resolve to be used;
                20651         * but this won't assure that we search only *inside* the
                20652         * redefined schema.
                20653         */
                20654         if (redef->reference)
                20655         node = WXS_ITEM_NODE(redef->reference);
                20656         else
                20657         node = WXS_ITEM_NODE(item);
                20658         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                20659         /*
                20660         * TODO: error code.
                20661         * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
                20662         * reference kind.
                20663         */
                20664         XML_SCHEMAP_SRC_REDEFINE, node, NULL,
                20665         "The %s '%s' to be redefined could not be found in "
                20666         "the redefined schema",
                20667         WXS_ITEM_TYPE_NAME(item),
                20668         xmlSchemaFormatQName(&str, redef->refTargetNs,
                20669             redef->refName));
                20670         FREE_AND_NULL(str);
                20671         err = pctxt->err;
                20672         redef = redef->next;
                20673         continue;
                20674     }
                20675     /*
                20676     * TODO: Obtaining and setting the redefinition state is really
                20677     * clumsy.
                20678     */
                20679     wasRedefined = 0;
                20680     switch (item->type) {
                20681         case XML_SCHEMA_TYPE_COMPLEX:
                20682         case XML_SCHEMA_TYPE_SIMPLE:
                20683         if ((WXS_TYPE_CAST prev)->flags &
                20684             XML_SCHEMAS_TYPE_REDEFINED)
                20685         {
                20686             wasRedefined = 1;
                20687             break;
                20688         }
                20689         /* Mark it as redefined. */
                20690         (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
                20691         /*
                20692         * Assign the redefined type to the
                20693         * base type of the redefining type.
                20694         * TODO: How
                20695         */
                20696         ((xmlSchemaTypePtr) item)->baseType =
                20697             (xmlSchemaTypePtr) prev;
                20698         break;
                20699         case XML_SCHEMA_TYPE_GROUP:
                20700         if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
                20701             XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
                20702         {
                20703             wasRedefined = 1;
                20704             break;
                20705         }
                20706         /* Mark it as redefined. */
                20707         (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
                20708             XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
                20709         if (redef->reference != NULL) {
                20710             /*
                20711             * Overwrite the QName-reference with the
                20712             * referenced model group def.
                20713             */
                20714             (WXS_PTC_CAST redef->reference)->children =
                20715             WXS_TREE_CAST prev;
                20716         }
                20717         redef->target = prev;
                20718         break;
                20719         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                20720         if ((WXS_ATTR_GROUP_CAST prev)->flags &
                20721             XML_SCHEMAS_ATTRGROUP_REDEFINED)
                20722         {
                20723             wasRedefined = 1;
                20724             break;
                20725         }
                20726         (WXS_ATTR_GROUP_CAST prev)->flags |=
                20727             XML_SCHEMAS_ATTRGROUP_REDEFINED;
                20728         if (redef->reference != NULL) {
                20729             /*
                20730             * Assign the redefined attribute group to the
                20731             * QName-reference component.
                20732             * This is the easy case, since we will just
                20733             * expand the redefined group.
                20734             */
                20735             (WXS_QNAME_CAST redef->reference)->item = prev;
                20736             redef->target = NULL;
                20737         } else {
                20738             /*
                20739             * This is the complicated case: we need
                20740             * to apply src-redefine (7.2.2) at a later
                20741             * stage, i.e. when attribute group references
                20742             * have been expanded and simple types have
                20743             * been fixed.
                20744             */
                20745             redef->target = prev;
                20746         }
                20747         break;
                20748         default:
                20749         PERROR_INT("xmlSchemaResolveRedefReferences",
                20750             "Unexpected redefined component type");
                20751         return(-1);
                20752     }
                20753     if (wasRedefined) {
                20754         xmlChar *str = NULL;
                20755         xmlNodePtr node;
                20756 
                20757         if (redef->reference)
                20758         node = WXS_ITEM_NODE(redef->reference);
                20759         else
                20760         node = WXS_ITEM_NODE(redef->item);
                20761 
                20762         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                20763         /* TODO: error code. */
                20764         XML_SCHEMAP_SRC_REDEFINE,
                20765         node, NULL,
                20766         "The referenced %s was already redefined. Multiple "
                20767         "redefinition of the same component is not supported",
                20768         xmlSchemaGetComponentDesignation(&str, prev),
                20769         NULL);
                20770         FREE_AND_NULL(str)
                20771         err = pctxt->err;
                20772         redef = redef->next;
                20773         continue;
                20774     }
                20775     redef = redef->next;
                20776     } while (redef != NULL);
                20777 
                20778     return(err);
                20779 }
                20780 
                20781 static int
                20782 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
                20783 {
                20784     int err = 0;
                20785     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
                20786     xmlSchemaBasicItemPtr item;
                20787 
                20788     if (redef == NULL)
                20789     return(0);
                20790 
                20791     do {
                20792     if (redef->target == NULL) {
                20793         redef = redef->next;
                20794         continue;
                20795     }
                20796     item = redef->item;
                20797 
                20798     switch (item->type) {
                20799         case XML_SCHEMA_TYPE_SIMPLE:
                20800         case XML_SCHEMA_TYPE_COMPLEX:
                20801         /*
                20802         * Since the spec wants the {name} of the redefined
                20803         * type to be 'absent', we'll NULL it.
                20804         */
                20805         (WXS_TYPE_CAST redef->target)->name = NULL;
                20806 
                20807         /*
                20808         * TODO: Seems like there's nothing more to do. The normal
                20809         * inheritance mechanism is used. But not 100% sure.
                20810         */
                20811         break;
                20812         case XML_SCHEMA_TYPE_GROUP:
                20813         /*
                20814         * URGENT TODO:
                20815         * SPEC src-redefine:
                20816         * (6.2.2) "The {model group} of the model group definition
                20817         * which corresponds to it per XML Representation of Model
                20818         * Group Definition Schema Components ($3.7.2) must be a
                20819         * `valid restriction` of the {model group} of that model
                20820         * group definition in I, as defined in Particle Valid
                20821         * (Restriction) ($3.9.6)."
                20822         */
                20823         break;
                20824         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                20825         /*
                20826         * SPEC src-redefine:
                20827         * (7.2.2) "The {attribute uses} and {attribute wildcard} of
                20828         * the attribute group definition which corresponds to it
                20829         * per XML Representation of Attribute Group Definition Schema
                20830         * Components ($3.6.2) must be `valid restrictions` of the
                20831         * {attribute uses} and {attribute wildcard} of that attribute
                20832         * group definition in I, as defined in clause 2, clause 3 and
                20833         * clause 4 of Derivation Valid (Restriction, Complex)
                20834         * ($3.4.6) (where references to the base type definition are
                20835         * understood as references to the attribute group definition
                20836         * in I)."
                20837         */
                20838         err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
                20839             XML_SCHEMA_ACTION_REDEFINE,
                20840             item, redef->target,
                20841             (WXS_ATTR_GROUP_CAST item)->attrUses,
                20842             (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
                20843             (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
                20844             (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
                20845         if (err == -1)
                20846             return(-1);
                20847         break;
                20848         default:
                20849         break;
                20850     }
                20851     redef = redef->next;
                20852     } while (redef != NULL);
                20853     return(0);
                20854 }
                20855 
                20856 
                20857 static int
                20858 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
                20859                xmlSchemaBucketPtr bucket)
                20860 {
                20861     xmlSchemaBasicItemPtr item;
                20862     int err;
                20863     xmlHashTablePtr *table;
                20864     const xmlChar *name;
                20865     int i;
                20866 
                20867 #define WXS_GET_GLOBAL_HASH(c, slot) { \
                20868     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
                20869     table = &(WXS_IMPBUCKET((c))->schema->slot); \
                20870     else \
                20871     table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
                20872 
                20873     /*
                20874     * Add global components to the schema's hash tables.
                20875     * This is the place where duplicate components will be
                20876     * detected.
                20877     * TODO: I think normally we should support imports of the
                20878     *   same namespace from multiple locations. We don't do currently,
                20879     *   but if we do then according to:
                20880     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
                20881     *   we would need, if imported directly, to import redefined
                20882     *   components as well to be able to catch clashing components.
                20883     *   (I hope I'll still know what this means after some months :-()
                20884     */
                20885     if (bucket == NULL)
                20886     return(-1);
                20887     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
                20888     return(0);
                20889     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
                20890 
                20891     for (i = 0; i < bucket->globals->nbItems; i++) {
                20892     item = bucket->globals->items[i];
                20893     table = NULL;
                20894     switch (item->type) {
                20895         case XML_SCHEMA_TYPE_COMPLEX:
                20896         case XML_SCHEMA_TYPE_SIMPLE:
                20897         if (WXS_REDEFINED_TYPE(item))
                20898             continue;
                20899         name = (WXS_TYPE_CAST item)->name;
                20900         WXS_GET_GLOBAL_HASH(bucket, typeDecl)
                20901         break;
                20902         case XML_SCHEMA_TYPE_ELEMENT:
                20903         name = (WXS_ELEM_CAST item)->name;
                20904         WXS_GET_GLOBAL_HASH(bucket, elemDecl)
                20905         break;
                20906         case XML_SCHEMA_TYPE_ATTRIBUTE:
                20907         name = (WXS_ATTR_CAST item)->name;
                20908         WXS_GET_GLOBAL_HASH(bucket, attrDecl)
                20909         break;
                20910         case XML_SCHEMA_TYPE_GROUP:
                20911         if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
                20912             continue;
                20913         name = (WXS_MODEL_GROUPDEF_CAST item)->name;
                20914         WXS_GET_GLOBAL_HASH(bucket, groupDecl)
                20915         break;
                20916         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                20917         if (WXS_REDEFINED_ATTR_GROUP(item))
                20918             continue;
                20919         name = (WXS_ATTR_GROUP_CAST item)->name;
                20920         WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
                20921         break;
                20922         case XML_SCHEMA_TYPE_IDC_KEY:
                20923         case XML_SCHEMA_TYPE_IDC_UNIQUE:
                20924         case XML_SCHEMA_TYPE_IDC_KEYREF:
                20925         name = (WXS_IDC_CAST item)->name;
                20926         WXS_GET_GLOBAL_HASH(bucket, idcDef)
                20927         break;
                20928         case XML_SCHEMA_TYPE_NOTATION:
                20929         name = ((xmlSchemaNotationPtr) item)->name;
                20930         WXS_GET_GLOBAL_HASH(bucket, notaDecl)
                20931         break;
                20932         default:
                20933         PERROR_INT("xmlSchemaAddComponents",
                20934             "Unexpected global component type");
                20935         continue;
                20936     }
                20937     if (*table == NULL) {
                20938         *table = xmlHashCreateDict(10, pctxt->dict);
                20939         if (*table == NULL) {
                20940         PERROR_INT("xmlSchemaAddComponents",
                20941             "failed to create a component hash table");
                20942         return(-1);
                20943         }
                20944     }
                20945     err = xmlHashAddEntry(*table, name, item);
                20946     if (err != 0) {
                20947         xmlChar *str = NULL;
                20948 
                20949         xmlSchemaCustomErr(ACTXT_CAST pctxt,
                20950         XML_SCHEMAP_REDEFINED_TYPE,
                20951         WXS_ITEM_NODE(item),
                20952         WXS_BASIC_CAST item,
                20953         "A global %s '%s' does already exist",
                20954         WXS_ITEM_TYPE_NAME(item),
                20955         xmlSchemaGetComponentQName(&str, item));
                20956         FREE_AND_NULL(str);
                20957     }
                20958     }
                20959     /*
                20960     * Process imported/included schemas.
                20961     */
                20962     if (bucket->relations != NULL) {
                20963     xmlSchemaSchemaRelationPtr rel = bucket->relations;
                20964     do {
                20965         if ((rel->bucket != NULL) &&
                20966         ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
                20967         if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
                20968             return(-1);
                20969         }
                20970         rel = rel->next;
                20971     } while (rel != NULL);
                20972     }
                20973     return(0);
                20974 }
                20975 
                20976 static int
                20977 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
                20978              xmlSchemaBucketPtr rootBucket)
                20979 {
                20980     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
                20981     xmlSchemaTreeItemPtr item, *items;
                20982     int nbItems, i, ret = 0;
                20983     xmlSchemaBucketPtr oldbucket = con->bucket;
                20984     xmlSchemaElementPtr elemDecl;
                20985 
                20986 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
                20987 
                20988     if ((con->pending == NULL) ||
                20989     (con->pending->nbItems == 0))
                20990     return(0);
                20991 
                20992     /*
                20993     * Since xmlSchemaFixupComplexType() will create new particles
                20994     * (local components), and those particle components need a bucket
                20995     * on the constructor, we'll assure here that the constructor has
                20996     * a bucket.
                20997     * TODO: Think about storing locals _only_ on the main bucket.
                20998     */
                20999     if (con->bucket == NULL)
                21000     con->bucket = rootBucket;
                21001 
                21002     /* TODO:
                21003     * SPEC (src-redefine):
                21004     * (6.2) "If it has no such self-reference, then all of the
                21005     * following must be true:"
                21006 
                21007     * (6.2.2) The {model group} of the model group definition which
                21008     * corresponds to it per XML Representation of Model Group
                21009     * Definition Schema Components ($3.7.2) must be a `valid
                21010     * restriction` of the {model group} of that model group definition
                21011     * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
                21012     */
                21013     xmlSchemaCheckSRCRedefineFirst(pctxt);
                21014 
                21015     /*
                21016     * Add global components to the schemata's hash tables.
                21017     */
                21018     xmlSchemaAddComponents(pctxt, rootBucket);
                21019 
                21020     pctxt->ctxtType = NULL;
                21021     items = (xmlSchemaTreeItemPtr *) con->pending->items;
                21022     nbItems = con->pending->nbItems;
                21023     /*
                21024     * Now that we have parsed *all* the schema document(s) and converted
                21025     * them to schema components, we can resolve references, apply component
                21026     * constraints, create the FSA from the content model, etc.
                21027     */
                21028     /*
                21029     * Resolve references of..
                21030     *
                21031     * 1. element declarations:
                21032     *   - the type definition
                21033     *   - the substitution group affiliation
                21034     * 2. simple/complex types:
                21035     *   - the base type definition
                21036     *   - the memberTypes of union types
                21037     *   - the itemType of list types
                21038     * 3. attributes declarations and attribute uses:
                21039     *   - the type definition
                21040     *   - if an attribute use, then the attribute declaration
                21041     * 4. attribute group references:
                21042     *   - the attribute group definition
                21043     * 5. particles:
                21044     *   - the term of the particle (e.g. a model group)
                21045     * 6. IDC key-references:
                21046     *   - the referenced IDC 'key' or 'unique' definition
                21047     * 7. Attribute prohibitions which had a "ref" attribute.
                21048     */
                21049     for (i = 0; i < nbItems; i++) {
                21050     item = items[i];
                21051     switch (item->type) {
                21052         case XML_SCHEMA_TYPE_ELEMENT:
                21053         xmlSchemaResolveElementReferences(
                21054             (xmlSchemaElementPtr) item, pctxt);
                21055         FIXHFAILURE;
                21056         break;
                21057         case XML_SCHEMA_TYPE_COMPLEX:
                21058         case XML_SCHEMA_TYPE_SIMPLE:
                21059         xmlSchemaResolveTypeReferences(
                21060             (xmlSchemaTypePtr) item, pctxt);
                21061         FIXHFAILURE;
                21062         break;
                21063         case XML_SCHEMA_TYPE_ATTRIBUTE:
                21064         xmlSchemaResolveAttrTypeReferences(
                21065             (xmlSchemaAttributePtr) item, pctxt);
                21066         FIXHFAILURE;
                21067         break;
                21068         case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                21069         xmlSchemaResolveAttrUseReferences(
                21070             (xmlSchemaAttributeUsePtr) item, pctxt);
                21071         FIXHFAILURE;
                21072         break;
                21073         case XML_SCHEMA_EXTRA_QNAMEREF:
                21074         if ((WXS_QNAME_CAST item)->itemType ==
                21075             XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
                21076         {
                21077             xmlSchemaResolveAttrGroupReferences(
                21078             WXS_QNAME_CAST item, pctxt);
                21079         }
                21080         FIXHFAILURE;
                21081         break;
                21082         case XML_SCHEMA_TYPE_SEQUENCE:
                21083         case XML_SCHEMA_TYPE_CHOICE:
                21084         case XML_SCHEMA_TYPE_ALL:
                21085         xmlSchemaResolveModelGroupParticleReferences(pctxt,
                21086             WXS_MODEL_GROUP_CAST item);
                21087         FIXHFAILURE;
                21088         break;
                21089         case XML_SCHEMA_TYPE_IDC_KEY:
                21090         case XML_SCHEMA_TYPE_IDC_UNIQUE:
                21091         case XML_SCHEMA_TYPE_IDC_KEYREF:
                21092         xmlSchemaResolveIDCKeyReferences(
                21093             (xmlSchemaIDCPtr) item, pctxt);
                21094         FIXHFAILURE;
                21095         break;
                21096         case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
                21097         /*
                21098         * Handle attribute prohibition which had a
                21099         * "ref" attribute.
                21100         */
                21101         xmlSchemaResolveAttrUseProhibReferences(
                21102             WXS_ATTR_PROHIB_CAST item, pctxt);
                21103         FIXHFAILURE;
                21104         break;
                21105         default:
                21106         break;
                21107     }
                21108     }
                21109     if (pctxt->nberrors != 0)
                21110     goto exit_error;
                21111 
                21112     /*
                21113     * Now that all references are resolved we
                21114     * can check for circularity of...
                21115     * 1. the base axis of type definitions
                21116     * 2. nested model group definitions
                21117     * 3. nested attribute group definitions
                21118     * TODO: check for circular substitution groups.
                21119     */
                21120     for (i = 0; i < nbItems; i++) {
                21121     item = items[i];
                21122     /*
                21123     * Let's better stop on the first error here.
                21124     */
                21125     switch (item->type) {
                21126         case XML_SCHEMA_TYPE_COMPLEX:
                21127         case XML_SCHEMA_TYPE_SIMPLE:
                21128         xmlSchemaCheckTypeDefCircular(
                21129             (xmlSchemaTypePtr) item, pctxt);
                21130         FIXHFAILURE;
                21131         if (pctxt->nberrors != 0)
                21132             goto exit_error;
                21133         break;
                21134         case XML_SCHEMA_TYPE_GROUP:
                21135         xmlSchemaCheckGroupDefCircular(
                21136             (xmlSchemaModelGroupDefPtr) item, pctxt);
                21137         FIXHFAILURE;
                21138         if (pctxt->nberrors != 0)
                21139             goto exit_error;
                21140         break;
                21141         case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                21142         xmlSchemaCheckAttrGroupCircular(
                21143             (xmlSchemaAttributeGroupPtr) item, pctxt);
                21144         FIXHFAILURE;
                21145         if (pctxt->nberrors != 0)
                21146             goto exit_error;
                21147         break;
                21148         default:
                21149         break;
                21150     }
                21151     }
                21152     if (pctxt->nberrors != 0)
                21153     goto exit_error;
                21154     /*
                21155     * Model group definition references:
                21156     * Such a reference is reflected by a particle at the component
                21157     * level. Until now the 'term' of such particles pointed
                21158     * to the model group definition; this was done, in order to
                21159     * ease circularity checks. Now we need to set the 'term' of
                21160     * such particles to the model group of the model group definition.
                21161     */
                21162     for (i = 0; i < nbItems; i++) {
                21163     item = items[i];
                21164     switch (item->type) {
                21165         case XML_SCHEMA_TYPE_SEQUENCE:
                21166         case XML_SCHEMA_TYPE_CHOICE:
                21167         xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
                21168             WXS_MODEL_GROUP_CAST item);
                21169         break;
                21170         default:
                21171         break;
                21172     }
                21173     }
                21174     if (pctxt->nberrors != 0)
                21175     goto exit_error;
                21176     /*
                21177     * Expand attribute group references of attribute group definitions.
                21178     */
                21179     for (i = 0; i < nbItems; i++) {
                21180     item = items[i];
                21181     switch (item->type) {
                21182             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                21183         if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
                21184             WXS_ATTR_GROUP_HAS_REFS(item))
                21185         {
                21186             xmlSchemaAttributeGroupExpandRefs(pctxt,
                21187             WXS_ATTR_GROUP_CAST item);
                21188             FIXHFAILURE;
                21189         }
                21190         break;
                21191         default:
                21192         break;
                21193     }
                21194     }
                21195     if (pctxt->nberrors != 0)
                21196     goto exit_error;
                21197     /*
                21198     * First compute the variety of simple types. This is needed as
                21199     * a separate step, since otherwise we won't be able to detect
                21200     * circular union types in all cases.
                21201     */
                21202     for (i = 0; i < nbItems; i++) {
                21203     item = items[i];
                21204     switch (item->type) {
                21205             case XML_SCHEMA_TYPE_SIMPLE:
                21206         if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
                21207             xmlSchemaFixupSimpleTypeStageOne(pctxt,
                21208             (xmlSchemaTypePtr) item);
                21209             FIXHFAILURE;
                21210         }
                21211         break;
                21212         default:
                21213         break;
                21214     }
                21215     }
                21216     if (pctxt->nberrors != 0)
                21217     goto exit_error;
                21218     /*
                21219     * Detect circular union types. Note that this needs the variety to
                21220     * be already computed.
                21221     */
                21222     for (i = 0; i < nbItems; i++) {
                21223     item = items[i];
                21224     switch (item->type) {
                21225             case XML_SCHEMA_TYPE_SIMPLE:
                21226         if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
                21227             xmlSchemaCheckUnionTypeDefCircular(pctxt,
                21228             (xmlSchemaTypePtr) item);
                21229             FIXHFAILURE;
                21230         }
                21231         break;
                21232         default:
                21233         break;
                21234     }
                21235     }
                21236     if (pctxt->nberrors != 0)
                21237     goto exit_error;
                21238 
                21239     /*
                21240     * Do the complete type fixup for simple types.
                21241     */
                21242     for (i = 0; i < nbItems; i++) {
                21243     item = items[i];
                21244     switch (item->type) {
                21245             case XML_SCHEMA_TYPE_SIMPLE:
                21246         if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
                21247             xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
                21248             FIXHFAILURE;
                21249         }
                21250         break;
                21251         default:
                21252         break;
                21253     }
                21254     }
                21255     if (pctxt->nberrors != 0)
                21256     goto exit_error;
                21257     /*
                21258     * At this point we need build and check all simple types.
                21259     */
                21260     /*
                21261     * Apply constraints for attribute declarations.
                21262     */
                21263     for (i = 0; i < nbItems; i++) {
                21264     item = items[i];
                21265     switch (item->type) {
                21266         case XML_SCHEMA_TYPE_ATTRIBUTE:
                21267         xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
                21268         FIXHFAILURE;
                21269         break;
                21270         default:
                21271         break;
                21272     }
                21273     }
                21274     if (pctxt->nberrors != 0)
                21275     goto exit_error;
                21276     /*
                21277     * Apply constraints for attribute uses.
                21278     */
                21279     for (i = 0; i < nbItems; i++) {
                21280     item = items[i];
                21281     switch (item->type) {
                21282         case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
                21283         if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
                21284             xmlSchemaCheckAttrUsePropsCorrect(pctxt,
                21285             WXS_ATTR_USE_CAST item);
                21286             FIXHFAILURE;
                21287         }
                21288         break;
                21289         default:
                21290         break;
                21291     }
                21292     }
                21293     if (pctxt->nberrors != 0)
                21294     goto exit_error;
                21295 
                21296     /*
                21297     * Apply constraints for attribute group definitions.
                21298     */
                21299     for (i = 0; i < nbItems; i++) {
                21300     item = items[i];
                21301     switch (item->type) {
                21302     case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
                21303         if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
                21304         ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
                21305         {
                21306         xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
                21307         FIXHFAILURE;
                21308         }
                21309         break;
                21310     default:
                21311         break;
                21312     }
                21313     }
                21314     if (pctxt->nberrors != 0)
                21315     goto exit_error;
                21316 
                21317     /*
                21318     * Apply constraints for redefinitions.
                21319     */
                21320     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
                21321     xmlSchemaCheckSRCRedefineSecond(pctxt);
                21322     if (pctxt->nberrors != 0)
                21323     goto exit_error;
                21324 
                21325     /*
                21326     * Complex types are built and checked.
                21327     */
                21328     for (i = 0; i < nbItems; i++) {
                21329     item = con->pending->items[i];
                21330     switch (item->type) {
                21331         case XML_SCHEMA_TYPE_COMPLEX:
                21332         if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
                21333             xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
                21334             FIXHFAILURE;
                21335         }
                21336         break;
                21337         default:
                21338         break;
                21339     }
                21340     }
                21341     if (pctxt->nberrors != 0)
                21342     goto exit_error;
                21343 
                21344     /*
                21345     * The list could have changed, since xmlSchemaFixupComplexType()
                21346     * will create particles and model groups in some cases.
                21347     */
                21348     items = (xmlSchemaTreeItemPtr *) con->pending->items;
                21349     nbItems = con->pending->nbItems;
                21350 
                21351     /*
                21352     * Apply some constraints for element declarations.
                21353     */
                21354     for (i = 0; i < nbItems; i++) {
                21355     item = items[i];
                21356     switch (item->type) {
                21357         case XML_SCHEMA_TYPE_ELEMENT:
                21358         elemDecl = (xmlSchemaElementPtr) item;
                21359 
                21360         if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
                21361         {
                21362             xmlSchemaCheckElementDeclComponent(
                21363             (xmlSchemaElementPtr) elemDecl, pctxt);
                21364             FIXHFAILURE;
                21365         }
                21366 
                21367 #ifdef WXS_ELEM_DECL_CONS_ENABLED
                21368         /*
                21369         * Schema Component Constraint: Element Declarations Consistent
                21370         * Apply this constraint to local types of element declarations.
                21371         */
                21372         if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
                21373             (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
                21374             (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
                21375         {
                21376             xmlSchemaCheckElementDeclConsistent(pctxt,
                21377             WXS_BASIC_CAST elemDecl,
                21378             WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
                21379             NULL, NULL, 0);
                21380         }
                21381 #endif
                21382         break;
                21383         default:
                21384         break;
                21385     }
                21386     }
                21387     if (pctxt->nberrors != 0)
                21388     goto exit_error;
                21389 
                21390     /*
                21391     * Finally we can build the automaton from the content model of
                21392     * complex types.
                21393     */
                21394 
                21395     for (i = 0; i < nbItems; i++) {
                21396     item = items[i];
                21397     switch (item->type) {
                21398         case XML_SCHEMA_TYPE_COMPLEX:
                21399         xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
                21400         /* FIXHFAILURE; */
                21401         break;
                21402         default:
                21403         break;
                21404     }
                21405     }
                21406     if (pctxt->nberrors != 0)
                21407     goto exit_error;
                21408     /*
                21409     * URGENT TODO: cos-element-consistent
                21410     */
                21411     goto exit;
                21412 
                21413 exit_error:
                21414     ret = pctxt->err;
                21415     goto exit;
                21416 
                21417 exit_failure:
                21418     ret = -1;
                21419 
                21420 exit:
                21421     /*
                21422     * Reset the constructor. This is needed for XSI acquisition, since
                21423     * those items will be processed over and over again for every XSI
                21424     * if not cleared here.
                21425     */
                21426     con->bucket = oldbucket;
                21427     con->pending->nbItems = 0;
                21428     if (con->substGroups != NULL) {
                21429     xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
                21430     con->substGroups = NULL;
                21431     }
                21432     if (con->redefs != NULL) {
                21433     xmlSchemaRedefListFree(con->redefs);
                21434     con->redefs = NULL;
                21435     }
                21436     return(ret);
                21437 }
                21438 /**
                21439  * xmlSchemaParse:
                21440  * @ctxt:  a schema validation context
                21441  *
                21442  * parse a schema definition resource and build an internal
                21443  * XML Schema structure which can be used to validate instances.
                21444  *
                21445  * Returns the internal XML Schema structure built from the resource or
                21446  *         NULL in case of error
                21447  */
                21448 xmlSchemaPtr
                21449 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
                21450 {
                21451     xmlSchemaPtr mainSchema = NULL;
                21452     xmlSchemaBucketPtr bucket = NULL;
                21453     int res;
                21454 
                21455     /*
                21456     * This one is used if the schema to be parsed was specified via
                21457     * the API; i.e. not automatically by the validated instance document.
                21458     */
                21459 
ad7b9726c Alex*21460     if (xmlSchemaInitTypes() < 0)
                21461         return (NULL);
9d9d4fcc3 Alex*21462 
                21463     if (ctxt == NULL)
                21464         return (NULL);
                21465 
                21466     /* TODO: Init the context. Is this all we need?*/
                21467     ctxt->nberrors = 0;
                21468     ctxt->err = 0;
                21469     ctxt->counter = 0;
                21470 
                21471     /* Create the *main* schema. */
                21472     mainSchema = xmlSchemaNewSchema(ctxt);
                21473     if (mainSchema == NULL)
                21474     goto exit_failure;
                21475     /*
                21476     * Create the schema constructor.
                21477     */
                21478     if (ctxt->constructor == NULL) {
                21479     ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
                21480     if (ctxt->constructor == NULL)
ad7b9726c Alex*21481         goto exit_failure;
9d9d4fcc3 Alex*21482     /* Take ownership of the constructor to be able to free it. */
                21483     ctxt->ownsConstructor = 1;
                21484     }
                21485     ctxt->constructor->mainSchema = mainSchema;
                21486     /*
                21487     * Locate and add the schema document.
                21488     */
                21489     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
                21490     ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
                21491     NULL, NULL, &bucket);
                21492     if (res == -1)
                21493     goto exit_failure;
                21494     if (res != 0)
                21495     goto exit;
                21496 
                21497     if (bucket == NULL) {
                21498     /* TODO: Error code, actually we failed to *locate* the schema. */
                21499     if (ctxt->URL)
                21500         xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
                21501         NULL, NULL,
                21502         "Failed to locate the main schema resource at '%s'",
                21503         ctxt->URL, NULL);
                21504     else
                21505         xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
                21506         NULL, NULL,
                21507         "Failed to locate the main schema resource",
                21508             NULL, NULL);
                21509     goto exit;
                21510     }
                21511     /* Then do the parsing for good. */
                21512     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
                21513     goto exit_failure;
                21514     if (ctxt->nberrors != 0)
                21515     goto exit;
                21516 
                21517     mainSchema->doc = bucket->doc;
                21518     mainSchema->preserve = ctxt->preserve;
                21519 
                21520     ctxt->schema = mainSchema;
                21521 
                21522     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
                21523     goto exit_failure;
                21524 
                21525     /*
                21526     * TODO: This is not nice, since we cannot distinguish from the
                21527     * result if there was an internal error or not.
                21528     */
                21529 exit:
                21530     if (ctxt->nberrors != 0) {
                21531     if (mainSchema) {
                21532         xmlSchemaFree(mainSchema);
                21533         mainSchema = NULL;
                21534     }
                21535     if (ctxt->constructor) {
                21536         xmlSchemaConstructionCtxtFree(ctxt->constructor);
                21537         ctxt->constructor = NULL;
                21538         ctxt->ownsConstructor = 0;
                21539     }
                21540     }
                21541     ctxt->schema = NULL;
                21542     return(mainSchema);
                21543 exit_failure:
                21544     /*
                21545     * Quite verbose, but should catch internal errors, which were
                21546     * not communicated.
                21547     */
                21548     if (mainSchema) {
                21549         xmlSchemaFree(mainSchema);
                21550     mainSchema = NULL;
                21551     }
                21552     if (ctxt->constructor) {
                21553     xmlSchemaConstructionCtxtFree(ctxt->constructor);
                21554     ctxt->constructor = NULL;
                21555     ctxt->ownsConstructor = 0;
                21556     }
                21557     PERROR_INT2("xmlSchemaParse",
                21558     "An internal error occurred");
                21559     ctxt->schema = NULL;
                21560     return(NULL);
                21561 }
                21562 
                21563 /**
                21564  * xmlSchemaSetParserErrors:
                21565  * @ctxt:  a schema validation context
                21566  * @err:  the error callback
                21567  * @warn:  the warning callback
                21568  * @ctx:  contextual data for the callbacks
                21569  *
                21570  * Set the callback functions used to handle errors for a validation context
                21571  */
                21572 void
                21573 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
                21574                          xmlSchemaValidityErrorFunc err,
                21575                          xmlSchemaValidityWarningFunc warn, void *ctx)
                21576 {
                21577     if (ctxt == NULL)
                21578         return;
                21579     ctxt->error = err;
                21580     ctxt->warning = warn;
                21581     ctxt->errCtxt = ctx;
                21582     if (ctxt->vctxt != NULL)
                21583     xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
                21584 }
                21585 
                21586 /**
                21587  * xmlSchemaSetParserStructuredErrors:
                21588  * @ctxt:  a schema parser context
                21589  * @serror:  the structured error function
                21590  * @ctx: the functions context
                21591  *
                21592  * Set the structured error callback
                21593  */
                21594 void
                21595 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
                21596                    xmlStructuredErrorFunc serror,
                21597                    void *ctx)
                21598 {
                21599     if (ctxt == NULL)
                21600     return;
                21601     ctxt->serror = serror;
                21602     ctxt->errCtxt = ctx;
                21603     if (ctxt->vctxt != NULL)
                21604     xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
                21605 }
                21606 
                21607 /**
                21608  * xmlSchemaGetParserErrors:
                21609  * @ctxt:  a XMl-Schema parser context
                21610  * @err: the error callback result
                21611  * @warn: the warning callback result
                21612  * @ctx: contextual data for the callbacks result
                21613  *
                21614  * Get the callback information used to handle errors for a parser context
                21615  *
                21616  * Returns -1 in case of failure, 0 otherwise
                21617  */
                21618 int
                21619 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
                21620              xmlSchemaValidityErrorFunc * err,
                21621              xmlSchemaValidityWarningFunc * warn, void **ctx)
                21622 {
                21623     if (ctxt == NULL)
                21624         return(-1);
                21625     if (err != NULL)
                21626         *err = ctxt->error;
                21627     if (warn != NULL)
                21628         *warn = ctxt->warning;
                21629     if (ctx != NULL)
                21630         *ctx = ctxt->errCtxt;
                21631     return(0);
                21632 }
                21633 
                21634 /**
                21635  * xmlSchemaFacetTypeToString:
                21636  * @type:  the facet type
                21637  *
                21638  * Convert the xmlSchemaTypeType to a char string.
                21639  *
                21640  * Returns the char string representation of the facet type if the
                21641  *     type is a facet and an "Internal Error" string otherwise.
                21642  */
                21643 static const xmlChar *
                21644 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
                21645 {
                21646     switch (type) {
                21647         case XML_SCHEMA_FACET_PATTERN:
                21648             return (BAD_CAST "pattern");
                21649         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
                21650             return (BAD_CAST "maxExclusive");
                21651         case XML_SCHEMA_FACET_MAXINCLUSIVE:
                21652             return (BAD_CAST "maxInclusive");
                21653         case XML_SCHEMA_FACET_MINEXCLUSIVE:
                21654             return (BAD_CAST "minExclusive");
                21655         case XML_SCHEMA_FACET_MININCLUSIVE:
                21656             return (BAD_CAST "minInclusive");
                21657         case XML_SCHEMA_FACET_WHITESPACE:
                21658             return (BAD_CAST "whiteSpace");
                21659         case XML_SCHEMA_FACET_ENUMERATION:
                21660             return (BAD_CAST "enumeration");
                21661         case XML_SCHEMA_FACET_LENGTH:
                21662             return (BAD_CAST "length");
                21663         case XML_SCHEMA_FACET_MAXLENGTH:
                21664             return (BAD_CAST "maxLength");
                21665         case XML_SCHEMA_FACET_MINLENGTH:
                21666             return (BAD_CAST "minLength");
                21667         case XML_SCHEMA_FACET_TOTALDIGITS:
                21668             return (BAD_CAST "totalDigits");
                21669         case XML_SCHEMA_FACET_FRACTIONDIGITS:
                21670             return (BAD_CAST "fractionDigits");
                21671         default:
                21672             break;
                21673     }
                21674     return (BAD_CAST "Internal Error");
                21675 }
                21676 
                21677 static xmlSchemaWhitespaceValueType
                21678 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
                21679 {
                21680     /*
                21681     * The normalization type can be changed only for types which are derived
                21682     * from xsd:string.
                21683     */
                21684     if (type->type == XML_SCHEMA_TYPE_BASIC) {
                21685     /*
                21686     * Note that we assume a whitespace of preserve for anySimpleType.
                21687     */
                21688     if ((type->builtInType == XML_SCHEMAS_STRING) ||
                21689         (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
                21690         return(XML_SCHEMA_WHITESPACE_PRESERVE);
                21691     else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
                21692         return(XML_SCHEMA_WHITESPACE_REPLACE);
                21693     else {
                21694         /*
                21695         * For all `atomic` datatypes other than string (and types `derived`
                21696         * by `restriction` from it) the value of whiteSpace is fixed to
                21697         * collapse
                21698         * Note that this includes built-in list datatypes.
                21699         */
                21700         return(XML_SCHEMA_WHITESPACE_COLLAPSE);
                21701     }
                21702     } else if (WXS_IS_LIST(type)) {
                21703     /*
                21704     * For list types the facet "whiteSpace" is fixed to "collapse".
                21705     */
                21706     return (XML_SCHEMA_WHITESPACE_COLLAPSE);
                21707     } else if (WXS_IS_UNION(type)) {
                21708     return (XML_SCHEMA_WHITESPACE_UNKNOWN);
                21709     } else if (WXS_IS_ATOMIC(type)) {
                21710     if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
                21711         return (XML_SCHEMA_WHITESPACE_PRESERVE);
                21712     else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
                21713         return (XML_SCHEMA_WHITESPACE_REPLACE);
                21714     else
                21715         return (XML_SCHEMA_WHITESPACE_COLLAPSE);
                21716     }
                21717     return (-1);
                21718 }
                21719 
                21720 /************************************************************************
                21721  *                                  *
                21722  *          Simple type validation              *
                21723  *                                  *
                21724  ************************************************************************/
                21725 
                21726 
                21727 /************************************************************************
                21728  *                                  *
                21729  *          DOM Validation code             *
                21730  *                                  *
                21731  ************************************************************************/
                21732 
                21733 /**
                21734  * xmlSchemaAssembleByLocation:
                21735  * @pctxt:  a schema parser context
                21736  * @vctxt:  a schema validation context
                21737  * @schema: the existing schema
                21738  * @node: the node that fired the assembling
                21739  * @nsName: the namespace name of the new schema
                21740  * @location: the location of the schema
                21741  *
                21742  * Expands an existing schema by an additional schema.
                21743  *
                21744  * Returns 0 if the new schema is correct, a positive error code
                21745  * number otherwise and -1 in case of an internal or API error.
                21746  */
                21747 static int
                21748 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
                21749                 xmlSchemaPtr schema,
                21750                 xmlNodePtr node,
                21751                 const xmlChar *nsName,
                21752                 const xmlChar *location)
                21753 {
                21754     int ret = 0;
                21755     xmlSchemaParserCtxtPtr pctxt;
                21756     xmlSchemaBucketPtr bucket = NULL;
                21757 
                21758     if ((vctxt == NULL) || (schema == NULL))
                21759     return (-1);
                21760 
                21761     if (vctxt->pctxt == NULL) {
                21762     VERROR_INT("xmlSchemaAssembleByLocation",
                21763         "no parser context available");
                21764     return(-1);
                21765     }
                21766     pctxt = vctxt->pctxt;
                21767     if (pctxt->constructor == NULL) {
                21768     PERROR_INT("xmlSchemaAssembleByLocation",
                21769         "no constructor");
                21770     return(-1);
                21771     }
                21772     /*
                21773     * Acquire the schema document.
                21774     */
                21775     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
                21776     location, node);
                21777     /*
                21778     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
                21779     * the process will automatically change this to
                21780     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
                21781     */
                21782     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
                21783     location, NULL, NULL, 0, node, NULL, nsName,
                21784     &bucket);
                21785     if (ret != 0)
                21786     return(ret);
                21787     if (bucket == NULL) {
                21788     /*
                21789     * Generate a warning that the document could not be located.
                21790     */
                21791     xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
                21792         node, NULL,
                21793         "The document at location '%s' could not be acquired",
                21794         location, NULL, NULL);
                21795     return(ret);
                21796     }
                21797     /*
                21798     * The first located schema will be handled as if all other
                21799     * schemas imported by XSI were imported by this first schema.
                21800     */
                21801     if ((bucket != NULL) &&
                21802     (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
                21803     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
                21804     /*
                21805     * TODO: Is this handled like an import? I.e. is it not an error
                21806     * if the schema cannot be located?
                21807     */
                21808     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
                21809     return(0);
                21810     /*
                21811     * We will reuse the parser context for every schema imported
                21812     * directly via XSI. So reset the context.
                21813     */
                21814     pctxt->nberrors = 0;
                21815     pctxt->err = 0;
                21816     pctxt->doc = bucket->doc;
                21817 
                21818     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
                21819     if (ret == -1) {
                21820     pctxt->doc = NULL;
                21821     goto exit_failure;
                21822     }
                21823     /* Paranoid error channelling. */
                21824     if ((ret == 0) && (pctxt->nberrors != 0))
                21825     ret = pctxt->err;
                21826     if (pctxt->nberrors == 0) {
                21827     /*
                21828     * Only bother to fixup pending components, if there was
                21829     * no error yet.
                21830     * For every XSI acquired schema (and its sub-schemata) we will
                21831     * fixup the components.
                21832     */
                21833     xmlSchemaFixupComponents(pctxt, bucket);
                21834     ret = pctxt->err;
                21835     /*
                21836     * Not nice, but we need somehow to channel the schema parser
                21837     * error to the validation context.
                21838     */
                21839     if ((ret != 0) && (vctxt->err == 0))
                21840         vctxt->err = ret;
                21841     vctxt->nberrors += pctxt->nberrors;
                21842     } else {
                21843     /* Add to validation error sum. */
                21844     vctxt->nberrors += pctxt->nberrors;
                21845     }
                21846     pctxt->doc = NULL;
                21847     return(ret);
                21848 exit_failure:
                21849     pctxt->doc = NULL;
                21850     return (-1);
                21851 }
                21852 
                21853 static xmlSchemaAttrInfoPtr
                21854 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
                21855              int metaType)
                21856 {
                21857     if (vctxt->nbAttrInfos == 0)
                21858     return (NULL);
                21859     {
                21860     int i;
                21861     xmlSchemaAttrInfoPtr iattr;
                21862 
                21863     for (i = 0; i < vctxt->nbAttrInfos; i++) {
                21864         iattr = vctxt->attrInfos[i];
                21865         if (iattr->metaType == metaType)
                21866         return (iattr);
                21867     }
                21868 
                21869     }
                21870     return (NULL);
                21871 }
                21872 
                21873 /**
                21874  * xmlSchemaAssembleByXSI:
                21875  * @vctxt:  a schema validation context
                21876  *
                21877  * Expands an existing schema by an additional schema using
                21878  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
                21879  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
                21880  * must be set to 1.
                21881  *
                21882  * Returns 0 if the new schema is correct, a positive error code
                21883  * number otherwise and -1 in case of an internal or API error.
                21884  */
                21885 static int
                21886 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
                21887 {
                21888     const xmlChar *cur, *end;
                21889     const xmlChar *nsname = NULL, *location;
                21890     int ret = 0;
                21891     xmlSchemaAttrInfoPtr iattr;
                21892 
                21893     /*
                21894     * Parse the value; we will assume an even number of values
                21895     * to be given (this is how Xerces and XSV work).
                21896     *
                21897     * URGENT TODO: !! This needs to work for both
                21898     * @noNamespaceSchemaLocation AND @schemaLocation on the same
                21899     * element !!
                21900     */
                21901     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
                21902     XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
                21903     if (iattr == NULL)
                21904     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
                21905     XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
                21906     if (iattr == NULL)
                21907     return (0);
                21908     cur = iattr->value;
                21909     do {
                21910     /*
                21911     * TODO: Move the string parsing mechanism away from here.
                21912     */
                21913     if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
                21914         /*
                21915         * Get the namespace name.
                21916         */
                21917         while (IS_BLANK_CH(*cur))
                21918         cur++;
                21919         end = cur;
                21920         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                21921         end++;
                21922         if (end == cur)
                21923         break;
ad7b9726c Alex*21924         /* TODO: Don't use the schema's dict. */
9d9d4fcc3 Alex*21925         nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
                21926         cur = end;
                21927     }
                21928     /*
                21929     * Get the URI.
                21930     */
                21931     while (IS_BLANK_CH(*cur))
                21932         cur++;
                21933     end = cur;
                21934     while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                21935         end++;
                21936     if (end == cur) {
                21937         if (iattr->metaType ==
                21938         XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
                21939         {
                21940         /*
                21941         * If using @schemaLocation then tuples are expected.
                21942         * I.e. the namespace name *and* the document's URI.
                21943         */
                21944         xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
                21945             iattr->node, NULL,
                21946             "The value must consist of tuples: the target namespace "
                21947             "name and the document's URI", NULL, NULL, NULL);
                21948         }
                21949         break;
                21950     }
ad7b9726c Alex*21951     /* TODO: Don't use the schema's dict. */
9d9d4fcc3 Alex*21952     location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
                21953     cur = end;
                21954     ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
                21955         iattr->node, nsname, location);
                21956     if (ret == -1) {
                21957         VERROR_INT("xmlSchemaAssembleByXSI",
                21958         "assembling schemata");
                21959         return (-1);
                21960     }
                21961     } while (*cur != 0);
                21962     return (ret);
                21963 }
                21964 
                21965 static const xmlChar *
                21966 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
                21967              const xmlChar *prefix)
                21968 {
                21969     if (vctxt->sax != NULL) {
                21970     int i, j;
                21971     xmlSchemaNodeInfoPtr inode;
                21972 
                21973     for (i = vctxt->depth; i >= 0; i--) {
                21974         if (vctxt->elemInfos[i]->nbNsBindings != 0) {
                21975         inode = vctxt->elemInfos[i];
                21976         for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
                21977             if (((prefix == NULL) &&
                21978                 (inode->nsBindings[j] == NULL)) ||
                21979             ((prefix != NULL) && xmlStrEqual(prefix,
                21980                 inode->nsBindings[j]))) {
                21981 
                21982             /*
                21983             * Note that the namespace bindings are already
                21984             * in a string dict.
                21985             */
                21986             return (inode->nsBindings[j+1]);
                21987             }
                21988         }
                21989         }
                21990     }
                21991     return (NULL);
                21992 #ifdef LIBXML_READER_ENABLED
                21993     } else if (vctxt->reader != NULL) {
                21994     xmlChar *nsName;
                21995 
                21996     nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
                21997     if (nsName != NULL) {
                21998         const xmlChar *ret;
                21999 
                22000         ret = xmlDictLookup(vctxt->dict, nsName, -1);
                22001         xmlFree(nsName);
                22002         return (ret);
                22003     } else
                22004         return (NULL);
                22005 #endif
                22006     } else {
                22007     xmlNsPtr ns;
                22008 
                22009     if ((vctxt->inode->node == NULL) ||
                22010         (vctxt->inode->node->doc == NULL)) {
                22011         VERROR_INT("xmlSchemaLookupNamespace",
                22012         "no node or node's doc available");
                22013         return (NULL);
                22014     }
                22015     ns = xmlSearchNs(vctxt->inode->node->doc,
                22016         vctxt->inode->node, prefix);
                22017     if (ns != NULL)
                22018         return (ns->href);
                22019     return (NULL);
                22020     }
                22021 }
                22022 
                22023 /*
                22024 * This one works on the schema of the validation context.
                22025 */
                22026 static int
                22027 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
                22028               xmlSchemaPtr schema,
                22029               xmlNodePtr node,
                22030               const xmlChar *value,
                22031               xmlSchemaValPtr *val,
                22032               int valNeeded)
                22033 {
                22034     int ret;
                22035 
                22036     if (vctxt && (vctxt->schema == NULL)) {
                22037     VERROR_INT("xmlSchemaValidateNotation",
                22038         "a schema is needed on the validation context");
                22039     return (-1);
                22040     }
                22041     ret = xmlValidateQName(value, 1);
                22042     if (ret != 0)
                22043     return (ret);
                22044     {
                22045     xmlChar *localName = NULL;
                22046     xmlChar *prefix = NULL;
                22047 
                22048     localName = xmlSplitQName2(value, &prefix);
                22049     if (prefix != NULL) {
                22050         const xmlChar *nsName = NULL;
                22051 
                22052         if (vctxt != NULL)
                22053         nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
                22054         else if (node != NULL) {
                22055         xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
                22056         if (ns != NULL)
                22057             nsName = ns->href;
                22058         } else {
                22059         xmlFree(prefix);
                22060         xmlFree(localName);
                22061         return (1);
                22062         }
                22063         if (nsName == NULL) {
                22064         xmlFree(prefix);
                22065         xmlFree(localName);
                22066         return (1);
                22067         }
                22068         if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
                22069         if ((valNeeded) && (val != NULL)) {
                22070             (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
                22071                                xmlStrdup(nsName));
                22072             if (*val == NULL)
                22073             ret = -1;
                22074         }
                22075         } else
                22076         ret = 1;
                22077         xmlFree(prefix);
                22078         xmlFree(localName);
                22079     } else {
                22080         if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
                22081         if (valNeeded && (val != NULL)) {
                22082             (*val) = xmlSchemaNewNOTATIONValue(
                22083             BAD_CAST xmlStrdup(value), NULL);
                22084             if (*val == NULL)
                22085             ret = -1;
                22086         }
                22087         } else
                22088         return (1);
                22089     }
                22090     }
                22091     return (ret);
                22092 }
                22093 
                22094 static int
                22095 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
                22096                const xmlChar* lname,
                22097                const xmlChar* nsname)
                22098 {
                22099     int i;
                22100 
                22101     lname = xmlDictLookup(vctxt->dict, lname, -1);
                22102     if (lname == NULL)
                22103     return(-1);
                22104     if (nsname != NULL) {
                22105     nsname = xmlDictLookup(vctxt->dict, nsname, -1);
                22106     if (nsname == NULL)
                22107         return(-1);
                22108     }
                22109     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
                22110     if ((vctxt->nodeQNames->items [i] == lname) &&
                22111         (vctxt->nodeQNames->items[i +1] == nsname))
                22112         /* Already there */
                22113         return(i);
                22114     }
                22115     /* Add new entry. */
                22116     i = vctxt->nodeQNames->nbItems;
                22117     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
                22118     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
                22119     return(i);
                22120 }
                22121 
                22122 /************************************************************************
                22123  *                                  *
                22124  *  Validation of identity-constraints (IDC)                            *
                22125  *                                  *
                22126  ************************************************************************/
                22127 
                22128 /**
                22129  * xmlSchemaAugmentIDC:
                22130  * @idcDef: the IDC definition
                22131  *
                22132  * Creates an augmented IDC definition item.
                22133  *
                22134  * Returns the item, or NULL on internal errors.
                22135  */
                22136 static void
                22137 xmlSchemaAugmentIDC(void *payload, void *data,
                22138                     const xmlChar *name ATTRIBUTE_UNUSED)
                22139 {
                22140     xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
                22141     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
                22142     xmlSchemaIDCAugPtr aidc;
                22143 
                22144     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
                22145     if (aidc == NULL) {
                22146     xmlSchemaVErrMemory(vctxt,
                22147         "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
                22148         NULL);
                22149     return;
                22150     }
                22151     aidc->keyrefDepth = -1;
                22152     aidc->def = idcDef;
                22153     aidc->next = NULL;
                22154     if (vctxt->aidcs == NULL)
                22155     vctxt->aidcs = aidc;
                22156     else {
                22157     aidc->next = vctxt->aidcs;
                22158     vctxt->aidcs = aidc;
                22159     }
                22160     /*
                22161     * Save if we have keyrefs at all.
                22162     */
                22163     if ((vctxt->hasKeyrefs == 0) &&
                22164     (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
                22165     vctxt->hasKeyrefs = 1;
                22166 }
                22167 
                22168 /**
                22169  * xmlSchemaAugmentImportedIDC:
                22170  * @imported: the imported schema
                22171  *
                22172  * Creates an augmented IDC definition for the imported schema.
                22173  */
                22174 static void
                22175 xmlSchemaAugmentImportedIDC(void *payload, void *data,
                22176                             const xmlChar *name ATTRIBUTE_UNUSED) {
                22177     xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
                22178     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
                22179     if (imported->schema->idcDef != NULL) {
                22180         xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
                22181     }
                22182 }
                22183 
                22184 /**
                22185  * xmlSchemaIDCNewBinding:
                22186  * @idcDef: the IDC definition of this binding
                22187  *
                22188  * Creates a new IDC binding.
                22189  *
                22190  * Returns the new IDC binding, NULL on internal errors.
                22191  */
                22192 static xmlSchemaPSVIIDCBindingPtr
                22193 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
                22194 {
                22195     xmlSchemaPSVIIDCBindingPtr ret;
                22196 
                22197     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
                22198         sizeof(xmlSchemaPSVIIDCBinding));
                22199     if (ret == NULL) {
                22200     xmlSchemaVErrMemory(NULL,
                22201         "allocating a PSVI IDC binding item", NULL);
                22202     return (NULL);
                22203     }
                22204     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
                22205     ret->definition = idcDef;
                22206     return (ret);
                22207 }
                22208 
                22209 /**
                22210  * xmlSchemaIDCStoreNodeTableItem:
                22211  * @vctxt: the WXS validation context
                22212  * @item: the IDC node table item
                22213  *
                22214  * The validation context is used to store IDC node table items.
                22215  * They are stored to avoid copying them if IDC node-tables are merged
                22216  * with corresponding parent IDC node-tables (bubbling).
                22217  *
                22218  * Returns 0 if succeeded, -1 on internal errors.
                22219  */
                22220 static int
                22221 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
                22222                    xmlSchemaPSVIIDCNodePtr item)
                22223 {
                22224     /*
                22225     * Add to global list.
                22226     */
                22227     if (vctxt->idcNodes == NULL) {
                22228     vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
                22229         xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
                22230     if (vctxt->idcNodes == NULL) {
                22231         xmlSchemaVErrMemory(vctxt,
                22232         "allocating the IDC node table item list", NULL);
                22233         return (-1);
                22234     }
                22235     vctxt->sizeIdcNodes = 20;
                22236     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
                22237     vctxt->sizeIdcNodes *= 2;
                22238     vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
                22239         xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
                22240         sizeof(xmlSchemaPSVIIDCNodePtr));
                22241     if (vctxt->idcNodes == NULL) {
                22242         xmlSchemaVErrMemory(vctxt,
                22243         "re-allocating the IDC node table item list", NULL);
                22244         return (-1);
                22245     }
                22246     }
                22247     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
                22248 
                22249     return (0);
                22250 }
                22251 
                22252 /**
                22253  * xmlSchemaIDCStoreKey:
                22254  * @vctxt: the WXS validation context
                22255  * @item: the IDC key
                22256  *
                22257  * The validation context is used to store an IDC key.
                22258  *
                22259  * Returns 0 if succeeded, -1 on internal errors.
                22260  */
                22261 static int
                22262 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
                22263              xmlSchemaPSVIIDCKeyPtr key)
                22264 {
                22265     /*
                22266     * Add to global list.
                22267     */
                22268     if (vctxt->idcKeys == NULL) {
                22269     vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
                22270         xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
                22271     if (vctxt->idcKeys == NULL) {
                22272         xmlSchemaVErrMemory(vctxt,
                22273         "allocating the IDC key storage list", NULL);
                22274         return (-1);
                22275     }
                22276     vctxt->sizeIdcKeys = 40;
                22277     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
                22278     vctxt->sizeIdcKeys *= 2;
                22279     vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
                22280         xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
                22281         sizeof(xmlSchemaPSVIIDCKeyPtr));
                22282     if (vctxt->idcKeys == NULL) {
                22283         xmlSchemaVErrMemory(vctxt,
                22284         "re-allocating the IDC key storage list", NULL);
                22285         return (-1);
                22286     }
                22287     }
                22288     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
                22289 
                22290     return (0);
                22291 }
                22292 
                22293 /**
                22294  * xmlSchemaIDCAppendNodeTableItem:
                22295  * @bind: the IDC binding
                22296  * @ntItem: the node-table item
                22297  *
                22298  * Appends the IDC node-table item to the binding.
                22299  *
                22300  * Returns 0 on success and -1 on internal errors.
                22301  */
                22302 static int
                22303 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
                22304                 xmlSchemaPSVIIDCNodePtr ntItem)
                22305 {
                22306     if (bind->nodeTable == NULL) {
                22307     bind->sizeNodes = 10;
                22308     bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
                22309         xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
                22310     if (bind->nodeTable == NULL) {
                22311         xmlSchemaVErrMemory(NULL,
                22312         "allocating an array of IDC node-table items", NULL);
                22313         return(-1);
                22314     }
                22315     } else if (bind->sizeNodes <= bind->nbNodes) {
                22316     bind->sizeNodes *= 2;
                22317     bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
                22318         xmlRealloc(bind->nodeTable, bind->sizeNodes *
                22319         sizeof(xmlSchemaPSVIIDCNodePtr));
                22320     if (bind->nodeTable == NULL) {
                22321         xmlSchemaVErrMemory(NULL,
                22322         "re-allocating an array of IDC node-table items", NULL);
                22323         return(-1);
                22324     }
                22325     }
                22326     bind->nodeTable[bind->nbNodes++] = ntItem;
                22327     return(0);
                22328 }
                22329 
                22330 /**
                22331  * xmlSchemaIDCAcquireBinding:
                22332  * @vctxt: the WXS validation context
                22333  * @matcher: the IDC matcher
                22334  *
                22335  * Looks up an PSVI IDC binding, for the IDC definition and
                22336  * of the given matcher. If none found, a new one is created
                22337  * and added to the IDC table.
                22338  *
                22339  * Returns an IDC binding or NULL on internal errors.
                22340  */
                22341 static xmlSchemaPSVIIDCBindingPtr
                22342 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
                22343               xmlSchemaIDCMatcherPtr matcher)
                22344 {
                22345     xmlSchemaNodeInfoPtr ielem;
                22346 
                22347     ielem = vctxt->elemInfos[matcher->depth];
                22348 
                22349     if (ielem->idcTable == NULL) {
                22350     ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
                22351     if (ielem->idcTable == NULL)
                22352         return (NULL);
                22353     return(ielem->idcTable);
                22354     } else {
                22355     xmlSchemaPSVIIDCBindingPtr bind = NULL;
                22356 
                22357     bind = ielem->idcTable;
                22358     do {
                22359         if (bind->definition == matcher->aidc->def)
                22360         return(bind);
                22361         if (bind->next == NULL) {
                22362         bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
                22363         if (bind->next == NULL)
                22364             return (NULL);
                22365         return(bind->next);
                22366         }
                22367         bind = bind->next;
                22368     } while (bind != NULL);
                22369     }
                22370     return (NULL);
                22371 }
                22372 
                22373 static xmlSchemaItemListPtr
                22374 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
                22375                  xmlSchemaIDCMatcherPtr matcher)
                22376 {
                22377     if (matcher->targets == NULL)
                22378     matcher->targets = xmlSchemaItemListCreate();
                22379     return(matcher->targets);
                22380 }
                22381 
                22382 /**
                22383  * xmlSchemaIDCFreeKey:
                22384  * @key: the IDC key
                22385  *
                22386  * Frees an IDC key together with its compiled value.
                22387  */
                22388 static void
                22389 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
                22390 {
                22391     if (key->val != NULL)
                22392     xmlSchemaFreeValue(key->val);
                22393     xmlFree(key);
                22394 }
                22395 
                22396 /**
                22397  * xmlSchemaIDCFreeBinding:
                22398  *
                22399  * Frees an IDC binding. Note that the node table-items
                22400  * are not freed.
                22401  */
                22402 static void
                22403 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
                22404 {
                22405     if (bind->nodeTable != NULL)
                22406     xmlFree(bind->nodeTable);
                22407     if (bind->dupls != NULL)
                22408     xmlSchemaItemListFree(bind->dupls);
                22409     xmlFree(bind);
                22410 }
                22411 
                22412 /**
                22413  * xmlSchemaIDCFreeIDCTable:
                22414  * @bind: the first IDC binding in the list
                22415  *
                22416  * Frees an IDC table, i.e. all the IDC bindings in the list.
                22417  */
                22418 static void
                22419 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
                22420 {
                22421     xmlSchemaPSVIIDCBindingPtr prev;
                22422 
                22423     while (bind != NULL) {
                22424     prev = bind;
                22425     bind = bind->next;
                22426     xmlSchemaIDCFreeBinding(prev);
                22427     }
                22428 }
                22429 
                22430 static void
                22431 xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
                22432 {
                22433     xmlIDCHashEntryPtr e = payload, n;
                22434     while (e) {
                22435     n = e->next;
                22436     xmlFree(e);
                22437     e = n;
                22438     }
                22439 }
                22440 
                22441 /**
                22442  * xmlSchemaIDCFreeMatcherList:
                22443  * @matcher: the first IDC matcher in the list
                22444  *
                22445  * Frees a list of IDC matchers.
                22446  */
                22447 static void
                22448 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
                22449 {
                22450     xmlSchemaIDCMatcherPtr next;
                22451 
                22452     while (matcher != NULL) {
                22453     next = matcher->next;
                22454     if (matcher->keySeqs != NULL) {
                22455         int i;
                22456         for (i = 0; i < matcher->sizeKeySeqs; i++)
                22457         if (matcher->keySeqs[i] != NULL)
                22458             xmlFree(matcher->keySeqs[i]);
                22459         xmlFree(matcher->keySeqs);
                22460     }
                22461     if (matcher->targets != NULL) {
                22462         if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
                22463         int i;
                22464         xmlSchemaPSVIIDCNodePtr idcNode;
                22465         /*
                22466         * Node-table items for keyrefs are not stored globally
                22467         * to the validation context, since they are not bubbled.
                22468         * We need to free them here.
                22469         */
                22470         for (i = 0; i < matcher->targets->nbItems; i++) {
                22471             idcNode =
                22472             (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
                22473             xmlFree(idcNode->keys);
                22474             xmlFree(idcNode);
                22475         }
                22476         }
                22477         xmlSchemaItemListFree(matcher->targets);
                22478     }
                22479     if (matcher->htab != NULL)
                22480       xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
                22481     xmlFree(matcher);
                22482     matcher = next;
                22483     }
                22484 }
                22485 
                22486 /**
                22487  * xmlSchemaIDCReleaseMatcherList:
                22488  * @vctxt: the WXS validation context
                22489  * @matcher: the first IDC matcher in the list
                22490  *
                22491  * Caches a list of IDC matchers for reuse.
                22492  */
                22493 static void
                22494 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
                22495                    xmlSchemaIDCMatcherPtr matcher)
                22496 {
                22497     xmlSchemaIDCMatcherPtr next;
                22498 
                22499     while (matcher != NULL) {
                22500     next = matcher->next;
                22501     if (matcher->keySeqs != NULL) {
                22502         int i;
                22503         /*
                22504         * Don't free the array, but only the content.
                22505         */
                22506         for (i = 0; i < matcher->sizeKeySeqs; i++)
                22507         if (matcher->keySeqs[i] != NULL) {
                22508             xmlFree(matcher->keySeqs[i]);
                22509             matcher->keySeqs[i] = NULL;
                22510         }
                22511     }
                22512     if (matcher->targets) {
                22513         if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
                22514         int i;
                22515         xmlSchemaPSVIIDCNodePtr idcNode;
                22516         /*
                22517         * Node-table items for keyrefs are not stored globally
                22518         * to the validation context, since they are not bubbled.
                22519         * We need to free them here.
                22520         */
                22521         for (i = 0; i < matcher->targets->nbItems; i++) {
                22522             idcNode =
                22523             (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
                22524             xmlFree(idcNode->keys);
                22525             xmlFree(idcNode);
                22526         }
                22527         }
                22528         xmlSchemaItemListFree(matcher->targets);
                22529         matcher->targets = NULL;
                22530     }
                22531     if (matcher->htab != NULL) {
                22532         xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
                22533         matcher->htab = NULL;
                22534     }
                22535     matcher->next = NULL;
                22536     /*
                22537     * Cache the matcher.
                22538     */
                22539     if (vctxt->idcMatcherCache != NULL)
                22540         matcher->nextCached = vctxt->idcMatcherCache;
                22541     vctxt->idcMatcherCache = matcher;
                22542 
                22543     matcher = next;
                22544     }
                22545 }
                22546 
                22547 /**
                22548  * xmlSchemaIDCAddStateObject:
                22549  * @vctxt: the WXS validation context
                22550  * @matcher: the IDC matcher
                22551  * @sel: the XPath information
                22552  * @parent: the parent "selector" state object if any
                22553  * @type: "selector" or "field"
                22554  *
                22555  * Creates/reuses and activates state objects for the given
                22556  * XPath information; if the XPath expression consists of unions,
                22557  * multiple state objects are created for every unioned expression.
                22558  *
                22559  * Returns 0 on success and -1 on internal errors.
                22560  */
                22561 static int
                22562 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
                22563             xmlSchemaIDCMatcherPtr matcher,
                22564             xmlSchemaIDCSelectPtr sel,
                22565             int type)
                22566 {
                22567     xmlSchemaIDCStateObjPtr sto;
                22568 
                22569     /*
                22570     * Reuse the state objects from the pool.
                22571     */
                22572     if (vctxt->xpathStatePool != NULL) {
                22573     sto = vctxt->xpathStatePool;
                22574     vctxt->xpathStatePool = sto->next;
                22575     sto->next = NULL;
                22576     } else {
                22577     /*
                22578     * Create a new state object.
                22579     */
                22580     sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
                22581     if (sto == NULL) {
                22582         xmlSchemaVErrMemory(NULL,
                22583         "allocating an IDC state object", NULL);
                22584         return (-1);
                22585     }
                22586     memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
                22587     }
                22588     /*
                22589     * Add to global list.
                22590     */
                22591     if (vctxt->xpathStates != NULL)
                22592     sto->next = vctxt->xpathStates;
                22593     vctxt->xpathStates = sto;
                22594 
                22595     /*
                22596     * Free the old xpath validation context.
                22597     */
                22598     if (sto->xpathCtxt != NULL)
                22599     xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
                22600 
                22601     /*
                22602     * Create a new XPath (pattern) validation context.
                22603     */
                22604     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
                22605     (xmlPatternPtr) sel->xpathComp);
                22606     if (sto->xpathCtxt == NULL) {
                22607     VERROR_INT("xmlSchemaIDCAddStateObject",
                22608         "failed to create an XPath validation context");
                22609     return (-1);
                22610     }
                22611     sto->type = type;
                22612     sto->depth = vctxt->depth;
                22613     sto->matcher = matcher;
                22614     sto->sel = sel;
                22615     sto->nbHistory = 0;
                22616 
                22617 #ifdef DEBUG_IDC
                22618     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
                22619     sto->sel->xpath);
                22620 #endif
                22621     return (0);
                22622 }
                22623 
                22624 /**
                22625  * xmlSchemaXPathEvaluate:
                22626  * @vctxt: the WXS validation context
                22627  * @nodeType: the nodeType of the current node
                22628  *
                22629  * Evaluates all active XPath state objects.
                22630  *
                22631  * Returns the number of IC "field" state objects which resolved to
                22632  * this node, 0 if none resolved and -1 on internal errors.
                22633  */
                22634 static int
                22635 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
                22636                xmlElementType nodeType)
                22637 {
                22638     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
                22639     int res, resolved = 0, depth = vctxt->depth;
                22640 
                22641     if (vctxt->xpathStates == NULL)
                22642     return (0);
                22643 
                22644     if (nodeType == XML_ATTRIBUTE_NODE)
                22645     depth++;
                22646 #ifdef DEBUG_IDC
                22647     {
                22648     xmlChar *str = NULL;
                22649     xmlGenericError(xmlGenericErrorContext,
                22650         "IDC: EVAL on %s, depth %d, type %d\n",
                22651         xmlSchemaFormatQName(&str, vctxt->inode->nsName,
                22652         vctxt->inode->localName), depth, nodeType);
                22653     FREE_AND_NULL(str)
                22654     }
                22655 #endif
                22656     /*
                22657     * Process all active XPath state objects.
                22658     */
                22659     first = vctxt->xpathStates;
                22660     sto = first;
                22661     while (sto != head) {
                22662 #ifdef DEBUG_IDC
                22663     if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
                22664         xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
                22665         sto->matcher->aidc->def->name, sto->sel->xpath);
                22666     else
                22667         xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
                22668         sto->matcher->aidc->def->name, sto->sel->xpath);
                22669 #endif
                22670     if (nodeType == XML_ELEMENT_NODE)
                22671         res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
                22672         vctxt->inode->localName, vctxt->inode->nsName);
                22673     else
                22674         res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
                22675         vctxt->inode->localName, vctxt->inode->nsName);
                22676 
                22677     if (res == -1) {
                22678         VERROR_INT("xmlSchemaXPathEvaluate",
                22679         "calling xmlStreamPush()");
                22680         return (-1);
                22681     }
                22682     if (res == 0)
                22683         goto next_sto;
                22684     /*
                22685     * Full match.
                22686     */
                22687 #ifdef DEBUG_IDC
                22688     xmlGenericError(xmlGenericErrorContext, "IDC:     "
                22689         "MATCH\n");
                22690 #endif
                22691     /*
                22692     * Register a match in the state object history.
                22693     */
                22694     if (sto->history == NULL) {
                22695         sto->history = (int *) xmlMalloc(5 * sizeof(int));
                22696         if (sto->history == NULL) {
                22697         xmlSchemaVErrMemory(NULL,
                22698             "allocating the state object history", NULL);
                22699         return(-1);
                22700         }
                22701         sto->sizeHistory = 5;
                22702     } else if (sto->sizeHistory <= sto->nbHistory) {
                22703         sto->sizeHistory *= 2;
                22704         sto->history = (int *) xmlRealloc(sto->history,
                22705         sto->sizeHistory * sizeof(int));
                22706         if (sto->history == NULL) {
                22707         xmlSchemaVErrMemory(NULL,
                22708             "re-allocating the state object history", NULL);
                22709         return(-1);
                22710         }
                22711     }
                22712     sto->history[sto->nbHistory++] = depth;
                22713 
                22714 #ifdef DEBUG_IDC
                22715     xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
                22716         vctxt->depth);
                22717 #endif
                22718 
                22719     if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
                22720         xmlSchemaIDCSelectPtr sel;
                22721         /*
                22722         * Activate state objects for the IDC fields of
                22723         * the IDC selector.
                22724         */
                22725 #ifdef DEBUG_IDC
                22726         xmlGenericError(xmlGenericErrorContext, "IDC:     "
                22727         "activating field states\n");
                22728 #endif
                22729         sel = sto->matcher->aidc->def->fields;
                22730         while (sel != NULL) {
                22731         if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
                22732             sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
                22733             return (-1);
                22734         sel = sel->next;
                22735         }
                22736     } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
                22737         /*
                22738         * An IDC key node was found by the IDC field.
                22739         */
                22740 #ifdef DEBUG_IDC
                22741         xmlGenericError(xmlGenericErrorContext,
                22742         "IDC:     key found\n");
                22743 #endif
                22744         /*
                22745         * Notify that the character value of this node is
                22746         * needed.
                22747         */
                22748         if (resolved == 0) {
                22749         if ((vctxt->inode->flags &
                22750             XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
                22751         vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
                22752         }
                22753         resolved++;
                22754     }
                22755 next_sto:
                22756     if (sto->next == NULL) {
                22757         /*
                22758         * Evaluate field state objects created on this node as well.
                22759         */
                22760         head = first;
                22761         sto = vctxt->xpathStates;
                22762     } else
                22763         sto = sto->next;
                22764     }
                22765     return (resolved);
                22766 }
                22767 
                22768 static const xmlChar *
                22769 xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
                22770                 xmlChar **buf,
                22771                 xmlSchemaPSVIIDCKeyPtr *seq,
                22772                 int count, int for_hash)
                22773 {
                22774     int i, res;
                22775     xmlChar *value = NULL;
                22776 
                22777     *buf = xmlStrdup(BAD_CAST "[");
                22778     for (i = 0; i < count; i++) {
                22779     *buf = xmlStrcat(*buf, BAD_CAST "'");
                22780     if (!for_hash)
                22781         res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
                22782             xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
                22783             &value);
                22784     else {
                22785         res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
                22786     }
                22787     if (res == 0)
                22788         *buf = xmlStrcat(*buf, BAD_CAST value);
                22789     else {
                22790         VERROR_INT("xmlSchemaFormatIDCKeySequence",
                22791         "failed to compute a canonical value");
                22792         *buf = xmlStrcat(*buf, BAD_CAST "???");
                22793     }
                22794     if (i < count -1)
                22795         *buf = xmlStrcat(*buf, BAD_CAST "', ");
                22796     else
                22797         *buf = xmlStrcat(*buf, BAD_CAST "'");
                22798     if (value != NULL) {
                22799         xmlFree(value);
                22800         value = NULL;
                22801     }
                22802     }
                22803     *buf = xmlStrcat(*buf, BAD_CAST "]");
                22804 
                22805     return (BAD_CAST *buf);
                22806 }
                22807 
                22808 static const xmlChar *
                22809 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
                22810                   xmlChar **buf,
                22811                   xmlSchemaPSVIIDCKeyPtr *seq,
                22812                   int count)
                22813 {
                22814     return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
                22815 }
                22816 
                22817 static const xmlChar *
                22818 xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
                22819              xmlChar **buf,
                22820              xmlSchemaPSVIIDCKeyPtr *seq,
                22821              int count)
                22822 {
                22823     return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
                22824 }
                22825 
                22826 /**
                22827  * xmlSchemaXPathPop:
                22828  * @vctxt: the WXS validation context
                22829  *
                22830  * Pops all XPath states.
                22831  *
                22832  * Returns 0 on success and -1 on internal errors.
                22833  */
                22834 static int
                22835 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
                22836 {
                22837     xmlSchemaIDCStateObjPtr sto;
                22838     int res;
                22839 
                22840     if (vctxt->xpathStates == NULL)
                22841     return(0);
                22842     sto = vctxt->xpathStates;
                22843     do {
                22844     res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
                22845     if (res == -1)
                22846         return (-1);
                22847     sto = sto->next;
                22848     } while (sto != NULL);
                22849     return(0);
                22850 }
                22851 
                22852 /**
                22853  * xmlSchemaXPathProcessHistory:
                22854  * @vctxt: the WXS validation context
                22855  * @type: the simple/complex type of the current node if any at all
                22856  * @val: the precompiled value
                22857  *
                22858  * Processes and pops the history items of the IDC state objects.
                22859  * IDC key-sequences are validated/created on IDC bindings.
                22860  *
                22861  * Returns 0 on success and -1 on internal errors.
                22862  */
                22863 static int
                22864 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
                22865                  int depth)
                22866 {
                22867     xmlSchemaIDCStateObjPtr sto, nextsto;
                22868     int res, matchDepth;
                22869     xmlSchemaPSVIIDCKeyPtr key = NULL;
                22870     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
                22871 
                22872     if (vctxt->xpathStates == NULL)
                22873     return (0);
                22874     sto = vctxt->xpathStates;
                22875 
                22876 #ifdef DEBUG_IDC
                22877     {
                22878     xmlChar *str = NULL;
                22879     xmlGenericError(xmlGenericErrorContext,
                22880         "IDC: BACK on %s, depth %d\n",
                22881         xmlSchemaFormatQName(&str, vctxt->inode->nsName,
                22882         vctxt->inode->localName), vctxt->depth);
                22883     FREE_AND_NULL(str)
                22884     }
                22885 #endif
                22886     /*
                22887     * Evaluate the state objects.
                22888     */
                22889     while (sto != NULL) {
                22890     res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
                22891     if (res == -1) {
                22892         VERROR_INT("xmlSchemaXPathProcessHistory",
                22893         "calling xmlStreamPop()");
                22894         return (-1);
                22895     }
                22896 #ifdef DEBUG_IDC
                22897     xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
                22898         sto->sel->xpath);
                22899 #endif
                22900     if (sto->nbHistory == 0)
                22901         goto deregister_check;
                22902 
                22903     matchDepth = sto->history[sto->nbHistory -1];
                22904 
                22905     /*
                22906     * Only matches at the current depth are of interest.
                22907     */
                22908     if (matchDepth != depth) {
                22909         sto = sto->next;
                22910         continue;
                22911     }
                22912     if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
                22913         /*
                22914         * NOTE: According to
                22915         *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
                22916         *   ... the simple-content of complex types is also allowed.
                22917         */
                22918 
                22919         if (WXS_IS_COMPLEX(type)) {
                22920         if (WXS_HAS_SIMPLE_CONTENT(type)) {
                22921             /*
                22922             * Sanity check for complex types with simple content.
                22923             */
                22924             simpleType = type->contentTypeDef;
                22925             if (simpleType == NULL) {
                22926             VERROR_INT("xmlSchemaXPathProcessHistory",
                22927                 "field resolves to a CT with simple content "
                22928                 "but the CT is missing the ST definition");
                22929             return (-1);
                22930             }
                22931         } else
                22932             simpleType = NULL;
                22933         } else
                22934         simpleType = type;
                22935         if (simpleType == NULL) {
                22936         xmlChar *str = NULL;
                22937 
                22938         /*
                22939         * Not qualified if the field resolves to a node of non
                22940         * simple type.
                22941         */
                22942         xmlSchemaCustomErr(ACTXT_CAST vctxt,
                22943             XML_SCHEMAV_CVC_IDC, NULL,
                22944             WXS_BASIC_CAST sto->matcher->aidc->def,
                22945             "The XPath '%s' of a field of %s does evaluate to a node of "
                22946             "non-simple type",
                22947             sto->sel->xpath,
                22948             xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
                22949         FREE_AND_NULL(str);
                22950         sto->nbHistory--;
                22951         goto deregister_check;
                22952         }
                22953 
                22954         if ((key == NULL) && (vctxt->inode->val == NULL)) {
                22955         /*
                22956         * Failed to provide the normalized value; maybe
                22957         * the value was invalid.
                22958         */
                22959         VERROR(XML_SCHEMAV_CVC_IDC,
                22960             WXS_BASIC_CAST sto->matcher->aidc->def,
                22961             "Warning: No precomputed value available, the value "
                22962             "was either invalid or something strange happened");
                22963         sto->nbHistory--;
                22964         goto deregister_check;
                22965         } else {
                22966         xmlSchemaIDCMatcherPtr matcher = sto->matcher;
                22967         xmlSchemaPSVIIDCKeyPtr *keySeq;
                22968         int pos, idx;
                22969 
                22970         /*
                22971         * The key will be anchored on the matcher's list of
                22972         * key-sequences. The position in this list is determined
                22973         * by the target node's depth relative to the matcher's
                22974         * depth of creation (i.e. the depth of the scope element).
                22975         *
                22976         * Element        Depth    Pos   List-entries
                22977         * <scope>          0              NULL
                22978         *   <bar>          1              NULL
                22979         *     <target/>    2       2      target
                22980         *   <bar>
                22981                 * </scope>
                22982         *
                22983         * The size of the list is only dependent on the depth of
                22984         * the tree.
                22985         * An entry will be NULLed in selector_leave, i.e. when
                22986         * we hit the target's
                22987         */
                22988         pos = sto->depth - matcher->depth;
                22989         idx = sto->sel->index;
                22990 
                22991         /*
                22992         * Create/grow the array of key-sequences.
                22993         */
                22994         if (matcher->keySeqs == NULL) {
                22995             if (pos > 9)
                22996             matcher->sizeKeySeqs = pos * 2;
                22997             else
                22998             matcher->sizeKeySeqs = 10;
                22999             matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
                23000             xmlMalloc(matcher->sizeKeySeqs *
                23001             sizeof(xmlSchemaPSVIIDCKeyPtr *));
                23002             if (matcher->keySeqs == NULL) {
                23003             xmlSchemaVErrMemory(NULL,
                23004                 "allocating an array of key-sequences",
                23005                 NULL);
                23006             return(-1);
                23007             }
                23008             memset(matcher->keySeqs, 0,
                23009             matcher->sizeKeySeqs *
                23010             sizeof(xmlSchemaPSVIIDCKeyPtr *));
                23011         } else if (pos >= matcher->sizeKeySeqs) {
                23012             int i = matcher->sizeKeySeqs;
                23013 
da6279058 Alex*23014             matcher->sizeKeySeqs = pos * 2;
9d9d4fcc3 Alex*23015             matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
                23016             xmlRealloc(matcher->keySeqs,
                23017             matcher->sizeKeySeqs *
                23018             sizeof(xmlSchemaPSVIIDCKeyPtr *));
                23019             if (matcher->keySeqs == NULL) {
                23020             xmlSchemaVErrMemory(NULL,
                23021                 "reallocating an array of key-sequences",
                23022                 NULL);
                23023             return (-1);
                23024             }
                23025             /*
                23026             * The array needs to be NULLed.
                23027             * TODO: Use memset?
                23028             */
                23029             for (; i < matcher->sizeKeySeqs; i++)
                23030             matcher->keySeqs[i] = NULL;
                23031         }
                23032 
                23033         /*
                23034         * Get/create the key-sequence.
                23035         */
                23036         keySeq = matcher->keySeqs[pos];
                23037         if (keySeq == NULL) {
                23038             goto create_sequence;
                23039         } else if (keySeq[idx] != NULL) {
                23040             xmlChar *str = NULL;
                23041             /*
                23042             * cvc-identity-constraint:
                23043             * 3 For each node in the `target node set` all
                23044             * of the {fields}, with that node as the context
                23045             * node, evaluate to either an empty node-set or
                23046             * a node-set with exactly one member, which must
                23047             * have a simple type.
                23048             *
                23049             * The key was already set; report an error.
                23050             */
                23051             xmlSchemaCustomErr(ACTXT_CAST vctxt,
                23052             XML_SCHEMAV_CVC_IDC, NULL,
                23053             WXS_BASIC_CAST matcher->aidc->def,
                23054             "The XPath '%s' of a field of %s evaluates to a "
                23055             "node-set with more than one member",
                23056             sto->sel->xpath,
                23057             xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
                23058             FREE_AND_NULL(str);
                23059             sto->nbHistory--;
                23060             goto deregister_check;
                23061         } else
                23062             goto create_key;
                23063 
                23064 create_sequence:
                23065         /*
                23066         * Create a key-sequence.
                23067         */
                23068         keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
                23069             matcher->aidc->def->nbFields *
                23070             sizeof(xmlSchemaPSVIIDCKeyPtr));
                23071         if (keySeq == NULL) {
                23072             xmlSchemaVErrMemory(NULL,
                23073             "allocating an IDC key-sequence", NULL);
                23074             return(-1);
                23075         }
                23076         memset(keySeq, 0, matcher->aidc->def->nbFields *
                23077             sizeof(xmlSchemaPSVIIDCKeyPtr));
                23078         matcher->keySeqs[pos] = keySeq;
                23079 create_key:
                23080         /*
                23081         * Create a key once per node only.
                23082         */
                23083         if (key == NULL) {
                23084             key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
                23085             sizeof(xmlSchemaPSVIIDCKey));
                23086             if (key == NULL) {
                23087             xmlSchemaVErrMemory(NULL,
                23088                 "allocating a IDC key", NULL);
                23089             xmlFree(keySeq);
                23090             matcher->keySeqs[pos] = NULL;
                23091             return(-1);
                23092             }
                23093             /*
                23094             * Consume the compiled value.
                23095             */
                23096             key->type = simpleType;
                23097             key->val = vctxt->inode->val;
                23098             vctxt->inode->val = NULL;
                23099             /*
                23100             * Store the key in a global list.
                23101             */
                23102             if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
                23103             xmlSchemaIDCFreeKey(key);
                23104             return (-1);
                23105             }
                23106         }
                23107         keySeq[idx] = key;
                23108         }
                23109     } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
                23110 
                23111         xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
                23112         /* xmlSchemaPSVIIDCBindingPtr bind; */
                23113         xmlSchemaPSVIIDCNodePtr ntItem;
                23114         xmlSchemaIDCMatcherPtr matcher;
                23115         xmlSchemaIDCPtr idc;
                23116         xmlSchemaItemListPtr targets;
                23117         int pos, i, j, nbKeys;
                23118         /*
                23119         * Here we have the following scenario:
                23120         * An IDC 'selector' state object resolved to a target node,
                23121         * during the time this target node was in the
                23122         * ancestor-or-self axis, the 'field' state object(s) looked
                23123         * out for matching nodes to create a key-sequence for this
                23124         * target node. Now we are back to this target node and need
                23125         * to put the key-sequence, together with the target node
                23126         * itself, into the node-table of the corresponding IDC
                23127         * binding.
                23128         */
                23129         matcher = sto->matcher;
                23130         idc = matcher->aidc->def;
                23131         nbKeys = idc->nbFields;
                23132         pos = depth - matcher->depth;
                23133         /*
                23134         * Check if the matcher has any key-sequences at all, plus
                23135         * if it has a key-sequence for the current target node.
                23136         */
                23137         if ((matcher->keySeqs == NULL) ||
                23138         (matcher->sizeKeySeqs <= pos)) {
                23139         if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
                23140             goto selector_key_error;
                23141         else
                23142             goto selector_leave;
                23143         }
                23144 
                23145         keySeq = &(matcher->keySeqs[pos]);
                23146         if (*keySeq == NULL) {
                23147         if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
                23148             goto selector_key_error;
                23149         else
                23150             goto selector_leave;
                23151         }
                23152 
                23153         for (i = 0; i < nbKeys; i++) {
                23154         if ((*keySeq)[i] == NULL) {
                23155             /*
                23156             * Not qualified, if not all fields did resolve.
                23157             */
                23158             if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
                23159             /*
                23160             * All fields of a "key" IDC must resolve.
                23161             */
                23162             goto selector_key_error;
                23163             }
                23164             goto selector_leave;
                23165         }
                23166         }
                23167         /*
                23168         * All fields did resolve.
                23169         */
                23170 
                23171         /*
                23172         * 4.1 If the {identity-constraint category} is unique(/key),
                23173         * then no two members of the `qualified node set` have
                23174         * `key-sequences` whose members are pairwise equal, as
                23175         * defined by Equal in [XML Schemas: Datatypes].
                23176         *
                23177         * Get the IDC binding from the matcher and check for
                23178         * duplicate key-sequences.
                23179         */
                23180 #if 0
                23181         bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
                23182 #endif
                23183         targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
                23184         if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
                23185         (targets->nbItems != 0)) {
                23186         xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
                23187         xmlIDCHashEntryPtr e;
                23188 
                23189         res = 0;
                23190 
                23191         if (!matcher->htab)
                23192             e = NULL;
                23193         else {
                23194             xmlChar *value = NULL;
                23195             xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
                23196             e = xmlHashLookup(matcher->htab, value);
                23197             FREE_AND_NULL(value);
                23198         }
                23199 
                23200         /*
                23201         * Compare the key-sequences, key by key.
                23202         */
                23203         for (;e; e = e->next) {
                23204             bkeySeq =
                23205             ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
                23206             for (j = 0; j < nbKeys; j++) {
                23207             ckey = (*keySeq)[j];
                23208             bkey = bkeySeq[j];
                23209             res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
                23210             if (res == -1) {
                23211                 return (-1);
                23212             } else if (res == 0) {
                23213                 /*
                23214                 * One of the keys differs, so the key-sequence
                23215                 * won't be equal; get out.
                23216                 */
                23217                 break;
                23218             }
                23219             }
                23220             if (res == 1) {
                23221             /*
                23222             * Duplicate key-sequence found.
                23223             */
                23224             break;
                23225             }
                23226         }
                23227         if (e) {
                23228             xmlChar *str = NULL, *strB = NULL;
                23229             /*
                23230             * TODO: Try to report the key-sequence.
                23231             */
                23232             xmlSchemaCustomErr(ACTXT_CAST vctxt,
                23233             XML_SCHEMAV_CVC_IDC, NULL,
                23234             WXS_BASIC_CAST idc,
                23235             "Duplicate key-sequence %s in %s",
                23236             xmlSchemaFormatIDCKeySequence(vctxt, &str,
                23237                 (*keySeq), nbKeys),
                23238             xmlSchemaGetIDCDesignation(&strB, idc));
                23239             FREE_AND_NULL(str);
                23240             FREE_AND_NULL(strB);
                23241             goto selector_leave;
                23242         }
                23243         }
                23244         /*
                23245         * Add a node-table item to the IDC binding.
                23246         */
                23247         ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
                23248         sizeof(xmlSchemaPSVIIDCNode));
                23249         if (ntItem == NULL) {
                23250         xmlSchemaVErrMemory(NULL,
                23251             "allocating an IDC node-table item", NULL);
                23252         xmlFree(*keySeq);
                23253         *keySeq = NULL;
                23254         return(-1);
                23255         }
                23256         memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
                23257 
                23258         /*
                23259         * Store the node-table item in a global list.
                23260         */
                23261         if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
                23262         if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
                23263             xmlFree(ntItem);
                23264             xmlFree(*keySeq);
                23265             *keySeq = NULL;
                23266             return (-1);
                23267         }
                23268         ntItem->nodeQNameID = -1;
                23269         } else {
                23270         /*
                23271         * Save a cached QName for this node on the IDC node, to be
                23272         * able to report it, even if the node is not saved.
                23273         */
                23274         ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
                23275             vctxt->inode->localName, vctxt->inode->nsName);
                23276         if (ntItem->nodeQNameID == -1) {
                23277             xmlFree(ntItem);
                23278             xmlFree(*keySeq);
                23279             *keySeq = NULL;
                23280             return (-1);
                23281         }
                23282         }
                23283         /*
                23284         * Init the node-table item: Save the node, position and
                23285         * consume the key-sequence.
                23286         */
                23287         ntItem->node = vctxt->node;
                23288         ntItem->nodeLine = vctxt->inode->nodeLine;
                23289         ntItem->keys = *keySeq;
                23290         *keySeq = NULL;
                23291 #if 0
                23292         if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
                23293 #endif
                23294         if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
                23295         if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
                23296             /*
                23297             * Free the item, since keyref items won't be
                23298             * put on a global list.
                23299             */
                23300             xmlFree(ntItem->keys);
                23301             xmlFree(ntItem);
                23302         }
                23303         return (-1);
                23304         }
                23305         if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
                23306         xmlChar *value = NULL;
                23307         xmlIDCHashEntryPtr r, e;
                23308         if (!matcher->htab)
                23309           matcher->htab = xmlHashCreate(4);
                23310         xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
                23311         e = xmlMalloc(sizeof *e);
                23312         e->index = targets->nbItems - 1;
                23313         r = xmlHashLookup(matcher->htab, value);
                23314         if (r) {
                23315             e->next = r->next;
                23316             r->next = e;
                23317         } else {
                23318             e->next = NULL;
                23319             xmlHashAddEntry(matcher->htab, value, e);
                23320         }
                23321         FREE_AND_NULL(value);
                23322         }
                23323 
                23324         goto selector_leave;
                23325 selector_key_error:
                23326         {
                23327         xmlChar *str = NULL;
                23328         /*
                23329         * 4.2.1 (KEY) The `target node set` and the
                23330         * `qualified node set` are equal, that is, every
                23331         * member of the `target node set` is also a member
                23332         * of the `qualified node set` and vice versa.
                23333         */
                23334         xmlSchemaCustomErr(ACTXT_CAST vctxt,
                23335             XML_SCHEMAV_CVC_IDC, NULL,
                23336             WXS_BASIC_CAST idc,
                23337             "Not all fields of %s evaluate to a node",
                23338             xmlSchemaGetIDCDesignation(&str, idc), NULL);
                23339         FREE_AND_NULL(str);
                23340         }
                23341 selector_leave:
                23342         /*
                23343         * Free the key-sequence if not added to the IDC table.
                23344         */
                23345         if ((keySeq != NULL) && (*keySeq != NULL)) {
                23346         xmlFree(*keySeq);
                23347         *keySeq = NULL;
                23348         }
                23349     } /* if selector */
                23350 
                23351     sto->nbHistory--;
                23352 
                23353 deregister_check:
                23354     /*
                23355     * Deregister state objects if they reach the depth of creation.
                23356     */
                23357     if ((sto->nbHistory == 0) && (sto->depth == depth)) {
                23358 #ifdef DEBUG_IDC
                23359         xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
                23360         sto->sel->xpath);
                23361 #endif
                23362         if (vctxt->xpathStates != sto) {
                23363         VERROR_INT("xmlSchemaXPathProcessHistory",
                23364             "The state object to be removed is not the first "
                23365             "in the list");
                23366         }
                23367         nextsto = sto->next;
                23368         /*
                23369         * Unlink from the list of active XPath state objects.
                23370         */
                23371         vctxt->xpathStates = sto->next;
                23372         sto->next = vctxt->xpathStatePool;
                23373         /*
                23374         * Link it to the pool of reusable state objects.
                23375         */
                23376         vctxt->xpathStatePool = sto;
                23377         sto = nextsto;
                23378     } else
                23379         sto = sto->next;
                23380     } /* while (sto != NULL) */
                23381     return (0);
                23382 }
                23383 
                23384 /**
                23385  * xmlSchemaIDCRegisterMatchers:
                23386  * @vctxt: the WXS validation context
                23387  * @elemDecl: the element declaration
                23388  *
                23389  * Creates helper objects to evaluate IDC selectors/fields
                23390  * successively.
                23391  *
                23392  * Returns 0 if OK and -1 on internal errors.
                23393  */
                23394 static int
                23395 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
                23396                  xmlSchemaElementPtr elemDecl)
                23397 {
                23398     xmlSchemaIDCMatcherPtr matcher, last = NULL;
                23399     xmlSchemaIDCPtr idc, refIdc;
                23400     xmlSchemaIDCAugPtr aidc;
                23401 
                23402     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
                23403     if (idc == NULL)
                23404     return (0);
                23405 
                23406 #ifdef DEBUG_IDC
                23407     {
                23408     xmlChar *str = NULL;
                23409     xmlGenericError(xmlGenericErrorContext,
                23410         "IDC: REGISTER on %s, depth %d\n",
                23411         (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
                23412         vctxt->inode->localName), vctxt->depth);
                23413     FREE_AND_NULL(str)
                23414     }
                23415 #endif
                23416     if (vctxt->inode->idcMatchers != NULL) {
                23417     VERROR_INT("xmlSchemaIDCRegisterMatchers",
                23418         "The chain of IDC matchers is expected to be empty");
                23419     return (-1);
                23420     }
                23421     do {
                23422     if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
                23423         /*
                23424         * Since IDCs bubbles are expensive we need to know the
                23425         * depth at which the bubbles should stop; this will be
                23426         * the depth of the top-most keyref IDC. If no keyref
                23427         * references a key/unique IDC, the keyrefDepth will
                23428         * be -1, indicating that no bubbles are needed.
                23429         */
                23430         refIdc = (xmlSchemaIDCPtr) idc->ref->item;
                23431         if (refIdc != NULL) {
                23432         /*
                23433         * Remember that we have keyrefs on this node.
                23434         */
                23435         vctxt->inode->hasKeyrefs = 1;
                23436         /*
                23437         * Lookup the referenced augmented IDC info.
                23438         */
                23439         aidc = vctxt->aidcs;
                23440         while (aidc != NULL) {
                23441             if (aidc->def == refIdc)
                23442             break;
                23443             aidc = aidc->next;
                23444         }
                23445         if (aidc == NULL) {
                23446             VERROR_INT("xmlSchemaIDCRegisterMatchers",
                23447             "Could not find an augmented IDC item for an IDC "
                23448             "definition");
                23449             return (-1);
                23450         }
                23451         if ((aidc->keyrefDepth == -1) ||
                23452             (vctxt->depth < aidc->keyrefDepth))
                23453             aidc->keyrefDepth = vctxt->depth;
                23454         }
                23455     }
                23456     /*
                23457     * Lookup the augmented IDC item for the IDC definition.
                23458     */
                23459     aidc = vctxt->aidcs;
                23460     while (aidc != NULL) {
                23461         if (aidc->def == idc)
                23462         break;
                23463         aidc = aidc->next;
                23464     }
                23465     if (aidc == NULL) {
                23466         VERROR_INT("xmlSchemaIDCRegisterMatchers",
                23467         "Could not find an augmented IDC item for an IDC definition");
                23468         return (-1);
                23469     }
                23470     /*
                23471     * Create an IDC matcher for every IDC definition.
                23472     */
                23473     if (vctxt->idcMatcherCache != NULL) {
                23474         /*
                23475         * Reuse a cached matcher.
                23476         */
                23477         matcher = vctxt->idcMatcherCache;
                23478         vctxt->idcMatcherCache = matcher->nextCached;
                23479         matcher->nextCached = NULL;
                23480     } else {
                23481         matcher = (xmlSchemaIDCMatcherPtr)
                23482         xmlMalloc(sizeof(xmlSchemaIDCMatcher));
                23483         if (matcher == NULL) {
                23484         xmlSchemaVErrMemory(vctxt,
                23485             "allocating an IDC matcher", NULL);
                23486         return (-1);
                23487         }
                23488         memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
                23489     }
                23490     if (last == NULL)
                23491         vctxt->inode->idcMatchers = matcher;
                23492     else
                23493         last->next = matcher;
                23494     last = matcher;
                23495 
                23496     matcher->type = IDC_MATCHER;
                23497     matcher->depth = vctxt->depth;
                23498     matcher->aidc = aidc;
                23499     matcher->idcType = aidc->def->type;
                23500 #ifdef DEBUG_IDC
                23501     xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
                23502 #endif
                23503     /*
                23504     * Init the automaton state object.
                23505     */
                23506     if (xmlSchemaIDCAddStateObject(vctxt, matcher,
                23507         idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
                23508         return (-1);
                23509 
                23510     idc = idc->next;
                23511     } while (idc != NULL);
                23512     return (0);
                23513 }
                23514 
                23515 static int
                23516 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
                23517                xmlSchemaNodeInfoPtr ielem)
                23518 {
                23519     xmlSchemaPSVIIDCBindingPtr bind;
                23520     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
                23521     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
                23522     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
                23523 
                23524     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
                23525     /* vctxt->createIDCNodeTables */
                23526     while (matcher != NULL) {
                23527     /*
                23528     * Skip keyref IDCs and empty IDC target-lists.
                23529     */
                23530     if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
                23531         WXS_ILIST_IS_EMPTY(matcher->targets))
                23532     {
                23533         matcher = matcher->next;
                23534         continue;
                23535     }
                23536     /*
                23537     * If we _want_ the IDC node-table to be created in any case
                23538     * then do so. Otherwise create them only if keyrefs need them.
                23539     */
                23540     if ((! vctxt->createIDCNodeTables) &&
                23541         ((matcher->aidc->keyrefDepth == -1) ||
                23542          (matcher->aidc->keyrefDepth > vctxt->depth)))
                23543     {
                23544         matcher = matcher->next;
                23545         continue;
                23546     }
                23547     /*
                23548     * Get/create the IDC binding on this element for the IDC definition.
                23549     */
                23550     bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
                23551     if (bind == NULL)
                23552        goto internal_error;
                23553 
                23554     if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
                23555         dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
                23556         nbDupls = bind->dupls->nbItems;
                23557     } else {
                23558         dupls = NULL;
                23559         nbDupls = 0;
                23560     }
                23561     if (bind->nodeTable != NULL) {
                23562         nbNodeTable = bind->nbNodes;
                23563     } else {
                23564         nbNodeTable = 0;
                23565     }
                23566 
                23567     if ((nbNodeTable == 0) && (nbDupls == 0)) {
                23568         /*
                23569         * Transfer all IDC target-nodes to the IDC node-table.
                23570         */
                23571         bind->nodeTable =
                23572         (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
                23573         bind->sizeNodes = matcher->targets->sizeItems;
                23574         bind->nbNodes = matcher->targets->nbItems;
                23575 
                23576         matcher->targets->items = NULL;
                23577         matcher->targets->sizeItems = 0;
                23578         matcher->targets->nbItems = 0;
                23579         if (matcher->htab) {
                23580         xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
                23581         matcher->htab = NULL;
                23582         }
                23583     } else {
                23584         /*
                23585         * Compare the key-sequences and add to the IDC node-table.
                23586         */
                23587         nbTargets = matcher->targets->nbItems;
                23588         targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
                23589         nbFields = matcher->aidc->def->nbFields;
                23590         i = 0;
                23591         do {
                23592         keys = targets[i]->keys;
                23593         if (nbDupls) {
                23594             /*
                23595             * Search in already found duplicates first.
                23596             */
                23597             j = 0;
                23598             do {
                23599             if (nbFields == 1) {
                23600                 res = xmlSchemaAreValuesEqual(keys[0]->val,
                23601                 dupls[j]->keys[0]->val);
                23602                 if (res == -1)
                23603                 goto internal_error;
                23604                 if (res == 1) {
                23605                 /*
                23606                 * Equal key-sequence.
                23607                 */
                23608                 goto next_target;
                23609                 }
                23610             } else {
                23611                 res = 0;
                23612                 ntkeys = dupls[j]->keys;
                23613                 for (k = 0; k < nbFields; k++) {
                23614                 res = xmlSchemaAreValuesEqual(keys[k]->val,
                23615                     ntkeys[k]->val);
                23616                 if (res == -1)
                23617                     goto internal_error;
                23618                 if (res == 0) {
                23619                     /*
                23620                     * One of the keys differs.
                23621                     */
                23622                     break;
                23623                 }
                23624                 }
                23625                 if (res == 1) {
                23626                 /*
                23627                 * Equal key-sequence found.
                23628                 */
                23629                 goto next_target;
                23630                 }
                23631             }
                23632             j++;
                23633             } while (j < nbDupls);
                23634         }
                23635         if (nbNodeTable) {
                23636             j = 0;
                23637             do {
                23638             if (nbFields == 1) {
                23639                 res = xmlSchemaAreValuesEqual(keys[0]->val,
                23640                 bind->nodeTable[j]->keys[0]->val);
                23641                 if (res == -1)
                23642                 goto internal_error;
                23643                 if (res == 0) {
                23644                 /*
                23645                 * The key-sequence differs.
                23646                 */
                23647                 goto next_node_table_entry;
                23648                 }
                23649             } else {
                23650                 res = 0;
                23651                 ntkeys = bind->nodeTable[j]->keys;
                23652                 for (k = 0; k < nbFields; k++) {
                23653                 res = xmlSchemaAreValuesEqual(keys[k]->val,
                23654                     ntkeys[k]->val);
                23655                 if (res == -1)
                23656                     goto internal_error;
                23657                 if (res == 0) {
                23658                     /*
                23659                     * One of the keys differs.
                23660                     */
                23661                     goto next_node_table_entry;
                23662                 }
                23663                 }
                23664             }
                23665             /*
                23666             * Add the duplicate to the list of duplicates.
                23667             */
                23668             if (bind->dupls == NULL) {
                23669                 bind->dupls = xmlSchemaItemListCreate();
                23670                 if (bind->dupls == NULL)
                23671                 goto internal_error;
                23672             }
                23673             if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
                23674                 goto internal_error;
                23675             /*
                23676             * Remove the duplicate entry from the IDC node-table.
                23677             */
                23678             bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
                23679             bind->nbNodes--;
                23680 
                23681             goto next_target;
                23682 
                23683 next_node_table_entry:
                23684             j++;
                23685             } while (j < nbNodeTable);
                23686         }
                23687         /*
                23688         * If everything is fine, then add the IDC target-node to
                23689         * the IDC node-table.
                23690         */
                23691         if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
                23692             goto internal_error;
                23693 
                23694 next_target:
                23695         i++;
                23696         } while (i < nbTargets);
                23697     }
                23698     matcher = matcher->next;
                23699     }
                23700     return(0);
                23701 
                23702 internal_error:
                23703     return(-1);
                23704 }
                23705 
                23706 /**
                23707  * xmlSchemaBubbleIDCNodeTables:
                23708  * @depth: the current tree depth
                23709  *
                23710  * Merges IDC bindings of an element at @depth into the corresponding IDC
                23711  * bindings of its parent element. If a duplicate note-table entry is found,
                23712  * both, the parent node-table entry and child entry are discarded from the
                23713  * node-table of the parent.
                23714  *
                23715  * Returns 0 if OK and -1 on internal errors.
                23716  */
                23717 static int
                23718 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
                23719 {
                23720     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
                23721     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
                23722     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
                23723     xmlSchemaIDCAugPtr aidc;
                23724     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
                23725 
                23726     bind = vctxt->inode->idcTable;
                23727     if (bind == NULL) {
                23728     /* Fine, no table, no bubbles. */
                23729     return (0);
                23730     }
                23731 
                23732     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
                23733     /*
                23734     * Walk all bindings; create new or add to existing bindings.
                23735     * Remove duplicate key-sequences.
                23736     */
                23737     while (bind != NULL) {
                23738 
                23739     if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
                23740         goto next_binding;
                23741     /*
                23742     * Check if the key/unique IDC table needs to be bubbled.
                23743     */
                23744     if (! vctxt->createIDCNodeTables) {
                23745         aidc = vctxt->aidcs;
                23746         do {
                23747         if (aidc->def == bind->definition) {
                23748             if ((aidc->keyrefDepth == -1) ||
                23749             (aidc->keyrefDepth >= vctxt->depth)) {
                23750             goto next_binding;
                23751             }
                23752             break;
                23753         }
                23754         aidc = aidc->next;
                23755         } while (aidc != NULL);
                23756     }
                23757 
                23758     if (parTable != NULL)
                23759         parBind = *parTable;
                23760     /*
                23761     * Search a matching parent binding for the
                23762     * IDC definition.
                23763     */
                23764     while (parBind != NULL) {
                23765         if (parBind->definition == bind->definition)
                23766         break;
                23767         parBind = parBind->next;
                23768     }
                23769 
                23770     if (parBind != NULL) {
                23771         /*
                23772         * Compare every node-table entry of the child node,
                23773         * i.e. the key-sequence within, ...
                23774         */
                23775         oldNum = parBind->nbNodes; /* Skip newly added items. */
                23776 
                23777         if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
                23778         oldDupls = parBind->dupls->nbItems;
                23779         dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
                23780         } else {
                23781         dupls = NULL;
                23782         oldDupls = 0;
                23783         }
                23784 
                23785         parNodes = parBind->nodeTable;
                23786         nbFields = bind->definition->nbFields;
                23787 
                23788         for (i = 0; i < bind->nbNodes; i++) {
                23789         node = bind->nodeTable[i];
                23790         if (node == NULL)
                23791             continue;
                23792         /*
                23793         * ...with every key-sequence of the parent node, already
                23794         * evaluated to be a duplicate key-sequence.
                23795         */
                23796         if (oldDupls) {
                23797             j = 0;
                23798             while (j < oldDupls) {
                23799             if (nbFields == 1) {
                23800                 ret = xmlSchemaAreValuesEqual(
                23801                 node->keys[0]->val,
                23802                 dupls[j]->keys[0]->val);
                23803                 if (ret == -1)
                23804                 goto internal_error;
                23805                 if (ret == 0) {
                23806                 j++;
                23807                 continue;
                23808                 }
                23809             } else {
                23810                 parNode = dupls[j];
                23811                 for (k = 0; k < nbFields; k++) {
                23812                 ret = xmlSchemaAreValuesEqual(
                23813                     node->keys[k]->val,
                23814                     parNode->keys[k]->val);
                23815                 if (ret == -1)
                23816                     goto internal_error;
                23817                 if (ret == 0)
                23818                     break;
                23819                 }
                23820             }
                23821             if (ret == 1)
                23822                 /* Duplicate found. */
                23823                 break;
                23824             j++;
                23825             }
                23826             if (j != oldDupls) {
                23827             /* Duplicate found. Skip this entry. */
                23828             continue;
                23829             }
                23830         }
                23831         /*
                23832         * ... and with every key-sequence of the parent node.
                23833         */
                23834         if (oldNum) {
                23835             j = 0;
                23836             while (j < oldNum) {
                23837             parNode = parNodes[j];
                23838             if (nbFields == 1) {
                23839                 ret = xmlSchemaAreValuesEqual(
                23840                 node->keys[0]->val,
                23841                 parNode->keys[0]->val);
                23842                 if (ret == -1)
                23843                 goto internal_error;
                23844                 if (ret == 0) {
                23845                 j++;
                23846                 continue;
                23847                 }
                23848             } else {
                23849                 for (k = 0; k < nbFields; k++) {
                23850                 ret = xmlSchemaAreValuesEqual(
                23851                     node->keys[k]->val,
                23852                     parNode->keys[k]->val);
                23853                 if (ret == -1)
                23854                     goto internal_error;
                23855                 if (ret == 0)
                23856                     break;
                23857                 }
                23858             }
                23859             if (ret == 1)
                23860                 /* Duplicate found. */
                23861                 break;
                23862             j++;
                23863             }
                23864             if (j != oldNum) {
                23865             /*
                23866             * Handle duplicates. Move the duplicate in
                23867             * the parent's node-table to the list of
                23868             * duplicates.
                23869             */
                23870             oldNum--;
                23871             parBind->nbNodes--;
                23872             /*
                23873             * Move last old item to pos of duplicate.
                23874             */
                23875             parNodes[j] = parNodes[oldNum];
                23876 
                23877             if (parBind->nbNodes != oldNum) {
                23878                 /*
                23879                 * If new items exist, move last new item to
                23880                 * last of old items.
                23881                 */
                23882                 parNodes[oldNum] =
                23883                 parNodes[parBind->nbNodes];
                23884             }
                23885             if (parBind->dupls == NULL) {
                23886                 parBind->dupls = xmlSchemaItemListCreate();
                23887                 if (parBind->dupls == NULL)
                23888                 goto internal_error;
                23889             }
                23890             xmlSchemaItemListAdd(parBind->dupls, parNode);
                23891             } else {
                23892             /*
                23893             * Add the node-table entry (node and key-sequence) of
                23894             * the child node to the node table of the parent node.
                23895             */
                23896             if (parBind->nodeTable == NULL) {
                23897                 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
                23898                 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
                23899                 if (parBind->nodeTable == NULL) {
                23900                 xmlSchemaVErrMemory(NULL,
                23901                     "allocating IDC list of node-table items", NULL);
                23902                 goto internal_error;
                23903                 }
                23904                 parBind->sizeNodes = 1;
                23905             } else if (parBind->nbNodes >= parBind->sizeNodes) {
                23906                 parBind->sizeNodes *= 2;
                23907                 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
                23908                 xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
                23909                 sizeof(xmlSchemaPSVIIDCNodePtr));
                23910                 if (parBind->nodeTable == NULL) {
                23911                 xmlSchemaVErrMemory(NULL,
                23912                     "re-allocating IDC list of node-table items", NULL);
                23913                 goto internal_error;
                23914                 }
                23915             }
                23916             parNodes = parBind->nodeTable;
                23917             /*
                23918             * Append the new node-table entry to the 'new node-table
                23919             * entries' section.
                23920             */
                23921             parNodes[parBind->nbNodes++] = node;
                23922             }
                23923 
                23924         }
                23925 
                23926         }
                23927     } else {
                23928         /*
                23929         * No binding for the IDC was found: create a new one and
                23930         * copy all node-tables.
                23931         */
                23932         parBind = xmlSchemaIDCNewBinding(bind->definition);
                23933         if (parBind == NULL)
                23934         goto internal_error;
                23935 
                23936         /*
                23937         * TODO: Hmm, how to optimize the initial number of
                23938         * allocated entries?
                23939         */
                23940         if (bind->nbNodes != 0) {
                23941         /*
                23942         * Add all IDC node-table entries.
                23943         */
                23944         if (! vctxt->psviExposeIDCNodeTables) {
                23945             /*
                23946             * Just move the entries.
                23947             * NOTE: this is quite save here, since
                23948             * all the keyref lookups have already been
                23949             * performed.
                23950             */
                23951             parBind->nodeTable = bind->nodeTable;
                23952             bind->nodeTable = NULL;
                23953             parBind->sizeNodes = bind->sizeNodes;
                23954             bind->sizeNodes = 0;
                23955             parBind->nbNodes = bind->nbNodes;
                23956             bind->nbNodes = 0;
                23957         } else {
                23958             /*
                23959             * Copy the entries.
                23960             */
                23961             parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
                23962             xmlMalloc(bind->nbNodes *
                23963             sizeof(xmlSchemaPSVIIDCNodePtr));
                23964             if (parBind->nodeTable == NULL) {
                23965             xmlSchemaVErrMemory(NULL,
                23966                 "allocating an array of IDC node-table "
                23967                 "items", NULL);
                23968             xmlSchemaIDCFreeBinding(parBind);
                23969             goto internal_error;
                23970             }
                23971             parBind->sizeNodes = bind->nbNodes;
                23972             parBind->nbNodes = bind->nbNodes;
                23973             memcpy(parBind->nodeTable, bind->nodeTable,
                23974             bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
                23975         }
                23976         }
                23977         if (bind->dupls) {
                23978         /*
                23979         * Move the duplicates.
                23980         */
                23981         if (parBind->dupls != NULL)
                23982             xmlSchemaItemListFree(parBind->dupls);
                23983         parBind->dupls = bind->dupls;
                23984         bind->dupls = NULL;
                23985         }
                23986             if (parTable != NULL) {
                23987                 if (*parTable == NULL)
                23988                     *parTable = parBind;
                23989                 else {
                23990                     parBind->next = *parTable;
                23991                     *parTable = parBind;
                23992                 }
                23993             }
                23994     }
                23995 
                23996 next_binding:
                23997     bind = bind->next;
                23998     }
                23999     return (0);
                24000 
                24001 internal_error:
                24002     return(-1);
                24003 }
                24004 
                24005 /**
                24006  * xmlSchemaCheckCVCIDCKeyRef:
                24007  * @vctxt: the WXS validation context
                24008  * @elemDecl: the element declaration
                24009  *
                24010  * Check the cvc-idc-keyref constraints.
                24011  */
                24012 static int
                24013 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
                24014 {
                24015     xmlSchemaIDCMatcherPtr matcher;
                24016     xmlSchemaPSVIIDCBindingPtr bind;
                24017 
                24018     matcher = vctxt->inode->idcMatchers;
                24019     /*
                24020     * Find a keyref.
                24021     */
                24022     while (matcher != NULL) {
                24023     if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
                24024         matcher->targets &&
                24025         matcher->targets->nbItems)
                24026     {
                24027         int i, j, k, res, nbFields, hasDupls;
                24028         xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
                24029         xmlSchemaPSVIIDCNodePtr refNode = NULL;
                24030         xmlHashTablePtr table = NULL;
                24031 
                24032         nbFields = matcher->aidc->def->nbFields;
                24033 
                24034         /*
                24035         * Find the IDC node-table for the referenced IDC key/unique.
                24036         */
                24037         bind = vctxt->inode->idcTable;
                24038         while (bind != NULL) {
                24039         if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
                24040             bind->definition)
                24041             break;
                24042         bind = bind->next;
                24043         }
                24044         hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
                24045         /*
                24046         * Search for a matching key-sequences.
                24047         */
                24048         if (bind) {
                24049         table = xmlHashCreate(bind->nbNodes * 2);
                24050         for (j = 0; j < bind->nbNodes; j++) {
                24051             xmlChar *value;
                24052             xmlIDCHashEntryPtr r, e;
                24053             keys = bind->nodeTable[j]->keys;
                24054             xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
                24055             e = xmlMalloc(sizeof *e);
                24056             e->index = j;
                24057             r = xmlHashLookup(table, value);
                24058             if (r) {
                24059             e->next = r->next;
                24060             r->next = e;
                24061             } else {
                24062             e->next = NULL;
                24063             xmlHashAddEntry(table, value, e);
                24064             }
                24065             FREE_AND_NULL(value);
                24066         }
                24067         }
                24068         for (i = 0; i < matcher->targets->nbItems; i++) {
                24069         res = 0;
                24070         refNode = matcher->targets->items[i];
                24071         if (bind != NULL) {
                24072             xmlChar *value;
                24073             xmlIDCHashEntryPtr e;
                24074             refKeys = refNode->keys;
                24075             xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
                24076             e = xmlHashLookup(table, value);
                24077             FREE_AND_NULL(value);
                24078             res = 0;
                24079             for (;e; e = e->next) {
                24080             keys = bind->nodeTable[e->index]->keys;
                24081             for (k = 0; k < nbFields; k++) {
                24082                 res = xmlSchemaAreValuesEqual(keys[k]->val,
                24083                               refKeys[k]->val);
                24084                 if (res == 0)
                24085                     break;
                24086                 else if (res == -1) {
                24087                 return (-1);
                24088                 }
                24089             }
                24090             if (res == 1) {
                24091                 /*
                24092                  * Match found.
                24093                  */
                24094                 break;
                24095             }
                24096             }
                24097             if ((res == 0) && hasDupls) {
                24098             /*
                24099             * Search in duplicates
                24100             */
                24101             for (j = 0; j < bind->dupls->nbItems; j++) {
                24102                 keys = ((xmlSchemaPSVIIDCNodePtr)
                24103                 bind->dupls->items[j])->keys;
                24104                 for (k = 0; k < nbFields; k++) {
                24105                 res = xmlSchemaAreValuesEqual(keys[k]->val,
                24106                     refKeys[k]->val);
                24107                 if (res == 0)
                24108                     break;
                24109                 else if (res == -1) {
                24110                     return (-1);
                24111                 }
                24112                 }
                24113                 if (res == 1) {
                24114                 /*
                24115                 * Match in duplicates found.
                24116                 */
                24117                 xmlChar *str = NULL, *strB = NULL;
                24118                 xmlSchemaKeyrefErr(vctxt,
                24119                     XML_SCHEMAV_CVC_IDC, refNode,
                24120                     (xmlSchemaTypePtr) matcher->aidc->def,
                24121                     "More than one match found for "
                24122                     "key-sequence %s of keyref '%s'",
                24123                     xmlSchemaFormatIDCKeySequence(vctxt, &str,
                24124                     refNode->keys, nbFields),
                24125                     xmlSchemaGetComponentQName(&strB,
                24126                     matcher->aidc->def));
                24127                 FREE_AND_NULL(str);
                24128                 FREE_AND_NULL(strB);
                24129                 break;
                24130                 }
                24131             }
                24132             }
                24133         }
                24134 
                24135         if (res == 0) {
                24136             xmlChar *str = NULL, *strB = NULL;
                24137             xmlSchemaKeyrefErr(vctxt,
                24138             XML_SCHEMAV_CVC_IDC, refNode,
                24139             (xmlSchemaTypePtr) matcher->aidc->def,
                24140             "No match found for key-sequence %s of keyref '%s'",
                24141             xmlSchemaFormatIDCKeySequence(vctxt, &str,
                24142                 refNode->keys, nbFields),
                24143             xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
                24144             FREE_AND_NULL(str);
                24145             FREE_AND_NULL(strB);
                24146         }
                24147         }
                24148         if (table) {
                24149         xmlHashFree(table, xmlFreeIDCHashEntry);
                24150         }
                24151     }
                24152     matcher = matcher->next;
                24153     }
                24154     /* TODO: Return an error if any error encountered. */
                24155     return (0);
                24156 }
                24157 
                24158 /************************************************************************
                24159  *                                  *
                24160  *          XML Reader validation code                      *
                24161  *                                  *
                24162  ************************************************************************/
                24163 
                24164 static xmlSchemaAttrInfoPtr
                24165 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
                24166 {
                24167     xmlSchemaAttrInfoPtr iattr;
                24168     /*
                24169     * Grow/create list of attribute infos.
                24170     */
                24171     if (vctxt->attrInfos == NULL) {
                24172     vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
                24173         xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
                24174     vctxt->sizeAttrInfos = 1;
                24175     if (vctxt->attrInfos == NULL) {
                24176         xmlSchemaVErrMemory(vctxt,
                24177         "allocating attribute info list", NULL);
                24178         return (NULL);
                24179     }
                24180     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
                24181     vctxt->sizeAttrInfos++;
                24182     vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
                24183         xmlRealloc(vctxt->attrInfos,
                24184         vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
                24185     if (vctxt->attrInfos == NULL) {
                24186         xmlSchemaVErrMemory(vctxt,
                24187         "re-allocating attribute info list", NULL);
                24188         return (NULL);
                24189     }
                24190     } else {
                24191     iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
                24192     if (iattr->localName != NULL) {
                24193         VERROR_INT("xmlSchemaGetFreshAttrInfo",
                24194         "attr info not cleared");
                24195         return (NULL);
                24196     }
                24197     iattr->nodeType = XML_ATTRIBUTE_NODE;
                24198     return (iattr);
                24199     }
                24200     /*
                24201     * Create an attribute info.
                24202     */
                24203     iattr = (xmlSchemaAttrInfoPtr)
                24204     xmlMalloc(sizeof(xmlSchemaAttrInfo));
                24205     if (iattr == NULL) {
                24206     xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
                24207     return (NULL);
                24208     }
                24209     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
                24210     iattr->nodeType = XML_ATTRIBUTE_NODE;
                24211     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
                24212 
                24213     return (iattr);
                24214 }
                24215 
                24216 static int
                24217 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
                24218             xmlNodePtr attrNode,
                24219             int nodeLine,
                24220             const xmlChar *localName,
                24221             const xmlChar *nsName,
                24222             int ownedNames,
                24223             xmlChar *value,
                24224             int ownedValue)
                24225 {
                24226     xmlSchemaAttrInfoPtr attr;
                24227 
                24228     attr = xmlSchemaGetFreshAttrInfo(vctxt);
                24229     if (attr == NULL) {
                24230     VERROR_INT("xmlSchemaPushAttribute",
                24231         "calling xmlSchemaGetFreshAttrInfo()");
                24232     return (-1);
                24233     }
                24234     attr->node = attrNode;
                24235     attr->nodeLine = nodeLine;
                24236     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
                24237     attr->localName = localName;
                24238     attr->nsName = nsName;
                24239     if (ownedNames)
                24240     attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
                24241     /*
                24242     * Evaluate if it's an XSI attribute.
                24243     */
                24244     if (nsName != NULL) {
                24245     if (xmlStrEqual(localName, BAD_CAST "nil")) {
                24246         if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
                24247         attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
                24248         }
                24249     } else if (xmlStrEqual(localName, BAD_CAST "type")) {
                24250         if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
                24251         attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
                24252         }
                24253     } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
                24254         if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
                24255         attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
                24256         }
                24257     } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
                24258         if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
                24259         attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
                24260         }
                24261     } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
                24262         attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
                24263     }
                24264     }
                24265     attr->value = value;
                24266     if (ownedValue)
                24267     attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
                24268     if (attr->metaType != 0)
                24269     attr->state = XML_SCHEMAS_ATTR_META;
                24270     return (0);
                24271 }
                24272 
                24273 /**
                24274  * xmlSchemaClearElemInfo:
                24275  * @vctxt: the WXS validation context
                24276  * @ielem: the element information item
                24277  */
                24278 static void
                24279 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
                24280                xmlSchemaNodeInfoPtr ielem)
                24281 {
                24282     ielem->hasKeyrefs = 0;
                24283     ielem->appliedXPath = 0;
                24284     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
                24285     FREE_AND_NULL(ielem->localName);
                24286     FREE_AND_NULL(ielem->nsName);
                24287     } else {
                24288     ielem->localName = NULL;
                24289     ielem->nsName = NULL;
                24290     }
                24291     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
                24292     FREE_AND_NULL(ielem->value);
                24293     } else {
                24294     ielem->value = NULL;
                24295     }
                24296     if (ielem->val != NULL) {
                24297     /*
                24298     * PSVI TODO: Be careful not to free it when the value is
                24299     * exposed via PSVI.
                24300     */
                24301     xmlSchemaFreeValue(ielem->val);
                24302     ielem->val = NULL;
                24303     }
                24304     if (ielem->idcMatchers != NULL) {
                24305     /*
                24306     * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
                24307     *   Does it work?
                24308     */
                24309     xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
                24310 #if 0
                24311     xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
                24312 #endif
                24313     ielem->idcMatchers = NULL;
                24314     }
                24315     if (ielem->idcTable != NULL) {
                24316     /*
                24317     * OPTIMIZE TODO: Use a pool of IDC tables??.
                24318     */
                24319     xmlSchemaIDCFreeIDCTable(ielem->idcTable);
                24320     ielem->idcTable = NULL;
                24321     }
                24322     if (ielem->regexCtxt != NULL) {
                24323     xmlRegFreeExecCtxt(ielem->regexCtxt);
                24324     ielem->regexCtxt = NULL;
                24325     }
                24326     if (ielem->nsBindings != NULL) {
                24327     xmlFree((xmlChar **)ielem->nsBindings);
                24328     ielem->nsBindings = NULL;
                24329     ielem->nbNsBindings = 0;
                24330     ielem->sizeNsBindings = 0;
                24331     }
                24332 }
                24333 
                24334 /**
                24335  * xmlSchemaGetFreshElemInfo:
                24336  * @vctxt: the schema validation context
                24337  *
                24338  * Creates/reuses and initializes the element info item for
                24339  * the current tree depth.
                24340  *
                24341  * Returns the element info item or NULL on API or internal errors.
                24342  */
                24343 static xmlSchemaNodeInfoPtr
                24344 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
                24345 {
                24346     xmlSchemaNodeInfoPtr info = NULL;
                24347 
                24348     if (vctxt->depth > vctxt->sizeElemInfos) {
                24349     VERROR_INT("xmlSchemaGetFreshElemInfo",
                24350         "inconsistent depth encountered");
                24351     return (NULL);
                24352     }
                24353     if (vctxt->elemInfos == NULL) {
                24354     vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
                24355         xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
                24356     if (vctxt->elemInfos == NULL) {
                24357         xmlSchemaVErrMemory(vctxt,
                24358         "allocating the element info array", NULL);
                24359         return (NULL);
                24360     }
                24361     memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
                24362     vctxt->sizeElemInfos = 10;
                24363     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
                24364     int i = vctxt->sizeElemInfos;
                24365 
                24366     vctxt->sizeElemInfos *= 2;
                24367     vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
                24368         xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
                24369         sizeof(xmlSchemaNodeInfoPtr));
                24370     if (vctxt->elemInfos == NULL) {
                24371         xmlSchemaVErrMemory(vctxt,
                24372         "re-allocating the element info array", NULL);
                24373         return (NULL);
                24374     }
                24375     /*
                24376     * We need the new memory to be NULLed.
                24377     * TODO: Use memset instead?
                24378     */
                24379     for (; i < vctxt->sizeElemInfos; i++)
                24380         vctxt->elemInfos[i] = NULL;
                24381     } else
                24382     info = vctxt->elemInfos[vctxt->depth];
                24383 
                24384     if (info == NULL) {
                24385     info = (xmlSchemaNodeInfoPtr)
                24386         xmlMalloc(sizeof(xmlSchemaNodeInfo));
                24387     if (info == NULL) {
                24388         xmlSchemaVErrMemory(vctxt,
                24389         "allocating an element info", NULL);
                24390         return (NULL);
                24391     }
                24392     vctxt->elemInfos[vctxt->depth] = info;
                24393     } else {
                24394     if (info->localName != NULL) {
                24395         VERROR_INT("xmlSchemaGetFreshElemInfo",
                24396         "elem info has not been cleared");
                24397         return (NULL);
                24398     }
                24399     }
                24400     memset(info, 0, sizeof(xmlSchemaNodeInfo));
                24401     info->nodeType = XML_ELEMENT_NODE;
                24402     info->depth = vctxt->depth;
                24403 
                24404     return (info);
                24405 }
                24406 
                24407 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
                24408 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
                24409 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
                24410 
                24411 static int
                24412 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
                24413             xmlNodePtr node,
                24414             xmlSchemaTypePtr type,
                24415             xmlSchemaValType valType,
                24416             const xmlChar * value,
                24417             xmlSchemaValPtr val,
                24418             unsigned long length,
                24419             int fireErrors)
                24420 {
                24421     int ret, error = 0, found;
                24422 
                24423     xmlSchemaTypePtr tmpType;
                24424     xmlSchemaFacetLinkPtr facetLink;
                24425     xmlSchemaFacetPtr facet;
                24426     unsigned long len = 0;
                24427     xmlSchemaWhitespaceValueType ws;
                24428 
                24429     /*
                24430     * In Libxml2, derived built-in types have currently no explicit facets.
                24431     */
                24432     if (type->type == XML_SCHEMA_TYPE_BASIC)
                24433     return (0);
                24434 
                24435     /*
                24436     * NOTE: Do not jump away, if the facetSet of the given type is
                24437     * empty: until now, "pattern" and "enumeration" facets of the
                24438     * *base types* need to be checked as well.
                24439     */
                24440     if (type->facetSet == NULL)
                24441     goto pattern_and_enum;
                24442 
                24443     if (! WXS_IS_ATOMIC(type)) {
                24444     if (WXS_IS_LIST(type))
                24445         goto WXS_IS_LIST;
                24446     else
                24447         goto pattern_and_enum;
                24448     }
                24449 
                24450     /*
                24451     * Whitespace handling is only of importance for string-based
                24452     * types.
                24453     */
                24454     tmpType = xmlSchemaGetPrimitiveType(type);
                24455     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
                24456     WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
                24457     ws = xmlSchemaGetWhiteSpaceFacetValue(type);
                24458     } else
                24459     ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
                24460 
                24461     /*
                24462     * If the value was not computed (for string or
                24463     * anySimpleType based types), then use the provided
                24464     * type.
                24465     */
                24466     if (val != NULL)
                24467     valType = xmlSchemaGetValType(val);
                24468 
                24469     ret = 0;
                24470     for (facetLink = type->facetSet; facetLink != NULL;
                24471     facetLink = facetLink->next) {
                24472     /*
                24473     * Skip the pattern "whiteSpace": it is used to
                24474     * format the character content beforehand.
                24475     */
                24476     switch (facetLink->facet->type) {
                24477         case XML_SCHEMA_FACET_WHITESPACE:
                24478         case XML_SCHEMA_FACET_PATTERN:
                24479         case XML_SCHEMA_FACET_ENUMERATION:
                24480         continue;
                24481         case XML_SCHEMA_FACET_LENGTH:
                24482         case XML_SCHEMA_FACET_MINLENGTH:
                24483         case XML_SCHEMA_FACET_MAXLENGTH:
                24484         ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
                24485             valType, value, val, &len, ws);
                24486         break;
                24487         default:
                24488         ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
                24489             valType, value, val, ws);
                24490         break;
                24491     }
                24492     if (ret < 0) {
                24493         AERROR_INT("xmlSchemaValidateFacets",
                24494         "validating against a atomic type facet");
                24495         return (-1);
                24496     } else if (ret > 0) {
                24497         if (fireErrors)
                24498         xmlSchemaFacetErr(actxt, ret, node,
                24499         value, len, type, facetLink->facet, NULL, NULL, NULL);
                24500         else
                24501         return (ret);
                24502         if (error == 0)
                24503         error = ret;
                24504     }
                24505     ret = 0;
                24506     }
                24507 
                24508 WXS_IS_LIST:
                24509     if (! WXS_IS_LIST(type))
                24510     goto pattern_and_enum;
                24511     /*
                24512     * "length", "minLength" and "maxLength" of list types.
                24513     */
                24514     ret = 0;
                24515     for (facetLink = type->facetSet; facetLink != NULL;
                24516     facetLink = facetLink->next) {
                24517 
                24518     switch (facetLink->facet->type) {
                24519         case XML_SCHEMA_FACET_LENGTH:
                24520         case XML_SCHEMA_FACET_MINLENGTH:
                24521         case XML_SCHEMA_FACET_MAXLENGTH:
                24522         ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
                24523             value, length, NULL);
                24524         break;
                24525         default:
                24526         continue;
                24527     }
                24528     if (ret < 0) {
                24529         AERROR_INT("xmlSchemaValidateFacets",
                24530         "validating against a list type facet");
                24531         return (-1);
                24532     } else if (ret > 0) {
                24533         if (fireErrors)
                24534         xmlSchemaFacetErr(actxt, ret, node,
                24535         value, length, type, facetLink->facet, NULL, NULL, NULL);
                24536         else
                24537         return (ret);
                24538         if (error == 0)
                24539         error = ret;
                24540     }
                24541     ret = 0;
                24542     }
                24543 
                24544 pattern_and_enum:
                24545     found = 0;
                24546     /*
                24547     * Process enumerations. Facet values are in the value space
                24548     * of the defining type's base type. This seems to be a bug in the
                24549     * XML Schema 1.0 spec. Use the whitespace type of the base type.
                24550     * Only the first set of enumerations in the ancestor-or-self axis
                24551     * is used for validation.
                24552     */
                24553     ret = 0;
                24554     tmpType = type;
                24555     do {
                24556         for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
                24557             if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
                24558                 continue;
                24559             found = 1;
                24560             ret = xmlSchemaAreValuesEqual(facet->val, val);
                24561             if (ret == 1)
                24562                 break;
                24563             else if (ret < 0) {
                24564                 AERROR_INT("xmlSchemaValidateFacets",
                24565                     "validating against an enumeration facet");
                24566                 return (-1);
                24567             }
                24568         }
                24569         if (ret != 0)
                24570             break;
                24571         /*
                24572         * Break on the first set of enumerations. Any additional
                24573         *  enumerations which might be existent on the ancestors
                24574         *  of the current type are restricted by this set; thus
                24575         *  *must* *not* be taken into account.
                24576         */
                24577         if (found)
                24578             break;
                24579         tmpType = tmpType->baseType;
                24580     } while ((tmpType != NULL) &&
                24581         (tmpType->type != XML_SCHEMA_TYPE_BASIC));
                24582     if (found && (ret == 0)) {
                24583         ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
                24584         if (fireErrors) {
                24585             xmlSchemaFacetErr(actxt, ret, node,
                24586                 value, 0, type, NULL, NULL, NULL, NULL);
                24587         } else
                24588             return (ret);
                24589         if (error == 0)
                24590             error = ret;
                24591     }
                24592 
                24593     /*
                24594     * Process patters. Pattern facets are ORed at type level
                24595     * and ANDed if derived. Walk the base type axis.
                24596     */
                24597     tmpType = type;
                24598     facet = NULL;
                24599     do {
                24600         found = 0;
                24601         for (facetLink = tmpType->facetSet; facetLink != NULL;
                24602             facetLink = facetLink->next) {
                24603             if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
                24604                 continue;
                24605             found = 1;
                24606             /*
                24607             * NOTE that for patterns, @value needs to be the
                24608             * normalized value.
                24609             */
                24610             ret = xmlRegexpExec(facetLink->facet->regexp, value);
                24611             if (ret == 1)
                24612                 break;
                24613             else if (ret < 0) {
                24614                 AERROR_INT("xmlSchemaValidateFacets",
                24615                     "validating against a pattern facet");
                24616                 return (-1);
                24617             } else {
                24618                 /*
                24619                 * Save the last non-validating facet.
                24620                 */
                24621                 facet = facetLink->facet;
                24622             }
                24623         }
                24624         if (found && (ret != 1)) {
                24625             ret = XML_SCHEMAV_CVC_PATTERN_VALID;
                24626             if (fireErrors) {
                24627                 xmlSchemaFacetErr(actxt, ret, node,
                24628                     value, 0, type, facet, NULL, NULL, NULL);
                24629             } else
                24630                 return (ret);
                24631             if (error == 0)
                24632                 error = ret;
                24633             break;
                24634         }
                24635         tmpType = tmpType->baseType;
                24636     } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
                24637 
                24638     return (error);
                24639 }
                24640 
                24641 static xmlChar *
                24642 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
                24643             const xmlChar *value)
                24644 {
                24645     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
                24646     case XML_SCHEMA_WHITESPACE_COLLAPSE:
                24647         return (xmlSchemaCollapseString(value));
                24648     case XML_SCHEMA_WHITESPACE_REPLACE:
                24649         return (xmlSchemaWhiteSpaceReplace(value));
                24650     default:
                24651         return (NULL);
                24652     }
                24653 }
                24654 
                24655 static int
                24656 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
                24657                const xmlChar *value,
                24658                xmlSchemaValPtr *val,
                24659                int valNeeded)
                24660 {
                24661     int ret;
015491ab3 Alex*24662     xmlChar *stripped;
9d9d4fcc3 Alex*24663     const xmlChar *nsName;
                24664     xmlChar *local, *prefix = NULL;
                24665 
                24666     ret = xmlValidateQName(value, 1);
                24667     if (ret != 0) {
                24668     if (ret == -1) {
                24669         VERROR_INT("xmlSchemaValidateQName",
                24670         "calling xmlValidateQName()");
                24671         return (-1);
                24672     }
                24673     return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
                24674     }
                24675     /*
                24676     * NOTE: xmlSplitQName2 will always return a duplicated
                24677     * strings.
                24678     */
015491ab3 Alex*24679     /* TODO: Export and use xmlSchemaStrip instead */
                24680     stripped = xmlSchemaCollapseString(value);
                24681     local = xmlSplitQName2(stripped ? stripped : value, &prefix);
                24682     xmlFree(stripped);
9d9d4fcc3 Alex*24683     if (local == NULL)
                24684     local = xmlStrdup(value);
                24685     /*
                24686     * OPTIMIZE TODO: Use flags for:
                24687     *  - is there any namespace binding?
                24688     *  - is there a default namespace?
                24689     */
                24690     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
                24691 
                24692     if (prefix != NULL) {
                24693     xmlFree(prefix);
                24694     /*
                24695     * A namespace must be found if the prefix is
                24696     * NOT NULL.
                24697     */
                24698     if (nsName == NULL) {
                24699         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
                24700         xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
                24701         WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
                24702         "The QName value '%s' has no "
                24703         "corresponding namespace declaration in "
                24704         "scope", value, NULL);
                24705         if (local != NULL)
                24706         xmlFree(local);
                24707         return (ret);
                24708     }
                24709     }
                24710     if (valNeeded && val) {
                24711     if (nsName != NULL)
                24712         *val = xmlSchemaNewQNameValue(
                24713         BAD_CAST xmlStrdup(nsName), BAD_CAST local);
                24714     else
                24715         *val = xmlSchemaNewQNameValue(NULL,
                24716         BAD_CAST local);
                24717     } else
                24718     xmlFree(local);
                24719     return (0);
                24720 }
                24721 
                24722 /*
                24723 * cvc-simple-type
                24724 */
                24725 static int
                24726 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
                24727                  xmlNodePtr node,
                24728                  xmlSchemaTypePtr type,
                24729                  const xmlChar *value,
                24730                  xmlSchemaValPtr *retVal,
                24731                  int fireErrors,
                24732                  int normalize,
                24733                  int isNormalized)
                24734 {
                24735     int ret = 0, valNeeded = (retVal) ? 1 : 0;
                24736     xmlSchemaValPtr val = NULL;
                24737     /* xmlSchemaWhitespaceValueType ws; */
                24738     xmlChar *normValue = NULL;
                24739 
                24740 #define NORMALIZE(atype) \
                24741     if ((! isNormalized) && \
                24742     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
                24743     normValue = xmlSchemaNormalizeValue(atype, value); \
                24744     if (normValue != NULL) \
                24745         value = normValue; \
                24746     isNormalized = 1; \
                24747     }
                24748 
                24749     if ((retVal != NULL) && (*retVal != NULL)) {
                24750     xmlSchemaFreeValue(*retVal);
                24751     *retVal = NULL;
                24752     }
                24753     /*
                24754     * 3.14.4 Simple Type Definition Validation Rules
                24755     * Validation Rule: String Valid
                24756     */
                24757     /*
                24758     * 1 It is schema-valid with respect to that definition as defined
                24759     * by Datatype Valid in [XML Schemas: Datatypes].
                24760     */
                24761     /*
                24762     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
                24763     * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
                24764     * the string must be a `declared entity name`.
                24765     */
                24766     /*
                24767     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
                24768     * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
                24769     * then every whitespace-delimited substring of the string must be a `declared
                24770     * entity name`.
                24771     */
                24772     /*
                24773     * 2.3 otherwise no further condition applies.
                24774     */
                24775     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
                24776     valNeeded = 1;
                24777     if (value == NULL)
                24778     value = BAD_CAST "";
                24779     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
                24780     xmlSchemaTypePtr biType; /* The built-in type. */
                24781     /*
                24782     * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
                24783     * a literal in the `lexical space` of {base type definition}"
                24784     */
                24785     /*
                24786     * Whitespace-normalize.
                24787     */
                24788     NORMALIZE(type);
                24789     if (type->type != XML_SCHEMA_TYPE_BASIC) {
                24790         /*
                24791         * Get the built-in type.
                24792         */
                24793         biType = type->baseType;
                24794         while ((biType != NULL) &&
                24795         (biType->type != XML_SCHEMA_TYPE_BASIC))
                24796         biType = biType->baseType;
                24797 
                24798         if (biType == NULL) {
                24799         AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                24800             "could not get the built-in type");
                24801         goto internal_error;
                24802         }
                24803     } else
                24804         biType = type;
                24805     /*
                24806     * NOTATIONs need to be processed here, since they need
                24807     * to lookup in the hashtable of NOTATION declarations of the schema.
                24808     */
                24809     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
                24810         switch (biType->builtInType) {
                24811         case XML_SCHEMAS_NOTATION:
                24812             ret = xmlSchemaValidateNotation(
                24813             (xmlSchemaValidCtxtPtr) actxt,
                24814             ((xmlSchemaValidCtxtPtr) actxt)->schema,
                24815             NULL, value, &val, valNeeded);
                24816             break;
                24817         case XML_SCHEMAS_QNAME:
                24818             ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
                24819             value, &val, valNeeded);
                24820             break;
                24821         default:
                24822             /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
                24823             if (valNeeded)
                24824             ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
                24825                 value, &val, node);
                24826             else
                24827             ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
                24828                 value, NULL, node);
                24829             break;
                24830         }
                24831     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
                24832         switch (biType->builtInType) {
                24833         case XML_SCHEMAS_NOTATION:
                24834             ret = xmlSchemaValidateNotation(NULL,
                24835             ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
                24836             value, &val, valNeeded);
                24837             break;
                24838         default:
                24839             /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
                24840             if (valNeeded)
                24841             ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
                24842                 value, &val, node);
                24843             else
                24844             ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
                24845                 value, NULL, node);
                24846             break;
                24847         }
                24848     } else {
                24849         /*
                24850         * Validation via a public API is not implemented yet.
                24851         */
                24852         TODO
                24853         goto internal_error;
                24854     }
                24855     if (ret != 0) {
                24856         if (ret < 0) {
                24857         AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                24858             "validating against a built-in type");
                24859         goto internal_error;
                24860         }
                24861         if (WXS_IS_LIST(type))
                24862         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
                24863         else
                24864         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
                24865     }
                24866     if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
                24867         /*
                24868         * Check facets.
                24869         */
                24870         ret = xmlSchemaValidateFacets(actxt, node, type,
                24871         (xmlSchemaValType) biType->builtInType, value, val,
                24872         0, fireErrors);
                24873         if (ret != 0) {
                24874         if (ret < 0) {
                24875             AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                24876             "validating facets of atomic simple type");
                24877             goto internal_error;
                24878         }
                24879         if (WXS_IS_LIST(type))
                24880             ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
                24881         else
                24882             ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
                24883         }
                24884     }
                24885     else if (fireErrors && (ret > 0))
                24886         xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
                24887     } else if (WXS_IS_LIST(type)) {
                24888 
                24889     xmlSchemaTypePtr itemType;
                24890     const xmlChar *cur, *end;
                24891     xmlChar *tmpValue = NULL;
                24892     unsigned long len = 0;
                24893     xmlSchemaValPtr prevVal = NULL, curVal = NULL;
                24894     /* 1.2.2 if {variety} is `list` then the string must be a sequence
                24895     * of white space separated tokens, each of which `match`es a literal
                24896     * in the `lexical space` of {item type definition}
                24897     */
                24898     /*
                24899     * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
                24900     * the list type has an enum or pattern facet.
                24901     */
                24902     NORMALIZE(type);
                24903     /*
                24904     * VAL TODO: Optimize validation of empty values.
                24905     * VAL TODO: We do not have computed values for lists.
                24906     */
                24907     itemType = WXS_LIST_ITEMTYPE(type);
                24908     cur = value;
                24909     do {
                24910         while (IS_BLANK_CH(*cur))
                24911         cur++;
                24912         end = cur;
                24913         while ((*end != 0) && (!(IS_BLANK_CH(*end))))
                24914         end++;
                24915         if (end == cur)
                24916         break;
                24917         tmpValue = xmlStrndup(cur, end - cur);
                24918         len++;
                24919 
                24920         if (valNeeded)
                24921         ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
                24922             tmpValue, &curVal, fireErrors, 0, 1);
                24923         else
                24924         ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
                24925             tmpValue, NULL, fireErrors, 0, 1);
                24926         FREE_AND_NULL(tmpValue);
                24927         if (curVal != NULL) {
                24928         /*
                24929         * Add to list of computed values.
                24930         */
                24931         if (val == NULL)
                24932             val = curVal;
                24933         else
                24934             xmlSchemaValueAppend(prevVal, curVal);
                24935         prevVal = curVal;
                24936         curVal = NULL;
                24937         }
                24938         if (ret != 0) {
                24939         if (ret < 0) {
                24940             AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                24941             "validating an item of list simple type");
                24942             goto internal_error;
                24943         }
                24944         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
                24945         break;
                24946         }
                24947         cur = end;
                24948     } while (*cur != 0);
                24949     FREE_AND_NULL(tmpValue);
                24950     if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
                24951         /*
                24952         * Apply facets (pattern, enumeration).
                24953         */
                24954         ret = xmlSchemaValidateFacets(actxt, node, type,
                24955         XML_SCHEMAS_UNKNOWN, value, val,
                24956         len, fireErrors);
                24957         if (ret != 0) {
                24958         if (ret < 0) {
                24959             AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                24960             "validating facets of list simple type");
                24961             goto internal_error;
                24962         }
                24963         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
                24964         }
                24965     }
                24966     if (fireErrors && (ret > 0)) {
                24967         /*
                24968         * Report the normalized value.
                24969         */
                24970         normalize = 1;
                24971         NORMALIZE(type);
                24972         xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
                24973     }
                24974     } else if (WXS_IS_UNION(type)) {
                24975     xmlSchemaTypeLinkPtr memberLink;
                24976     /*
                24977     * TODO: For all datatypes `derived` by `union`  whiteSpace does
                24978     * not apply directly; however, the normalization behavior of `union`
                24979     * types is controlled by the value of whiteSpace on that one of the
                24980     * `memberTypes` against which the `union` is successfully validated.
                24981     *
                24982     * This means that the value is normalized by the first validating
                24983     * member type, then the facets of the union type are applied. This
                24984     * needs changing of the value!
                24985     */
                24986 
                24987     /*
                24988     * 1.2.3 if {variety} is `union` then the string must `match` a
                24989     * literal in the `lexical space` of at least one member of
                24990     * {member type definitions}
                24991     */
                24992     memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
                24993     if (memberLink == NULL) {
                24994         AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                24995         "union simple type has no member types");
                24996         goto internal_error;
                24997     }
                24998     /*
                24999     * Always normalize union type values, since we currently
                25000     * cannot store the whitespace information with the value
                25001     * itself; otherwise a later value-comparison would be
                25002     * not possible.
                25003     */
                25004     while (memberLink != NULL) {
                25005         if (valNeeded)
                25006         ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
                25007             memberLink->type, value, &val, 0, 1, 0);
                25008         else
                25009         ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
                25010             memberLink->type, value, NULL, 0, 1, 0);
                25011         if (ret <= 0)
                25012         break;
                25013         memberLink = memberLink->next;
                25014     }
                25015     if (ret != 0) {
                25016         if (ret < 0) {
                25017         AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                25018             "validating members of union simple type");
                25019         goto internal_error;
                25020         }
                25021         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
                25022     }
                25023     /*
                25024     * Apply facets (pattern, enumeration).
                25025     */
                25026     if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
                25027         /*
                25028         * The normalization behavior of `union` types is controlled by
                25029         * the value of whiteSpace on that one of the `memberTypes`
                25030         * against which the `union` is successfully validated.
                25031         */
                25032         NORMALIZE(memberLink->type);
                25033         ret = xmlSchemaValidateFacets(actxt, node, type,
                25034         XML_SCHEMAS_UNKNOWN, value, val,
                25035         0, fireErrors);
                25036         if (ret != 0) {
                25037         if (ret < 0) {
                25038             AERROR_INT("xmlSchemaVCheckCVCSimpleType",
                25039             "validating facets of union simple type");
                25040             goto internal_error;
                25041         }
                25042         ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
                25043         }
                25044     }
                25045     if (fireErrors && (ret > 0))
                25046         xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
                25047     }
                25048 
                25049     if (normValue != NULL)
                25050     xmlFree(normValue);
                25051     if (ret == 0) {
                25052     if (retVal != NULL)
                25053         *retVal = val;
                25054     else if (val != NULL)
                25055         xmlSchemaFreeValue(val);
                25056     } else if (val != NULL)
                25057     xmlSchemaFreeValue(val);
                25058     return (ret);
                25059 internal_error:
                25060     if (normValue != NULL)
                25061     xmlFree(normValue);
                25062     if (val != NULL)
                25063     xmlSchemaFreeValue(val);
                25064     return (-1);
                25065 }
                25066 
                25067 static int
                25068 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
                25069                const xmlChar *value,
                25070                const xmlChar **nsName,
                25071                const xmlChar **localName)
                25072 {
                25073     int ret = 0;
                25074 
                25075     if ((nsName == NULL) || (localName == NULL))
                25076     return (-1);
                25077     *nsName = NULL;
                25078     *localName = NULL;
                25079 
                25080     ret = xmlValidateQName(value, 1);
                25081     if (ret == -1)
                25082     return (-1);
                25083     if (ret > 0) {
                25084     xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
                25085         XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
                25086         value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
                25087     return (1);
                25088     }
                25089     {
                25090     xmlChar *local = NULL;
                25091     xmlChar *prefix;
                25092 
                25093     /*
                25094     * NOTE: xmlSplitQName2 will return a duplicated
                25095     * string.
                25096     */
                25097     local = xmlSplitQName2(value, &prefix);
                25098     if (local == NULL)
                25099         *localName = xmlDictLookup(vctxt->dict, value, -1);
                25100     else {
                25101         *localName = xmlDictLookup(vctxt->dict, local, -1);
                25102         xmlFree(local);
                25103     }
                25104 
                25105     *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
                25106 
                25107     if (prefix != NULL) {
                25108         xmlFree(prefix);
                25109         /*
                25110         * A namespace must be found if the prefix is NOT NULL.
                25111         */
                25112         if (*nsName == NULL) {
                25113         xmlSchemaCustomErr(ACTXT_CAST vctxt,
                25114             XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
                25115             WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
                25116             "The QName value '%s' has no "
                25117             "corresponding namespace declaration in scope",
                25118             value, NULL);
                25119         return (2);
                25120         }
                25121     }
                25122     }
                25123     return (0);
                25124 }
                25125 
                25126 static int
                25127 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
                25128             xmlSchemaAttrInfoPtr iattr,
                25129             xmlSchemaTypePtr *localType,
                25130             xmlSchemaElementPtr elemDecl)
                25131 {
                25132     int ret = 0;
                25133     /*
                25134     * cvc-elt (3.3.4) : (4)
                25135     * AND
                25136     * Schema-Validity Assessment (Element) (cvc-assess-elt)
                25137     *   (1.2.1.2.1) - (1.2.1.2.4)
                25138     * Handle 'xsi:type'.
                25139     */
                25140     if (localType == NULL)
                25141     return (-1);
                25142     *localType = NULL;
                25143     if (iattr == NULL)
                25144     return (0);
                25145     else {
                25146     const xmlChar *nsName = NULL, *local = NULL;
                25147     /*
                25148     * TODO: We should report a *warning* that the type was overridden
                25149     * by the instance.
                25150     */
                25151     ACTIVATE_ATTRIBUTE(iattr);
                25152     /*
                25153     * (cvc-elt) (3.3.4) : (4.1)
                25154     * (cvc-assess-elt) (1.2.1.2.2)
                25155     */
                25156     ret = xmlSchemaVExpandQName(vctxt, iattr->value,
                25157         &nsName, &local);
                25158     if (ret != 0) {
                25159         if (ret < 0) {
                25160         VERROR_INT("xmlSchemaValidateElementByDeclaration",
                25161             "calling xmlSchemaQNameExpand() to validate the "
                25162             "attribute 'xsi:type'");
                25163         goto internal_error;
                25164         }
                25165         goto exit;
                25166     }
                25167     /*
                25168     * (cvc-elt) (3.3.4) : (4.2)
                25169     * (cvc-assess-elt) (1.2.1.2.3)
                25170     */
                25171     *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
                25172     if (*localType == NULL) {
                25173         xmlChar *str = NULL;
                25174 
                25175         xmlSchemaCustomErr(ACTXT_CAST vctxt,
                25176         XML_SCHEMAV_CVC_ELT_4_2, NULL,
                25177         WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
                25178         "The QName value '%s' of the xsi:type attribute does not "
                25179         "resolve to a type definition",
                25180         xmlSchemaFormatQName(&str, nsName, local), NULL);
                25181         FREE_AND_NULL(str);
                25182         ret = vctxt->err;
                25183         goto exit;
                25184     }
                25185     if (elemDecl != NULL) {
                25186         int set = 0;
                25187 
                25188         /*
                25189         * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
                25190         * "The `local type definition` must be validly
                25191         * derived from the {type definition} given the union of
                25192         * the {disallowed substitutions} and the {type definition}'s
                25193         * {prohibited substitutions}, as defined in
                25194         * Type Derivation OK (Complex) ($3.4.6)
                25195         * (if it is a complex type definition),
                25196         * or given {disallowed substitutions} as defined in Type
                25197         * Derivation OK (Simple) ($3.14.6) (if it is a simple type
                25198         * definition)."
                25199         *
                25200         * {disallowed substitutions}: the "block" on the element decl.
                25201         * {prohibited substitutions}: the "block" on the type def.
                25202         */
                25203         /*
                25204         * OPTIMIZE TODO: We could map types already evaluated
                25205         * to be validly derived from other types to avoid checking
                25206         * this over and over for the same types.
                25207         */
                25208         if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
                25209         (elemDecl->subtypes->flags &
                25210             XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
                25211         set |= SUBSET_EXTENSION;
                25212 
                25213         if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
                25214         (elemDecl->subtypes->flags &
                25215             XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
                25216         set |= SUBSET_RESTRICTION;
                25217 
                25218         /*
                25219         * REMOVED and CHANGED since this produced a parser context
                25220         * which adds to the string dict of the schema. So this would
                25221         * change the schema and we don't want this. We don't need
                25222         * the parser context anymore.
                25223         *
                25224         * if ((vctxt->pctxt == NULL) &&
                25225         *   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
                25226         *       return (-1);
                25227         */
                25228 
                25229         if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
                25230         elemDecl->subtypes, set) != 0) {
                25231         xmlChar *str = NULL;
                25232 
                25233         xmlSchemaCustomErr(ACTXT_CAST vctxt,
                25234             XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
                25235             "The type definition '%s', specified by xsi:type, is "
                25236             "blocked or not validly derived from the type definition "
                25237             "of the element declaration",
                25238             xmlSchemaFormatQName(&str,
                25239             (*localType)->targetNamespace,
                25240             (*localType)->name),
                25241             NULL);
                25242         FREE_AND_NULL(str);
                25243         ret = vctxt->err;
                25244         *localType = NULL;
                25245         }
                25246     }
                25247     }
                25248 exit:
                25249     ACTIVATE_ELEM;
                25250     return (ret);
                25251 internal_error:
                25252     ACTIVATE_ELEM;
                25253     return (-1);
                25254 }
                25255 
                25256 static int
                25257 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
                25258 {
                25259     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
                25260     xmlSchemaTypePtr actualType;
                25261 
                25262     /*
                25263     * cvc-elt (3.3.4) : 1
                25264     */
                25265     if (elemDecl == NULL) {
                25266     VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
                25267         "No matching declaration available");
                25268         return (vctxt->err);
                25269     }
                25270     actualType = WXS_ELEM_TYPEDEF(elemDecl);
                25271     /*
                25272     * cvc-elt (3.3.4) : 2
                25273     */
                25274     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
                25275     VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
                25276         "The element declaration is abstract");
                25277         return (vctxt->err);
                25278     }
                25279     if (actualType == NULL) {
                25280     VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
                25281         "The type definition is absent");
                25282     return (XML_SCHEMAV_CVC_TYPE_1);
                25283     }
                25284     if (vctxt->nbAttrInfos != 0) {
                25285     int ret;
                25286     xmlSchemaAttrInfoPtr iattr;
                25287     /*
                25288     * cvc-elt (3.3.4) : 3
                25289     * Handle 'xsi:nil'.
                25290     */
                25291     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
                25292         XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
                25293     if (iattr) {
                25294         ACTIVATE_ATTRIBUTE(iattr);
                25295         /*
                25296         * Validate the value.
                25297         */
                25298         ret = xmlSchemaVCheckCVCSimpleType(
                25299         ACTXT_CAST vctxt, NULL,
                25300         xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
                25301         iattr->value, &(iattr->val), 1, 0, 0);
                25302         ACTIVATE_ELEM;
                25303         if (ret < 0) {
                25304         VERROR_INT("xmlSchemaValidateElemDecl",
                25305             "calling xmlSchemaVCheckCVCSimpleType() to "
                25306             "validate the attribute 'xsi:nil'");
                25307         return (-1);
                25308         }
                25309         if (ret == 0) {
                25310         if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
                25311             /*
                25312             * cvc-elt (3.3.4) : 3.1
                25313             */
                25314             VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
                25315             "The element is not 'nillable'");
                25316             /* Does not return an error on purpose. */
                25317         } else {
                25318             if (xmlSchemaValueGetAsBoolean(iattr->val)) {
                25319             /*
                25320             * cvc-elt (3.3.4) : 3.2.2
                25321             */
                25322             if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
                25323                 (elemDecl->value != NULL)) {
                25324                 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
                25325                 "The element cannot be 'nilled' because "
                25326                 "there is a fixed value constraint defined "
                25327                 "for it");
                25328                  /* Does not return an error on purpose. */
                25329             } else
                25330                 vctxt->inode->flags |=
                25331                 XML_SCHEMA_ELEM_INFO_NILLED;
                25332             }
                25333         }
                25334         }
                25335     }
                25336     /*
                25337     * cvc-elt (3.3.4) : 4
                25338     * Handle 'xsi:type'.
                25339     */
                25340     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
                25341         XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
                25342     if (iattr) {
                25343         xmlSchemaTypePtr localType = NULL;
                25344 
                25345         ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
                25346         elemDecl);
                25347         if (ret != 0) {
                25348         if (ret == -1) {
                25349             VERROR_INT("xmlSchemaValidateElemDecl",
                25350             "calling xmlSchemaProcessXSIType() to "
                25351             "process the attribute 'xsi:type'");
                25352             return (-1);
                25353         }
                25354         /* Does not return an error on purpose. */
                25355         }
                25356         if (localType != NULL) {
                25357         vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
                25358         actualType = localType;
                25359         }
                25360     }
                25361     }
                25362     /*
                25363     * IDC: Register identity-constraint XPath matchers.
                25364     */
                25365     if ((elemDecl->idcs != NULL) &&
                25366     (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
                25367         return (-1);
                25368     /*
                25369     * No actual type definition.
                25370     */
                25371     if (actualType == NULL) {
                25372     VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
                25373         "The type definition is absent");
                25374     return (XML_SCHEMAV_CVC_TYPE_1);
                25375     }
                25376     /*
                25377     * Remember the actual type definition.
                25378     */
                25379     vctxt->inode->typeDef = actualType;
                25380 
                25381     return (0);
                25382 }
                25383 
                25384 static int
                25385 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
                25386 {
                25387     xmlSchemaAttrInfoPtr iattr;
                25388     int ret = 0, i;
                25389 
                25390     /*
                25391     * SPEC cvc-type (3.1.1)
                25392     * "The attributes of must be empty, excepting those whose namespace
                25393     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
                25394     * whose local name is one of type, nil, schemaLocation or
                25395     * noNamespaceSchemaLocation."
                25396     */
                25397     if (vctxt->nbAttrInfos == 0)
                25398     return (0);
                25399     for (i = 0; i < vctxt->nbAttrInfos; i++) {
                25400     iattr = vctxt->attrInfos[i];
                25401     if (! iattr->metaType) {
                25402         ACTIVATE_ATTRIBUTE(iattr)
                25403         xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
                25404         XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
                25405         ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
                25406         }
                25407     }
                25408     ACTIVATE_ELEM
                25409     return (ret);
                25410 }
                25411 
                25412 /*
                25413 * Cleanup currently used attribute infos.
                25414 */
                25415 static void
                25416 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
                25417 {
                25418     int i;
                25419     xmlSchemaAttrInfoPtr attr;
                25420 
                25421     if (vctxt->nbAttrInfos == 0)
                25422     return;
                25423     for (i = 0; i < vctxt->nbAttrInfos; i++) {
                25424     attr = vctxt->attrInfos[i];
                25425     if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
                25426         if (attr->localName != NULL)
                25427         xmlFree((xmlChar *) attr->localName);
                25428         if (attr->nsName != NULL)
                25429         xmlFree((xmlChar *) attr->nsName);
                25430     }
                25431     if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
                25432         if (attr->value != NULL)
                25433         xmlFree((xmlChar *) attr->value);
                25434     }
                25435     if (attr->val != NULL) {
                25436         xmlSchemaFreeValue(attr->val);
                25437         attr->val = NULL;
                25438     }
                25439     memset(attr, 0, sizeof(xmlSchemaAttrInfo));
                25440     }
                25441     vctxt->nbAttrInfos = 0;
                25442 }
                25443 
                25444 /*
                25445 * 3.4.4 Complex Type Definition Validation Rules
                25446 *   Element Locally Valid (Complex Type) (cvc-complex-type)
                25447 * 3.2.4 Attribute Declaration Validation Rules
                25448 *   Validation Rule: Attribute Locally Valid (cvc-attribute)
                25449 *   Attribute Locally Valid (Use) (cvc-au)
                25450 *
                25451 * Only "assessed" attribute information items will be visible to
                25452 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
                25453 */
                25454 static int
                25455 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
                25456 {
                25457     xmlSchemaTypePtr type = vctxt->inode->typeDef;
                25458     xmlSchemaItemListPtr attrUseList;
                25459     xmlSchemaAttributeUsePtr attrUse = NULL;
                25460     xmlSchemaAttributePtr attrDecl = NULL;
                25461     xmlSchemaAttrInfoPtr iattr, tmpiattr;
                25462     int i, j, found, nbAttrs, nbUses;
                25463     int xpathRes = 0, res, wildIDs = 0, fixed;
                25464     xmlNodePtr defAttrOwnerElem = NULL;
                25465 
                25466     /*
                25467     * SPEC (cvc-attribute)
                25468     * (1) "The declaration must not be `absent` (see Missing
                25469     * Sub-components ($5.3) for how this can fail to be
                25470     * the case)."
                25471     * (2) "Its {type definition} must not be absent."
                25472     *
                25473     * NOTE (1) + (2): This is not handled here, since we currently do not
                25474     * allow validation against schemas which have missing sub-components.
                25475     *
                25476     * SPEC (cvc-complex-type)
                25477     * (3) "For each attribute information item in the element information
                25478     * item's [attributes] excepting those whose [namespace name] is
                25479     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
                25480     * [local name] is one of type, nil, schemaLocation or
                25481     * noNamespaceSchemaLocation, the appropriate case among the following
                25482     * must be true:
                25483     *
                25484     */
                25485     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
                25486     /*
                25487     * @nbAttrs is the number of attributes present in the instance.
                25488     */
                25489     nbAttrs = vctxt->nbAttrInfos;
                25490     if (attrUseList != NULL)
                25491     nbUses = attrUseList->nbItems;
                25492     else
                25493     nbUses = 0;
                25494     for (i = 0; i < nbUses; i++) {
                25495         found = 0;
                25496     attrUse = attrUseList->items[i];
                25497     attrDecl = WXS_ATTRUSE_DECL(attrUse);
                25498         for (j = 0; j < nbAttrs; j++) {
                25499         iattr = vctxt->attrInfos[j];
                25500         /*
                25501         * SPEC (cvc-complex-type) (3)
                25502         * Skip meta attributes.
                25503         */
                25504         if (iattr->metaType)
                25505         continue;
                25506         if (iattr->localName[0] != attrDecl->name[0])
                25507         continue;
                25508         if (!xmlStrEqual(iattr->localName, attrDecl->name))
                25509         continue;
                25510         if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
                25511         continue;
                25512         found = 1;
                25513         /*
                25514         * SPEC (cvc-complex-type)
                25515         * (3.1) "If there is among the {attribute uses} an attribute
                25516         * use with an {attribute declaration} whose {name} matches
                25517         * the attribute information item's [local name] and whose
                25518         * {target namespace} is identical to the attribute information
                25519         * item's [namespace name] (where an `absent` {target namespace}
                25520         * is taken to be identical to a [namespace name] with no value),
                25521         * then the attribute information must be `valid` with respect
                25522         * to that attribute use as per Attribute Locally Valid (Use)
                25523         * ($3.5.4). In this case the {attribute declaration} of that
                25524         * attribute use is the `context-determined declaration` for the
                25525         * attribute information item with respect to Schema-Validity
                25526         * Assessment (Attribute) ($3.2.4) and
                25527         * Assessment Outcome (Attribute) ($3.2.5).
                25528         */
                25529         iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
                25530         iattr->use = attrUse;
                25531         /*
                25532         * Context-determined declaration.
                25533         */
                25534         iattr->decl = attrDecl;
                25535         iattr->typeDef = attrDecl->subtypes;
                25536         break;
                25537     }
                25538 
                25539     if (found)
                25540         continue;
                25541 
                25542     if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
                25543         /*
                25544         * Handle non-existent, required attributes.
                25545         *
                25546         * SPEC (cvc-complex-type)
                25547         * (4) "The {attribute declaration} of each attribute use in
                25548         * the {attribute uses} whose {required} is true matches one
                25549         * of the attribute information items in the element information
                25550         * item's [attributes] as per clause 3.1 above."
                25551         */
                25552         tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
                25553         if (tmpiattr == NULL) {
                25554         VERROR_INT(
                25555             "xmlSchemaVAttributesComplex",
                25556             "calling xmlSchemaGetFreshAttrInfo()");
                25557         return (-1);
                25558         }
                25559         tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
                25560         tmpiattr->use = attrUse;
                25561         tmpiattr->decl = attrDecl;
                25562     } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
                25563         ((attrUse->defValue != NULL) ||
                25564          (attrDecl->defValue != NULL))) {
                25565         /*
                25566         * Handle non-existent, optional, default/fixed attributes.
                25567         */
                25568         tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
                25569         if (tmpiattr == NULL) {
                25570         VERROR_INT(
                25571             "xmlSchemaVAttributesComplex",
                25572             "calling xmlSchemaGetFreshAttrInfo()");
                25573         return (-1);
                25574         }
                25575         tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
                25576         tmpiattr->use = attrUse;
                25577         tmpiattr->decl = attrDecl;
                25578         tmpiattr->typeDef = attrDecl->subtypes;
                25579         tmpiattr->localName = attrDecl->name;
                25580         tmpiattr->nsName = attrDecl->targetNamespace;
                25581     }
                25582     }
                25583 
                25584     if (vctxt->nbAttrInfos == 0)
                25585     return (0);
                25586     /*
                25587     * Validate against the wildcard.
                25588     */
                25589     if (type->attributeWildcard != NULL) {
                25590     /*
                25591     * SPEC (cvc-complex-type)
                25592     * (3.2.1) "There must be an {attribute wildcard}."
                25593     */
                25594     for (i = 0; i < nbAttrs; i++) {
                25595         iattr = vctxt->attrInfos[i];
                25596         /*
                25597         * SPEC (cvc-complex-type) (3)
                25598         * Skip meta attributes.
                25599         */
                25600         if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
                25601         continue;
                25602         /*
                25603         * SPEC (cvc-complex-type)
                25604         * (3.2.2) "The attribute information item must be `valid` with
                25605         * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
                25606         *
                25607         * SPEC Item Valid (Wildcard) (cvc-wildcard)
                25608         * "... its [namespace name] must be `valid` with respect to
                25609         * the wildcard constraint, as defined in Wildcard allows
                25610         * Namespace Name ($3.10.4)."
                25611         */
                25612         if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
                25613             iattr->nsName) == 0) {
                25614         /*
                25615         * Handle processContents.
                25616         *
                25617         * SPEC (cvc-wildcard):
                25618         * processContents | context-determined declaration:
                25619         * "strict"          "mustFind"
                25620         * "lax"             "none"
                25621         * "skip"            "skip"
                25622         */
                25623         if (type->attributeWildcard->processContents ==
                25624             XML_SCHEMAS_ANY_SKIP) {
                25625              /*
                25626             * context-determined declaration = "skip"
                25627             *
                25628             * SPEC PSVI Assessment Outcome (Attribute)
                25629             * [validity] = "notKnown"
                25630             * [validation attempted] = "none"
                25631             */
                25632             iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
                25633             continue;
                25634         }
                25635         /*
                25636         * Find an attribute declaration.
                25637         */
                25638         iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
                25639             iattr->localName, iattr->nsName);
                25640         if (iattr->decl != NULL) {
                25641             iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
                25642             /*
                25643             * SPEC (cvc-complex-type)
                25644             * (5) "Let [Definition:]  the wild IDs be the set of
                25645             * all attribute information item to which clause 3.2
                25646             * applied and whose `validation` resulted in a
                25647             * `context-determined declaration` of mustFind or no
                25648             * `context-determined declaration` at all, and whose
                25649             * [local name] and [namespace name] resolve (as
                25650             * defined by QName resolution (Instance) ($3.15.4)) to
                25651             * an attribute declaration whose {type definition} is
                25652             * or is derived from ID. Then all of the following
                25653             * must be true:"
                25654             */
                25655             iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
                25656             if (xmlSchemaIsDerivedFromBuiltInType(
                25657             iattr->typeDef, XML_SCHEMAS_ID)) {
                25658             /*
                25659             * SPEC (5.1) "There must be no more than one
                25660             * item in `wild IDs`."
                25661             */
                25662             if (wildIDs != 0) {
                25663                 /* VAL TODO */
                25664                 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
                25665                 TODO
                25666                 continue;
                25667             }
                25668             wildIDs++;
                25669             /*
                25670             * SPEC (cvc-complex-type)
                25671             * (5.2) "If `wild IDs` is non-empty, there must not
                25672             * be any attribute uses among the {attribute uses}
                25673             * whose {attribute declaration}'s {type definition}
                25674             * is or is derived from ID."
                25675             */
                25676                         if (attrUseList != NULL) {
                25677                             for (j = 0; j < attrUseList->nbItems; j++) {
                25678                                 if (xmlSchemaIsDerivedFromBuiltInType(
                25679                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
                25680                                     XML_SCHEMAS_ID)) {
                25681                                     /* URGENT VAL TODO: implement */
                25682                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
                25683                                     TODO
                25684                                     break;
                25685                                 }
                25686                             }
                25687                         }
                25688             }
                25689         } else if (type->attributeWildcard->processContents ==
                25690             XML_SCHEMAS_ANY_LAX) {
                25691             iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
                25692             /*
                25693             * SPEC PSVI Assessment Outcome (Attribute)
                25694             * [validity] = "notKnown"
                25695             * [validation attempted] = "none"
                25696             */
                25697         } else {
                25698             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
                25699         }
                25700         }
                25701     }
                25702     }
                25703 
                25704     if (vctxt->nbAttrInfos == 0)
                25705     return (0);
                25706 
                25707     /*
                25708     * Get the owner element; needed for creation of default attributes.
                25709     * This fixes bug #341337, reported by David Grohmann.
                25710     */
                25711     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
                25712     xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
                25713     if (ielem && ielem->node && ielem->node->doc)
                25714         defAttrOwnerElem = ielem->node;
                25715     }
                25716     /*
                25717     * Validate values, create default attributes, evaluate IDCs.
                25718     */
                25719     for (i = 0; i < vctxt->nbAttrInfos; i++) {
                25720     iattr = vctxt->attrInfos[i];
                25721     /*
                25722     * VAL TODO: Note that we won't try to resolve IDCs to
                25723     * "lax" and "skip" validated attributes. Check what to
                25724     * do in this case.
                25725     */
                25726     if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
                25727         (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
                25728         continue;
                25729     /*
                25730     * VAL TODO: What to do if the type definition is missing?
                25731     */
                25732     if (iattr->typeDef == NULL) {
                25733         iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
                25734         continue;
                25735     }
                25736 
                25737     ACTIVATE_ATTRIBUTE(iattr);
                25738     fixed = 0;
                25739     xpathRes = 0;
                25740 
                25741     if (vctxt->xpathStates != NULL) {
                25742         /*
                25743         * Evaluate IDCs.
                25744         */
                25745         xpathRes = xmlSchemaXPathEvaluate(vctxt,
                25746         XML_ATTRIBUTE_NODE);
                25747         if (xpathRes == -1) {
                25748         VERROR_INT("xmlSchemaVAttributesComplex",
                25749             "calling xmlSchemaXPathEvaluate()");
                25750         goto internal_error;
                25751         }
                25752     }
                25753 
                25754     if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
                25755         /*
                25756         * Default/fixed attributes.
                25757         * We need the value only if we need to resolve IDCs or
                25758         * will create default attributes.
                25759         */
                25760         if ((xpathRes) || (defAttrOwnerElem)) {
                25761         if (iattr->use->defValue != NULL) {
                25762             iattr->value = (xmlChar *) iattr->use->defValue;
                25763             iattr->val = iattr->use->defVal;
                25764         } else {
                25765             iattr->value = (xmlChar *) iattr->decl->defValue;
                25766             iattr->val = iattr->decl->defVal;
                25767         }
                25768         /*
                25769         * IDCs will consume the precomputed default value,
                25770         * so we need to clone it.
                25771         */
                25772         if (iattr->val == NULL) {
                25773             VERROR_INT("xmlSchemaVAttributesComplex",
                25774             "default/fixed value on an attribute use was "
                25775             "not precomputed");
                25776             goto internal_error;
                25777         }
                25778         iattr->val = xmlSchemaCopyValue(iattr->val);
                25779         if (iattr->val == NULL) {
                25780             VERROR_INT("xmlSchemaVAttributesComplex",
                25781             "calling xmlSchemaCopyValue()");
                25782             goto internal_error;
                25783         }
                25784         }
                25785         /*
                25786         * PSVI: Add the default attribute to the current element.
                25787         * VAL TODO: Should we use the *normalized* value? This currently
                25788         *   uses the *initial* value.
                25789         */
                25790 
                25791         if (defAttrOwnerElem) {
                25792         xmlChar *normValue;
                25793         const xmlChar *value;
                25794 
                25795         value = iattr->value;
                25796         /*
                25797         * Normalize the value.
                25798         */
                25799         normValue = xmlSchemaNormalizeValue(iattr->typeDef,
                25800             iattr->value);
                25801         if (normValue != NULL)
                25802             value = BAD_CAST normValue;
                25803 
                25804         if (iattr->nsName == NULL) {
                25805             if (xmlNewProp(defAttrOwnerElem,
                25806             iattr->localName, value) == NULL) {
                25807             VERROR_INT("xmlSchemaVAttributesComplex",
                25808                 "calling xmlNewProp()");
                25809             if (normValue != NULL)
                25810                 xmlFree(normValue);
                25811             goto internal_error;
                25812             }
                25813         } else {
                25814             xmlNsPtr ns;
                25815 
                25816             ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
                25817             defAttrOwnerElem, iattr->nsName);
                25818             if (ns == NULL) {
                25819             xmlChar prefix[12];
                25820             int counter = 0;
                25821 
                25822             /*
                25823             * Create a namespace declaration on the validation
                25824             * root node if no namespace declaration is in scope.
                25825             */
                25826             do {
                25827                 snprintf((char *) prefix, 12, "p%d", counter++);
                25828                 ns = xmlSearchNs(defAttrOwnerElem->doc,
                25829                 defAttrOwnerElem, BAD_CAST prefix);
                25830                 if (counter > 1000) {
                25831                 VERROR_INT(
                25832                     "xmlSchemaVAttributesComplex",
                25833                     "could not compute a ns prefix for a "
                25834                     "default/fixed attribute");
                25835                 if (normValue != NULL)
                25836                     xmlFree(normValue);
                25837                 goto internal_error;
                25838                 }
                25839             } while (ns != NULL);
                25840             ns = xmlNewNs(vctxt->validationRoot,
                25841                 iattr->nsName, BAD_CAST prefix);
                25842             }
                25843             /*
                25844             * TODO:
                25845             * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
                25846             * If we have QNames: do we need to ensure there's a
                25847             * prefix defined for the QName?
                25848             */
                25849             xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
                25850         }
                25851         if (normValue != NULL)
                25852             xmlFree(normValue);
                25853         }
                25854         /*
                25855         * Go directly to IDC evaluation.
                25856         */
                25857         goto eval_idcs;
                25858     }
                25859     /*
                25860     * Validate the value.
                25861     */
                25862     if (vctxt->value != NULL) {
                25863         /*
                25864         * Free last computed value; just for safety reasons.
                25865         */
                25866         xmlSchemaFreeValue(vctxt->value);
                25867         vctxt->value = NULL;
                25868     }
                25869     /*
                25870     * Note that the attribute *use* can be unavailable, if
                25871     * the attribute was a wild attribute.
                25872     */
                25873     if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
                25874         ((iattr->use != NULL) &&
                25875          (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
                25876         fixed = 1;
                25877     else
                25878         fixed = 0;
                25879     /*
                25880     * SPEC (cvc-attribute)
                25881     * (3) "The item's `normalized value` must be locally `valid`
                25882     * with respect to that {type definition} as per
                25883     * String Valid ($3.14.4)."
                25884     *
                25885     * VAL TODO: Do we already have the
                25886     * "normalized attribute value" here?
                25887     */
                25888     if (xpathRes || fixed) {
                25889         iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
                25890         /*
                25891         * Request a computed value.
                25892         */
                25893         res = xmlSchemaVCheckCVCSimpleType(
                25894         ACTXT_CAST vctxt,
                25895         iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
                25896         1, 1, 0);
                25897     } else {
                25898         res = xmlSchemaVCheckCVCSimpleType(
                25899         ACTXT_CAST vctxt,
                25900         iattr->node, iattr->typeDef, iattr->value, NULL,
                25901         1, 0, 0);
                25902     }
                25903 
                25904     if (res != 0) {
                25905         if (res == -1) {
                25906         VERROR_INT("xmlSchemaVAttributesComplex",
                25907             "calling xmlSchemaStreamValidateSimpleTypeValue()");
                25908         goto internal_error;
                25909         }
                25910         iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
                25911         /*
                25912         * SPEC PSVI Assessment Outcome (Attribute)
                25913         * [validity] = "invalid"
                25914         */
                25915         goto eval_idcs;
                25916     }
                25917 
                25918     if (fixed) {
                25919         /*
                25920         * SPEC Attribute Locally Valid (Use) (cvc-au)
                25921         * "For an attribute information item to be `valid`
                25922         * with respect to an attribute use its *normalized*
                25923         * value must match the *canonical* lexical
                25924         * representation of the attribute use's {value
                25925         * constraint}value, if it is present and fixed."
                25926         *
                25927         * VAL TODO: The requirement for the *canonical* value
                25928         * will be removed in XML Schema 1.1.
                25929         */
                25930         /*
                25931         * SPEC Attribute Locally Valid (cvc-attribute)
                25932         * (4) "The item's *actual* value must match the *value* of
                25933         * the {value constraint}, if it is present and fixed."
                25934         */
                25935         if (iattr->val == NULL) {
                25936         /* VAL TODO: A value was not precomputed. */
                25937         TODO
                25938         goto eval_idcs;
                25939         }
                25940         if ((iattr->use != NULL) &&
                25941         (iattr->use->defValue != NULL)) {
                25942         if (iattr->use->defVal == NULL) {
                25943             /* VAL TODO: A default value was not precomputed. */
                25944             TODO
                25945             goto eval_idcs;
                25946         }
                25947         iattr->vcValue = iattr->use->defValue;
                25948         /*
                25949         if (xmlSchemaCompareValuesWhtsp(attr->val,
                25950             (xmlSchemaWhitespaceValueType) ws,
                25951             attr->use->defVal,
                25952             (xmlSchemaWhitespaceValueType) ws) != 0) {
                25953         */
                25954         if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
                25955             iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
                25956         } else {
                25957         if (iattr->decl->defVal == NULL) {
                25958             /* VAL TODO: A default value was not precomputed. */
                25959             TODO
                25960             goto eval_idcs;
                25961         }
                25962         iattr->vcValue = iattr->decl->defValue;
                25963         /*
                25964         if (xmlSchemaCompareValuesWhtsp(attr->val,
                25965             (xmlSchemaWhitespaceValueType) ws,
                25966             attrDecl->defVal,
                25967             (xmlSchemaWhitespaceValueType) ws) != 0) {
                25968         */
                25969         if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
                25970             iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
                25971         }
                25972         /*
                25973         * [validity] = "valid"
                25974         */
                25975     }
                25976 eval_idcs:
                25977     /*
                25978     * Evaluate IDCs.
                25979     */
                25980     if (xpathRes) {
                25981         if (xmlSchemaXPathProcessHistory(vctxt,
                25982         vctxt->depth +1) == -1) {
                25983         VERROR_INT("xmlSchemaVAttributesComplex",
                25984             "calling xmlSchemaXPathEvaluate()");
                25985         goto internal_error;
                25986         }
                25987     } else if (vctxt->xpathStates != NULL)
                25988         xmlSchemaXPathPop(vctxt);
                25989     }
                25990 
                25991     /*
                25992     * Report errors.
                25993     */
                25994     for (i = 0; i < vctxt->nbAttrInfos; i++) {
                25995     iattr = vctxt->attrInfos[i];
                25996     if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
                25997         (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
                25998         (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
                25999         (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
                26000         continue;
                26001     ACTIVATE_ATTRIBUTE(iattr);
                26002     switch (iattr->state) {
                26003         case XML_SCHEMAS_ATTR_ERR_MISSING: {
                26004             xmlChar *str = NULL;
                26005             ACTIVATE_ELEM;
                26006             xmlSchemaCustomErr(ACTXT_CAST vctxt,
                26007             XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
                26008             "The attribute '%s' is required but missing",
                26009             xmlSchemaFormatQName(&str,
                26010                 iattr->decl->targetNamespace,
                26011                 iattr->decl->name),
                26012             NULL);
                26013             FREE_AND_NULL(str)
                26014             break;
                26015         }
                26016         case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
                26017         VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
                26018             "The type definition is absent");
                26019         break;
                26020         case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
                26021         xmlSchemaCustomErr(ACTXT_CAST vctxt,
                26022             XML_SCHEMAV_CVC_AU, NULL, NULL,
                26023             "The value '%s' does not match the fixed "
                26024             "value constraint '%s'",
                26025             iattr->value, iattr->vcValue);
                26026         break;
                26027         case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
                26028         VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
                26029             "No matching global attribute declaration available, but "
                26030             "demanded by the strict wildcard");
                26031         break;
                26032         case XML_SCHEMAS_ATTR_UNKNOWN:
                26033         if (iattr->metaType)
                26034             break;
                26035         /*
                26036         * MAYBE VAL TODO: One might report different error messages
                26037         * for the following errors.
                26038         */
                26039         if (type->attributeWildcard == NULL) {
                26040             xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
                26041             XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
                26042         } else {
                26043             xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
                26044             XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
                26045         }
                26046         break;
                26047         default:
                26048         break;
                26049     }
                26050     }
                26051 
                26052     ACTIVATE_ELEM;
                26053     return (0);
                26054 internal_error:
                26055     ACTIVATE_ELEM;
                26056     return (-1);
                26057 }
                26058 
                26059 static int
                26060 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
                26061                   int *skip)
                26062 {
                26063     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
                26064     /*
                26065     * The namespace of the element was already identified to be
                26066     * matching the wildcard.
                26067     */
                26068     if ((skip == NULL) || (wild == NULL) ||
                26069     (wild->type != XML_SCHEMA_TYPE_ANY)) {
                26070     VERROR_INT("xmlSchemaValidateElemWildcard",
                26071         "bad arguments");
                26072     return (-1);
                26073     }
                26074     *skip = 0;
                26075     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
                26076     /*
                26077     * URGENT VAL TODO: Either we need to position the stream to the
                26078     * next sibling, or walk the whole subtree.
                26079     */
                26080     *skip = 1;
                26081     return (0);
                26082     }
                26083     {
                26084     xmlSchemaElementPtr decl = NULL;
                26085 
                26086     decl = xmlSchemaGetElem(vctxt->schema,
                26087         vctxt->inode->localName, vctxt->inode->nsName);
                26088     if (decl != NULL) {
                26089         vctxt->inode->decl = decl;
                26090         return (0);
                26091     }
                26092     }
                26093     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
                26094     /* VAL TODO: Change to proper error code. */
                26095     VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
                26096         "No matching global element declaration available, but "
                26097         "demanded by the strict wildcard");
                26098     return (vctxt->err);
                26099     }
                26100     if (vctxt->nbAttrInfos != 0) {
                26101     xmlSchemaAttrInfoPtr iattr;
                26102     /*
                26103     * SPEC Validation Rule: Schema-Validity Assessment (Element)
                26104     * (1.2.1.2.1) - (1.2.1.2.3 )
                26105     *
                26106     * Use the xsi:type attribute for the type definition.
                26107     */
                26108     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
                26109         XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
                26110     if (iattr != NULL) {
                26111         if (xmlSchemaProcessXSIType(vctxt, iattr,
                26112         &(vctxt->inode->typeDef), NULL) == -1) {
                26113         VERROR_INT("xmlSchemaValidateElemWildcard",
                26114             "calling xmlSchemaProcessXSIType() to "
                26115             "process the attribute 'xsi:nil'");
                26116         return (-1);
                26117         }
                26118         /*
                26119         * Don't return an error on purpose.
                26120         */
                26121         return (0);
                26122     }
                26123     }
                26124     /*
                26125     * SPEC Validation Rule: Schema-Validity Assessment (Element)
                26126     *
                26127     * Fallback to "anyType".
                26128     */
                26129     vctxt->inode->typeDef =
                26130     xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
                26131     return (0);
                26132 }
                26133 
                26134 /*
                26135 * xmlSchemaCheckCOSValidDefault:
                26136 *
                26137 * This will be called if: not nilled, no content and a default/fixed
                26138 * value is provided.
                26139 */
                26140 
                26141 static int
                26142 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
                26143                   const xmlChar *value,
                26144                   xmlSchemaValPtr *val)
                26145 {
                26146     int ret = 0;
                26147     xmlSchemaNodeInfoPtr inode = vctxt->inode;
                26148 
                26149     /*
                26150     * cos-valid-default:
                26151     * Schema Component Constraint: Element Default Valid (Immediate)
                26152     * For a string to be a valid default with respect to a type
                26153     * definition the appropriate case among the following must be true:
                26154     */
                26155     if WXS_IS_COMPLEX(inode->typeDef) {
                26156     /*
                26157     * Complex type.
                26158     *
                26159     * SPEC (2.1) "its {content type} must be a simple type definition
                26160     * or mixed."
                26161     * SPEC (2.2.2) "If the {content type} is mixed, then the {content
                26162     * type}'s particle must be `emptiable` as defined by
                26163     * Particle Emptiable ($3.9.6)."
                26164     */
                26165     if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
                26166         ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
                26167          (! WXS_EMPTIABLE(inode->typeDef)))) {
                26168         ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
                26169         /* NOTE that this covers (2.2.2) as well. */
                26170         VERROR(ret, NULL,
                26171         "For a string to be a valid default, the type definition "
                26172         "must be a simple type or a complex type with simple content "
                26173         "or mixed content and a particle emptiable");
                26174         return(ret);
                26175     }
                26176     }
                26177     /*
                26178     * 1 If the type definition is a simple type definition, then the string
                26179     * must be `valid` with respect to that definition as defined by String
                26180     * Valid ($3.14.4).
                26181     *
                26182     * AND
                26183     *
                26184     * 2.2.1 If the {content type} is a simple type definition, then the
                26185     * string must be `valid` with respect to that simple type definition
                26186     * as defined by String Valid ($3.14.4).
                26187     */
                26188     if (WXS_IS_SIMPLE(inode->typeDef)) {
                26189 
                26190     ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
                26191         NULL, inode->typeDef, value, val, 1, 1, 0);
                26192 
                26193     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
                26194 
                26195     ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
                26196         NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
                26197     }
                26198     if (ret < 0) {
                26199     VERROR_INT("xmlSchemaCheckCOSValidDefault",
                26200         "calling xmlSchemaVCheckCVCSimpleType()");
                26201     }
                26202     return (ret);
                26203 }
                26204 
                26205 static void
                26206 xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
                26207                    const xmlChar * name ATTRIBUTE_UNUSED,
                26208                    void *transdata, void *inputdata)
                26209 {
                26210     xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
                26211     xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
                26212     inode->decl = item;
                26213 #ifdef DEBUG_CONTENT
                26214     {
                26215     xmlChar *str = NULL;
                26216 
                26217     if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
                26218         xmlGenericError(xmlGenericErrorContext,
                26219         "AUTOMATON callback for '%s' [declaration]\n",
                26220         xmlSchemaFormatQName(&str,
                26221         inode->localName, inode->nsName));
                26222     } else {
                26223         xmlGenericError(xmlGenericErrorContext,
                26224             "AUTOMATON callback for '%s' [wildcard]\n",
                26225             xmlSchemaFormatQName(&str,
                26226             inode->localName, inode->nsName));
                26227 
                26228     }
                26229     FREE_AND_NULL(str)
                26230     }
                26231 #endif
                26232 }
                26233 
                26234 static int
                26235 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
                26236 {
                26237     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
                26238     if (vctxt->inode == NULL) {
                26239     VERROR_INT("xmlSchemaValidatorPushElem",
                26240         "calling xmlSchemaGetFreshElemInfo()");
                26241     return (-1);
                26242     }
                26243     vctxt->nbAttrInfos = 0;
                26244     return (0);
                26245 }
                26246 
                26247 static int
                26248 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
                26249                  xmlSchemaNodeInfoPtr inode,
                26250                  xmlSchemaTypePtr type,
                26251                  const xmlChar *value)
                26252 {
                26253     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
                26254     return (xmlSchemaVCheckCVCSimpleType(
                26255         ACTXT_CAST vctxt, NULL,
                26256         type, value, &(inode->val), 1, 1, 0));
                26257     else
                26258     return (xmlSchemaVCheckCVCSimpleType(
                26259         ACTXT_CAST vctxt, NULL,
                26260         type, value, NULL, 1, 0, 0));
                26261 }
                26262 
                26263 
                26264 
                26265 /*
                26266 * Process END of element.
                26267 */
                26268 static int
                26269 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
                26270 {
                26271     int ret = 0;
                26272     xmlSchemaNodeInfoPtr inode = vctxt->inode;
                26273 
                26274     if (vctxt->nbAttrInfos != 0)
                26275     xmlSchemaClearAttrInfos(vctxt);
                26276     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
                26277     /*
                26278     * This element was not expected;
                26279     * we will not validate child elements of broken parents.
                26280     * Skip validation of all content of the parent.
                26281     */
                26282     vctxt->skipDepth = vctxt->depth -1;
                26283     goto end_elem;
                26284     }
                26285     if ((inode->typeDef == NULL) ||
                26286     (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
                26287     /*
                26288     * 1. the type definition might be missing if the element was
                26289     *    error prone
                26290     * 2. it might be abstract.
                26291     */
                26292     goto end_elem;
                26293     }
                26294     /*
                26295     * Check the content model.
                26296     */
                26297     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
                26298     (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
                26299 
                26300     /*
                26301     * Workaround for "anyType".
                26302     */
                26303     if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
                26304         goto character_content;
                26305 
                26306     if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
                26307         xmlChar *values[10];
                26308         int terminal, nbval = 10, nbneg;
                26309 
                26310         if (inode->regexCtxt == NULL) {
                26311         /*
                26312         * Create the regex context.
                26313         */
                26314         inode->regexCtxt =
                26315             xmlRegNewExecCtxt(inode->typeDef->contModel,
                26316             xmlSchemaVContentModelCallback, vctxt);
                26317         if (inode->regexCtxt == NULL) {
                26318             VERROR_INT("xmlSchemaValidatorPopElem",
                26319             "failed to create a regex context");
                26320             goto internal_error;
                26321         }
                26322 #ifdef DEBUG_AUTOMATA
                26323         xmlGenericError(xmlGenericErrorContext,
                26324             "AUTOMATON create on '%s'\n", inode->localName);
                26325 #endif
                26326         }
                26327 
                26328         /*
                26329          * Do not check further content if the node has been nilled
                26330          */
                26331         if (INODE_NILLED(inode)) {
                26332         ret = 0;
                26333 #ifdef DEBUG_AUTOMATA
                26334         xmlGenericError(xmlGenericErrorContext,
                26335             "AUTOMATON succeeded on nilled '%s'\n",
                26336             inode->localName);
                26337 #endif
                26338                 goto skip_nilled;
                26339         }
                26340 
                26341         /*
                26342         * Get hold of the still expected content, since a further
                26343         * call to xmlRegExecPushString() will lose this information.
                26344         */
                26345         xmlRegExecNextValues(inode->regexCtxt,
                26346         &nbval, &nbneg, &values[0], &terminal);
                26347         ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
                26348         if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
                26349         /*
                26350         * Still missing something.
                26351         */
                26352         ret = 1;
                26353         inode->flags |=
                26354             XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
                26355         xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
                26356             XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
                26357             "Missing child element(s)",
                26358             nbval, nbneg, values);
                26359 #ifdef DEBUG_AUTOMATA
                26360         xmlGenericError(xmlGenericErrorContext,
                26361             "AUTOMATON missing ERROR on '%s'\n",
                26362             inode->localName);
                26363 #endif
                26364         } else {
                26365         /*
                26366         * Content model is satisfied.
                26367         */
                26368         ret = 0;
                26369 #ifdef DEBUG_AUTOMATA
                26370         xmlGenericError(xmlGenericErrorContext,
                26371             "AUTOMATON succeeded on '%s'\n",
                26372             inode->localName);
                26373 #endif
                26374         }
                26375 
                26376     }
                26377     }
                26378 
                26379 skip_nilled:
                26380 
                26381     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
                26382     goto end_elem;
                26383 
                26384 character_content:
                26385 
                26386     if (vctxt->value != NULL) {
                26387     xmlSchemaFreeValue(vctxt->value);
                26388     vctxt->value = NULL;
                26389     }
                26390     /*
                26391     * Check character content.
                26392     */
                26393     if (inode->decl == NULL) {
                26394     /*
                26395     * Speedup if no declaration exists.
                26396     */
                26397     if (WXS_IS_SIMPLE(inode->typeDef)) {
                26398         ret = xmlSchemaVCheckINodeDataType(vctxt,
                26399         inode, inode->typeDef, inode->value);
                26400     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
                26401         ret = xmlSchemaVCheckINodeDataType(vctxt,
                26402         inode, inode->typeDef->contentTypeDef,
                26403         inode->value);
                26404     }
                26405     if (ret < 0) {
                26406         VERROR_INT("xmlSchemaValidatorPopElem",
                26407         "calling xmlSchemaVCheckCVCSimpleType()");
                26408         goto internal_error;
                26409     }
                26410     goto end_elem;
                26411     }
                26412     /*
                26413     * cvc-elt (3.3.4) : 5
                26414     * The appropriate case among the following must be true:
                26415     */
                26416     /*
                26417     * cvc-elt (3.3.4) : 5.1
                26418     * If the declaration has a {value constraint},
                26419     * the item has neither element nor character [children] and
                26420     * clause 3.2 has not applied, then all of the following must be true:
                26421     */
                26422     if ((inode->decl->value != NULL) &&
                26423     (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
                26424     (! INODE_NILLED(inode))) {
                26425     /*
                26426     * cvc-elt (3.3.4) : 5.1.1
                26427     * If the `actual type definition` is a `local type definition`
                26428     * then the canonical lexical representation of the {value constraint}
                26429     * value must be a valid default for the `actual type definition` as
                26430     * defined in Element Default Valid (Immediate) ($3.3.6).
                26431     */
                26432     /*
                26433     * NOTE: 'local' above means types acquired by xsi:type.
                26434     * NOTE: Although the *canonical* value is stated, it is not
                26435     * relevant if canonical or not. Additionally XML Schema 1.1
                26436     * will removed this requirement as well.
                26437     */
                26438     if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
                26439 
                26440         ret = xmlSchemaCheckCOSValidDefault(vctxt,
                26441         inode->decl->value, &(inode->val));
                26442         if (ret != 0) {
                26443         if (ret < 0) {
                26444             VERROR_INT("xmlSchemaValidatorPopElem",
                26445             "calling xmlSchemaCheckCOSValidDefault()");
                26446             goto internal_error;
                26447         }
                26448         goto end_elem;
                26449         }
                26450         /*
                26451         * Stop here, to avoid redundant validation of the value
                26452         * (see following).
                26453         */
                26454         goto default_psvi;
                26455     }
                26456     /*
                26457     * cvc-elt (3.3.4) : 5.1.2
                26458     * The element information item with the canonical lexical
                26459     * representation of the {value constraint} value used as its
                26460     * `normalized value` must be `valid` with respect to the
                26461     * `actual type definition` as defined by Element Locally Valid (Type)
                26462     * ($3.3.4).
                26463     */
                26464     if (WXS_IS_SIMPLE(inode->typeDef)) {
                26465         ret = xmlSchemaVCheckINodeDataType(vctxt,
                26466         inode, inode->typeDef, inode->decl->value);
                26467     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
                26468         ret = xmlSchemaVCheckINodeDataType(vctxt,
                26469         inode, inode->typeDef->contentTypeDef,
                26470         inode->decl->value);
                26471     }
                26472     if (ret != 0) {
                26473         if (ret < 0) {
                26474         VERROR_INT("xmlSchemaValidatorPopElem",
                26475             "calling xmlSchemaVCheckCVCSimpleType()");
                26476         goto internal_error;
                26477         }
                26478         goto end_elem;
                26479     }
                26480 
                26481 default_psvi:
                26482     /*
                26483     * PSVI: Create a text node on the instance element.
                26484     */
                26485     if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
                26486         (inode->node != NULL)) {
                26487         xmlNodePtr textChild;
                26488         xmlChar *normValue;
                26489         /*
                26490         * VAL TODO: Normalize the value.
                26491         */
                26492         normValue = xmlSchemaNormalizeValue(inode->typeDef,
                26493         inode->decl->value);
                26494         if (normValue != NULL) {
015491ab3 Alex*26495         textChild = xmlNewDocText(inode->node->doc,
                26496                         BAD_CAST normValue);
9d9d4fcc3 Alex*26497         xmlFree(normValue);
                26498         } else
015491ab3 Alex*26499         textChild = xmlNewDocText(inode->node->doc,
                26500                         inode->decl->value);
9d9d4fcc3 Alex*26501         if (textChild == NULL) {
                26502         VERROR_INT("xmlSchemaValidatorPopElem",
015491ab3 Alex*26503             "calling xmlNewDocText()");
9d9d4fcc3 Alex*26504         goto internal_error;
                26505         } else
                26506         xmlAddChild(inode->node, textChild);
                26507     }
                26508 
                26509     } else if (! INODE_NILLED(inode)) {
                26510     /*
                26511     * 5.2.1 The element information item must be `valid` with respect
                26512     * to the `actual type definition` as defined by Element Locally
                26513     * Valid (Type) ($3.3.4).
                26514     */
                26515     if (WXS_IS_SIMPLE(inode->typeDef)) {
                26516          /*
                26517         * SPEC (cvc-type) (3.1)
                26518         * "If the type definition is a simple type definition, ..."
                26519         * (3.1.3) "If clause 3.2 of Element Locally Valid
                26520         * (Element) ($3.3.4) did not apply, then the `normalized value`
                26521         * must be `valid` with respect to the type definition as defined
                26522         * by String Valid ($3.14.4).
                26523         */
                26524         ret = xmlSchemaVCheckINodeDataType(vctxt,
                26525             inode, inode->typeDef, inode->value);
                26526     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
                26527         /*
                26528         * SPEC (cvc-type) (3.2) "If the type definition is a complex type
                26529         * definition, then the element information item must be
                26530         * `valid` with respect to the type definition as per
                26531         * Element Locally Valid (Complex Type) ($3.4.4);"
                26532         *
                26533         * SPEC (cvc-complex-type) (2.2)
                26534         * "If the {content type} is a simple type definition, ...
                26535         * the `normalized value` of the element information item is
                26536         * `valid` with respect to that simple type definition as
                26537         * defined by String Valid ($3.14.4)."
                26538         */
                26539         ret = xmlSchemaVCheckINodeDataType(vctxt,
                26540         inode, inode->typeDef->contentTypeDef, inode->value);
                26541     }
                26542     if (ret != 0) {
                26543         if (ret < 0) {
                26544         VERROR_INT("xmlSchemaValidatorPopElem",
                26545             "calling xmlSchemaVCheckCVCSimpleType()");
                26546         goto internal_error;
                26547         }
                26548         goto end_elem;
                26549     }
                26550     /*
                26551     * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
                26552     * not applied, all of the following must be true:
                26553     */
                26554     if ((inode->decl->value != NULL) &&
                26555         (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
                26556 
                26557         /*
                26558         * TODO: We will need a computed value, when comparison is
                26559         * done on computed values.
                26560         */
                26561         /*
                26562         * 5.2.2.1 The element information item must have no element
                26563         * information item [children].
                26564         */
                26565         if (inode->flags &
                26566             XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
                26567         ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
                26568         VERROR(ret, NULL,
                26569             "The content must not contain element nodes since "
                26570             "there is a fixed value constraint");
                26571         goto end_elem;
                26572         } else {
                26573         /*
                26574         * 5.2.2.2 The appropriate case among the following must
                26575         * be true:
                26576         */
                26577         if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
                26578             /*
                26579             * 5.2.2.2.1 If the {content type} of the `actual type
                26580             * definition` is mixed, then the *initial value* of the
                26581             * item must match the canonical lexical representation
                26582             * of the {value constraint} value.
                26583             *
                26584             * ... the *initial value* of an element information
                26585             * item is the string composed of, in order, the
                26586             * [character code] of each character information item in
                26587             * the [children] of that element information item.
                26588             */
                26589             if (! xmlStrEqual(inode->value, inode->decl->value)){
                26590             /*
                26591             * VAL TODO: Report invalid & expected values as well.
                26592             * VAL TODO: Implement the canonical stuff.
                26593             */
                26594             ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
                26595             xmlSchemaCustomErr(ACTXT_CAST vctxt,
                26596                 ret, NULL, NULL,
                26597                 "The initial value '%s' does not match the fixed "
                26598                 "value constraint '%s'",
                26599                 inode->value, inode->decl->value);
                26600             goto end_elem;
                26601             }
                26602         } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
                26603             /*
                26604             * 5.2.2.2.2 If the {content type} of the `actual type
                26605             * definition` is a simple type definition, then the
                26606             * *actual value* of the item must match the canonical
                26607             * lexical representation of the {value constraint} value.
                26608             */
                26609             /*
                26610             * VAL TODO: *actual value* is the normalized value, impl.
                26611             *           this.
                26612             * VAL TODO: Report invalid & expected values as well.
                26613             * VAL TODO: Implement a comparison with the computed values.
                26614             */
                26615             if (! xmlStrEqual(inode->value,
                26616                 inode->decl->value)) {
                26617             ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
                26618             xmlSchemaCustomErr(ACTXT_CAST vctxt,
                26619                 ret, NULL, NULL,
                26620                 "The actual value '%s' does not match the fixed "
                26621                 "value constraint '%s'",
                26622                 inode->value,
                26623                 inode->decl->value);
                26624             goto end_elem;
                26625             }
                26626         }
                26627         }
                26628     }
                26629     }
                26630 
                26631 end_elem:
                26632     if (vctxt->depth < 0) {
                26633     /* TODO: raise error? */
                26634     return (0);
                26635     }
                26636     if (vctxt->depth == vctxt->skipDepth)
                26637     vctxt->skipDepth = -1;
                26638     /*
                26639     * Evaluate the history of XPath state objects.
                26640     */
                26641     if (inode->appliedXPath &&
                26642     (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
                26643     goto internal_error;
                26644     /*
                26645     * MAYBE TODO:
                26646     * SPEC (6) "The element information item must be `valid` with
                26647     * respect to each of the {identity-constraint definitions} as per
                26648     * Identity-constraint Satisfied ($3.11.4)."
                26649     */
                26650     /*
                26651     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
                26652     *   need to be built in any case.
                26653     *   We will currently build IDC node-tables and bubble them only if
                26654     *   keyrefs do exist.
                26655     */
                26656 
                26657     /*
                26658     * Add the current IDC target-nodes to the IDC node-tables.
                26659     */
                26660     if ((inode->idcMatchers != NULL) &&
                26661     (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
                26662     {
                26663     if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
                26664         goto internal_error;
                26665     }
                26666     /*
                26667     * Validate IDC keyrefs.
                26668     */
                26669     if (vctxt->inode->hasKeyrefs)
                26670     if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
                26671         goto internal_error;
                26672     /*
                26673     * Merge/free the IDC table.
                26674     */
                26675     if (inode->idcTable != NULL) {
                26676 #ifdef DEBUG_IDC_NODE_TABLE
                26677     xmlSchemaDebugDumpIDCTable(stdout,
                26678         inode->nsName,
                26679         inode->localName,
                26680         inode->idcTable);
                26681 #endif
                26682     if ((vctxt->depth > 0) &&
                26683         (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
                26684     {
                26685         /*
                26686         * Merge the IDC node table with the table of the parent node.
                26687         */
                26688         if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
                26689         goto internal_error;
                26690     }
                26691     }
                26692     /*
                26693     * Clear the current ielem.
                26694     * VAL TODO: Don't free the PSVI IDC tables if they are
                26695     * requested for the PSVI.
                26696     */
                26697     xmlSchemaClearElemInfo(vctxt, inode);
                26698     /*
                26699     * Skip further processing if we are on the validation root.
                26700     */
                26701     if (vctxt->depth == 0) {
                26702     vctxt->depth--;
                26703     vctxt->inode = NULL;
                26704     return (0);
                26705     }
                26706     /*
                26707     * Reset the keyrefDepth if needed.
                26708     */
                26709     if (vctxt->aidcs != NULL) {
                26710     xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
                26711     do {
                26712         if (aidc->keyrefDepth == vctxt->depth) {
                26713         /*
                26714         * A 'keyrefDepth' of a key/unique IDC matches the current
                26715         * depth, this means that we are leaving the scope of the
                26716         * top-most keyref IDC which refers to this IDC.
                26717         */
                26718         aidc->keyrefDepth = -1;
                26719         }
                26720         aidc = aidc->next;
                26721     } while (aidc != NULL);
                26722     }
                26723     vctxt->depth--;
                26724     vctxt->inode = vctxt->elemInfos[vctxt->depth];
                26725     /*
                26726     * VAL TODO: 7 If the element information item is the `validation root`, it must be
                26727     * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
                26728     */
                26729     return (ret);
                26730 
                26731 internal_error:
                26732     vctxt->err = -1;
                26733     return (-1);
                26734 }
                26735 
                26736 /*
                26737 * 3.4.4 Complex Type Definition Validation Rules
                26738 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
                26739 */
                26740 static int
                26741 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
                26742 {
                26743     xmlSchemaNodeInfoPtr pielem;
                26744     xmlSchemaTypePtr ptype;
                26745     int ret = 0;
                26746 
                26747     if (vctxt->depth <= 0) {
                26748     VERROR_INT("xmlSchemaValidateChildElem",
                26749         "not intended for the validation root");
                26750     return (-1);
                26751     }
                26752     pielem = vctxt->elemInfos[vctxt->depth -1];
                26753     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
                26754     pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
                26755     /*
                26756     * Handle 'nilled' elements.
                26757     */
                26758     if (INODE_NILLED(pielem)) {
                26759     /*
                26760     * SPEC (cvc-elt) (3.3.4) : (3.2.1)
                26761     */
                26762     ACTIVATE_PARENT_ELEM;
                26763     ret = XML_SCHEMAV_CVC_ELT_3_2_1;
                26764     VERROR(ret, NULL,
                26765         "Neither character nor element content is allowed, "
                26766         "because the element was 'nilled'");
                26767     ACTIVATE_ELEM;
                26768     goto unexpected_elem;
                26769     }
                26770 
                26771     ptype = pielem->typeDef;
                26772 
                26773     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
                26774     /*
                26775     * Workaround for "anyType": we have currently no content model
                26776     * assigned for "anyType", so handle it explicitly.
                26777     * "anyType" has an unbounded, lax "any" wildcard.
                26778     */
                26779     vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
                26780         vctxt->inode->localName,
                26781         vctxt->inode->nsName);
                26782 
                26783     if (vctxt->inode->decl == NULL) {
                26784         xmlSchemaAttrInfoPtr iattr;
                26785         /*
                26786         * Process "xsi:type".
                26787         * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
                26788         */
                26789         iattr = xmlSchemaGetMetaAttrInfo(vctxt,
                26790         XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
                26791         if (iattr != NULL) {
                26792         ret = xmlSchemaProcessXSIType(vctxt, iattr,
                26793             &(vctxt->inode->typeDef), NULL);
                26794         if (ret != 0) {
                26795             if (ret == -1) {
                26796             VERROR_INT("xmlSchemaValidateChildElem",
                26797                 "calling xmlSchemaProcessXSIType() to "
                26798                 "process the attribute 'xsi:nil'");
                26799             return (-1);
                26800             }
                26801             return (ret);
                26802         }
                26803         } else {
                26804          /*
                26805          * Fallback to "anyType".
                26806          *
                26807          * SPEC (cvc-assess-elt)
                26808          * "If the item cannot be `strictly assessed`, [...]
                26809          * an element information item's schema validity may be laxly
                26810          * assessed if its `context-determined declaration` is not
                26811          * skip by `validating` with respect to the `ur-type
                26812          * definition` as per Element Locally Valid (Type) ($3.3.4)."
                26813         */
                26814         vctxt->inode->typeDef =
                26815             xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
                26816         }
                26817     }
                26818     return (0);
                26819     }
                26820 
                26821     switch (ptype->contentType) {
                26822     case XML_SCHEMA_CONTENT_EMPTY:
                26823         /*
                26824         * SPEC (2.1) "If the {content type} is empty, then the
                26825         * element information item has no character or element
                26826         * information item [children]."
                26827         */
                26828         ACTIVATE_PARENT_ELEM
                26829         ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
                26830         VERROR(ret, NULL,
                26831         "Element content is not allowed, "
                26832         "because the content type is empty");
                26833         ACTIVATE_ELEM
                26834         goto unexpected_elem;
                26835         break;
                26836 
                26837     case XML_SCHEMA_CONTENT_MIXED:
                26838         case XML_SCHEMA_CONTENT_ELEMENTS: {
                26839         xmlRegExecCtxtPtr regexCtxt;
                26840         xmlChar *values[10];
                26841         int terminal, nbval = 10, nbneg;
                26842 
                26843         /* VAL TODO: Optimized "anyType" validation.*/
                26844 
                26845         if (ptype->contModel == NULL) {
                26846         VERROR_INT("xmlSchemaValidateChildElem",
                26847             "type has elem content but no content model");
                26848         return (-1);
                26849         }
                26850         /*
                26851         * Safety belt for evaluation if the cont. model was already
                26852         * examined to be invalid.
                26853         */
                26854         if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
                26855         VERROR_INT("xmlSchemaValidateChildElem",
                26856             "validating elem, but elem content is already invalid");
                26857         return (-1);
                26858         }
                26859 
                26860         regexCtxt = pielem->regexCtxt;
                26861         if (regexCtxt == NULL) {
                26862         /*
                26863         * Create the regex context.
                26864         */
                26865         regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
                26866             xmlSchemaVContentModelCallback, vctxt);
                26867         if (regexCtxt == NULL) {
                26868             VERROR_INT("xmlSchemaValidateChildElem",
                26869             "failed to create a regex context");
                26870             return (-1);
                26871         }
                26872         pielem->regexCtxt = regexCtxt;
                26873 #ifdef DEBUG_AUTOMATA
                26874         xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
                26875             pielem->localName);
                26876 #endif
                26877         }
                26878 
                26879         /*
                26880         * SPEC (2.4) "If the {content type} is element-only or mixed,
                26881         * then the sequence of the element information item's
                26882         * element information item [children], if any, taken in
                26883         * order, is `valid` with respect to the {content type}'s
                26884         * particle, as defined in Element Sequence Locally Valid
                26885         * (Particle) ($3.9.4)."
                26886         */
                26887         ret = xmlRegExecPushString2(regexCtxt,
                26888         vctxt->inode->localName,
                26889         vctxt->inode->nsName,
                26890         vctxt->inode);
                26891 #ifdef DEBUG_AUTOMATA
                26892         if (ret < 0)
                26893         xmlGenericError(xmlGenericErrorContext,
                26894         "AUTOMATON push ERROR for '%s' on '%s'\n",
                26895         vctxt->inode->localName, pielem->localName);
                26896         else
                26897         xmlGenericError(xmlGenericErrorContext,
                26898         "AUTOMATON push OK for '%s' on '%s'\n",
                26899         vctxt->inode->localName, pielem->localName);
                26900 #endif
                26901         if (vctxt->err == XML_SCHEMAV_INTERNAL) {
                26902         VERROR_INT("xmlSchemaValidateChildElem",
                26903             "calling xmlRegExecPushString2()");
                26904         return (-1);
                26905         }
                26906         if (ret < 0) {
                26907         xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
                26908             &values[0], &terminal);
                26909         xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
                26910             XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
                26911             "This element is not expected",
                26912             nbval, nbneg, values);
                26913         ret = vctxt->err;
                26914         goto unexpected_elem;
                26915         } else
                26916         ret = 0;
                26917     }
                26918         break;
                26919     case XML_SCHEMA_CONTENT_SIMPLE:
                26920     case XML_SCHEMA_CONTENT_BASIC:
                26921         ACTIVATE_PARENT_ELEM
                26922         if (WXS_IS_COMPLEX(ptype)) {
                26923         /*
                26924         * SPEC (cvc-complex-type) (2.2)
                26925         * "If the {content type} is a simple type definition, then
                26926         * the element information item has no element information
                26927         * item [children], ..."
                26928         */
                26929         ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
                26930         VERROR(ret, NULL, "Element content is not allowed, "
                26931             "because the content type is a simple type definition");
                26932         } else {
                26933         /*
                26934         * SPEC (cvc-type) (3.1.2) "The element information item must
                26935         * have no element information item [children]."
                26936         */
                26937         ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
                26938         VERROR(ret, NULL, "Element content is not allowed, "
                26939             "because the type definition is simple");
                26940         }
                26941         ACTIVATE_ELEM
                26942         ret = vctxt->err;
                26943         goto unexpected_elem;
                26944         break;
                26945 
                26946     default:
                26947         break;
                26948     }
                26949     return (ret);
                26950 unexpected_elem:
                26951     /*
                26952     * Pop this element and set the skipDepth to skip
                26953     * all further content of the parent element.
                26954     */
                26955     vctxt->skipDepth = vctxt->depth;
                26956     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
                26957     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
                26958     return (ret);
                26959 }
                26960 
                26961 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
                26962 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
                26963 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
                26964 
                26965 static int
                26966 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
                26967           int nodeType, const xmlChar *value, int len,
                26968           int mode, int *consumed)
                26969 {
                26970     /*
                26971     * Unfortunately we have to duplicate the text sometimes.
                26972     * OPTIMIZE: Maybe we could skip it, if:
                26973     *   1. content type is simple
                26974     *   2. whitespace is "collapse"
                26975     *   3. it consists of whitespace only
                26976     *
                26977     * Process character content.
                26978     */
                26979     if (consumed != NULL)
                26980     *consumed = 0;
                26981     if (INODE_NILLED(vctxt->inode)) {
                26982     /*
                26983     * SPEC cvc-elt (3.3.4 - 3.2.1)
                26984     * "The element information item must have no character or
                26985     * element information item [children]."
                26986     */
                26987     VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
                26988         "Neither character nor element content is allowed "
                26989         "because the element is 'nilled'");
                26990     return (vctxt->err);
                26991     }
                26992     /*
                26993     * SPEC (2.1) "If the {content type} is empty, then the
                26994     * element information item has no character or element
                26995     * information item [children]."
                26996     */
                26997     if (vctxt->inode->typeDef->contentType ==
                26998         XML_SCHEMA_CONTENT_EMPTY) {
                26999     VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
                27000         "Character content is not allowed, "
                27001         "because the content type is empty");
                27002     return (vctxt->err);
                27003     }
                27004 
                27005     if (vctxt->inode->typeDef->contentType ==
                27006         XML_SCHEMA_CONTENT_ELEMENTS) {
                27007     if ((nodeType != XML_TEXT_NODE) ||
                27008         (! xmlSchemaIsBlank((xmlChar *) value, len))) {
                27009         /*
                27010         * SPEC cvc-complex-type (2.3)
                27011         * "If the {content type} is element-only, then the
                27012         * element information item has no character information
                27013         * item [children] other than those whose [character
                27014         * code] is defined as a white space in [XML 1.0 (Second
                27015         * Edition)]."
                27016         */
                27017         VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
                27018         "Character content other than whitespace is not allowed "
                27019         "because the content type is 'element-only'");
                27020         return (vctxt->err);
                27021     }
                27022     return (0);
                27023     }
                27024 
                27025     if ((value == NULL) || (value[0] == 0))
                27026     return (0);
                27027     /*
                27028     * Save the value.
                27029     * NOTE that even if the content type is *mixed*, we need the
                27030     * *initial value* for default/fixed value constraints.
                27031     */
                27032     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
                27033     ((vctxt->inode->decl == NULL) ||
                27034     (vctxt->inode->decl->value == NULL)))
                27035     return (0);
                27036 
                27037     if (vctxt->inode->value == NULL) {
                27038     /*
                27039     * Set the value.
                27040     */
                27041     switch (mode) {
                27042         case XML_SCHEMA_PUSH_TEXT_PERSIST:
                27043         /*
                27044         * When working on a tree.
                27045         */
                27046         vctxt->inode->value = value;
                27047         break;
                27048         case XML_SCHEMA_PUSH_TEXT_CREATED:
                27049         /*
                27050         * When working with the reader.
                27051         * The value will be freed by the element info.
                27052         */
                27053         vctxt->inode->value = value;
                27054         if (consumed != NULL)
                27055             *consumed = 1;
                27056         vctxt->inode->flags |=
                27057             XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
                27058         break;
                27059         case XML_SCHEMA_PUSH_TEXT_VOLATILE:
                27060         /*
                27061         * When working with SAX.
                27062         * The value will be freed by the element info.
                27063         */
                27064         if (len != -1)
                27065             vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
                27066         else
                27067             vctxt->inode->value = BAD_CAST xmlStrdup(value);
                27068         vctxt->inode->flags |=
                27069             XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
                27070         break;
                27071         default:
                27072         break;
                27073     }
                27074     } else {
                27075     if (len < 0)
                27076         len = xmlStrlen(value);
                27077     /*
                27078     * Concat the value.
                27079     */
                27080     if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
                27081         vctxt->inode->value = BAD_CAST xmlStrncat(
                27082         (xmlChar *) vctxt->inode->value, value, len);
                27083     } else {
                27084         vctxt->inode->value =
                27085         BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
                27086         vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
                27087     }
                27088     }
                27089 
                27090     return (0);
                27091 }
                27092 
                27093 static int
                27094 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
                27095 {
                27096     int ret = 0;
                27097 
                27098     if ((vctxt->skipDepth != -1) &&
                27099     (vctxt->depth >= vctxt->skipDepth)) {
                27100     VERROR_INT("xmlSchemaValidateElem",
                27101         "in skip-state");
                27102     goto internal_error;
                27103     }
                27104     if (vctxt->xsiAssemble) {
                27105     /*
                27106     * We will stop validation if there was an error during
                27107     * dynamic schema construction.
                27108     * Note that we simply set @skipDepth to 0, this could
                27109     * mean that a streaming document via SAX would be
                27110     * still read to the end but it won't be validated any more.
                27111     * TODO: If we are sure how to stop the validation at once
                27112     *   for all input scenarios, then this should be changed to
                27113     *   instantly stop the validation.
                27114     */
                27115     ret = xmlSchemaAssembleByXSI(vctxt);
                27116     if (ret != 0) {
                27117         if (ret == -1)
                27118         goto internal_error;
                27119         vctxt->skipDepth = 0;
                27120         return(ret);
                27121     }
                27122         /*
                27123          * Augment the IDC definitions for the main schema and all imported ones
                27124          * NOTE: main schema is the first in the imported list
                27125          */
                27126         xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
                27127                     vctxt);
                27128     }
                27129     if (vctxt->depth > 0) {
                27130     /*
                27131     * Validate this element against the content model
                27132     * of the parent.
                27133     */
                27134     ret = xmlSchemaValidateChildElem(vctxt);
                27135     if (ret != 0) {
                27136         if (ret < 0) {
                27137         VERROR_INT("xmlSchemaValidateElem",
                27138             "calling xmlSchemaStreamValidateChildElement()");
                27139         goto internal_error;
                27140         }
                27141         goto exit;
                27142     }
                27143     if (vctxt->depth == vctxt->skipDepth)
                27144         goto exit;
                27145     if ((vctxt->inode->decl == NULL) &&
                27146         (vctxt->inode->typeDef == NULL)) {
                27147         VERROR_INT("xmlSchemaValidateElem",
                27148         "the child element was valid but neither the "
                27149         "declaration nor the type was set");
                27150         goto internal_error;
                27151     }
                27152     } else {
                27153     /*
                27154     * Get the declaration of the validation root.
                27155     */
                27156     vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
                27157         vctxt->inode->localName,
                27158         vctxt->inode->nsName);
                27159     if (vctxt->inode->decl == NULL) {
                27160         ret = XML_SCHEMAV_CVC_ELT_1;
                27161         VERROR(ret, NULL,
                27162         "No matching global declaration available "
                27163         "for the validation root");
                27164         goto exit;
                27165     }
                27166     }
                27167 
                27168     if (vctxt->inode->decl == NULL)
                27169     goto type_validation;
                27170 
                27171     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
                27172     int skip;
                27173     /*
                27174     * Wildcards.
                27175     */
                27176     ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
                27177     if (ret != 0) {
                27178         if (ret < 0) {
                27179         VERROR_INT("xmlSchemaValidateElem",
                27180             "calling xmlSchemaValidateElemWildcard()");
                27181         goto internal_error;
                27182         }
                27183         goto exit;
                27184     }
                27185     if (skip) {
                27186         vctxt->skipDepth = vctxt->depth;
                27187         goto exit;
                27188     }
                27189     /*
                27190     * The declaration might be set by the wildcard validation,
                27191     * when the processContents is "lax" or "strict".
                27192     */
                27193     if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
                27194         /*
                27195         * Clear the "decl" field to not confuse further processing.
                27196         */
                27197         vctxt->inode->decl = NULL;
                27198         goto type_validation;
                27199     }
                27200     }
                27201     /*
                27202     * Validate against the declaration.
                27203     */
                27204     ret = xmlSchemaValidateElemDecl(vctxt);
                27205     if (ret != 0) {
                27206     if (ret < 0) {
                27207         VERROR_INT("xmlSchemaValidateElem",
                27208         "calling xmlSchemaValidateElemDecl()");
                27209         goto internal_error;
                27210     }
                27211     goto exit;
                27212     }
                27213     /*
                27214     * Validate against the type definition.
                27215     */
                27216 type_validation:
                27217 
                27218     if (vctxt->inode->typeDef == NULL) {
                27219     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
                27220     ret = XML_SCHEMAV_CVC_TYPE_1;
                27221     VERROR(ret, NULL,
                27222         "The type definition is absent");
                27223     goto exit;
                27224     }
                27225     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
                27226     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
                27227     ret = XML_SCHEMAV_CVC_TYPE_2;
                27228         VERROR(ret, NULL,
                27229         "The type definition is abstract");
                27230     goto exit;
                27231     }
                27232     /*
                27233     * Evaluate IDCs. Do it here, since new IDC matchers are registered
                27234     * during validation against the declaration. This must be done
                27235     * _before_ attribute validation.
                27236     */
                27237     if (vctxt->xpathStates != NULL) {
                27238     ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
                27239     vctxt->inode->appliedXPath = 1;
                27240     if (ret == -1) {
                27241         VERROR_INT("xmlSchemaValidateElem",
                27242         "calling xmlSchemaXPathEvaluate()");
                27243         goto internal_error;
                27244     }
                27245     }
                27246     /*
                27247     * Validate attributes.
                27248     */
                27249     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
                27250     if ((vctxt->nbAttrInfos != 0) ||
                27251         (vctxt->inode->typeDef->attrUses != NULL)) {
                27252 
                27253         ret = xmlSchemaVAttributesComplex(vctxt);
                27254     }
                27255     } else if (vctxt->nbAttrInfos != 0) {
                27256 
                27257     ret = xmlSchemaVAttributesSimple(vctxt);
                27258     }
                27259     /*
                27260     * Clear registered attributes.
                27261     */
                27262     if (vctxt->nbAttrInfos != 0)
                27263     xmlSchemaClearAttrInfos(vctxt);
                27264     if (ret == -1) {
                27265     VERROR_INT("xmlSchemaValidateElem",
                27266         "calling attributes validation");
                27267     goto internal_error;
                27268     }
                27269     /*
                27270     * Don't return an error if attributes are invalid on purpose.
                27271     */
                27272     ret = 0;
                27273 
                27274 exit:
                27275     if (ret != 0)
                27276     vctxt->skipDepth = vctxt->depth;
                27277     return (ret);
                27278 internal_error:
                27279     return (-1);
                27280 }
                27281 
                27282 #ifdef XML_SCHEMA_READER_ENABLED
                27283 static int
                27284 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
                27285 {
                27286     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
                27287     int depth, nodeType, ret = 0, consumed;
                27288     xmlSchemaNodeInfoPtr ielem;
                27289 
                27290     vctxt->depth = -1;
                27291     ret = xmlTextReaderRead(vctxt->reader);
                27292     /*
                27293     * Move to the document element.
                27294     */
                27295     while (ret == 1) {
                27296     nodeType = xmlTextReaderNodeType(vctxt->reader);
                27297     if (nodeType == XML_ELEMENT_NODE)
                27298         goto root_found;
                27299     ret = xmlTextReaderRead(vctxt->reader);
                27300     }
                27301     goto exit;
                27302 
                27303 root_found:
                27304 
                27305     do {
                27306     depth = xmlTextReaderDepth(vctxt->reader);
                27307     nodeType = xmlTextReaderNodeType(vctxt->reader);
                27308 
                27309     if (nodeType == XML_ELEMENT_NODE) {
                27310 
                27311         vctxt->depth++;
                27312         if (xmlSchemaValidatorPushElem(vctxt) == -1) {
                27313         VERROR_INT("xmlSchemaVReaderWalk",
                27314             "calling xmlSchemaValidatorPushElem()");
                27315         goto internal_error;
                27316         }
                27317         ielem = vctxt->inode;
                27318         ielem->localName = xmlTextReaderLocalName(vctxt->reader);
                27319         ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
                27320         ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
                27321         /*
                27322         * Is the element empty?
                27323         */
                27324         ret = xmlTextReaderIsEmptyElement(vctxt->reader);
                27325         if (ret == -1) {
                27326         VERROR_INT("xmlSchemaVReaderWalk",
                27327             "calling xmlTextReaderIsEmptyElement()");
                27328         goto internal_error;
                27329         }
                27330         if (ret) {
                27331         ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
                27332         }
                27333         /*
                27334         * Register attributes.
                27335         */
                27336         vctxt->nbAttrInfos = 0;
                27337         ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
                27338         if (ret == -1) {
                27339         VERROR_INT("xmlSchemaVReaderWalk",
                27340             "calling xmlTextReaderMoveToFirstAttribute()");
                27341         goto internal_error;
                27342         }
                27343         if (ret == 1) {
                27344         do {
                27345             /*
                27346             * VAL TODO: How do we know that the reader works on a
                27347             * node tree, to be able to pass a node here?
                27348             */
                27349             if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
                27350             (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
                27351             xmlTextReaderNamespaceUri(vctxt->reader), 1,
                27352             xmlTextReaderValue(vctxt->reader), 1) == -1) {
                27353 
                27354             VERROR_INT("xmlSchemaVReaderWalk",
                27355                 "calling xmlSchemaValidatorPushAttribute()");
                27356             goto internal_error;
                27357             }
                27358             ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
                27359             if (ret == -1) {
                27360             VERROR_INT("xmlSchemaVReaderWalk",
                27361                 "calling xmlTextReaderMoveToFirstAttribute()");
                27362             goto internal_error;
                27363             }
                27364         } while (ret == 1);
                27365         /*
                27366         * Back to element position.
                27367         */
                27368         ret = xmlTextReaderMoveToElement(vctxt->reader);
                27369         if (ret == -1) {
                27370             VERROR_INT("xmlSchemaVReaderWalk",
                27371             "calling xmlTextReaderMoveToElement()");
                27372             goto internal_error;
                27373         }
                27374         }
                27375         /*
                27376         * Validate the element.
                27377         */
                27378         ret= xmlSchemaValidateElem(vctxt);
                27379         if (ret != 0) {
                27380         if (ret == -1) {
                27381             VERROR_INT("xmlSchemaVReaderWalk",
                27382             "calling xmlSchemaValidateElem()");
                27383             goto internal_error;
                27384         }
                27385         goto exit;
                27386         }
                27387         if (vctxt->depth == vctxt->skipDepth) {
                27388         int curDepth;
                27389         /*
                27390         * Skip all content.
                27391         */
                27392         if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
                27393             ret = xmlTextReaderRead(vctxt->reader);
                27394             curDepth = xmlTextReaderDepth(vctxt->reader);
                27395             while ((ret == 1) && (curDepth != depth)) {
                27396             ret = xmlTextReaderRead(vctxt->reader);
                27397             curDepth = xmlTextReaderDepth(vctxt->reader);
                27398             }
                27399             if (ret < 0) {
                27400             /*
                27401             * VAL TODO: A reader error occurred; what to do here?
                27402             */
                27403             ret = 1;
                27404             goto exit;
                27405             }
                27406         }
                27407         goto leave_elem;
                27408         }
                27409         /*
                27410         * READER VAL TODO: Is an END_ELEM really never called
                27411         * if the elem is empty?
                27412         */
                27413         if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
                27414         goto leave_elem;
                27415     } else if (nodeType == END_ELEM) {
                27416         /*
                27417         * Process END of element.
                27418         */
                27419 leave_elem:
                27420         ret = xmlSchemaValidatorPopElem(vctxt);
                27421         if (ret != 0) {
                27422         if (ret < 0) {
                27423             VERROR_INT("xmlSchemaVReaderWalk",
                27424             "calling xmlSchemaValidatorPopElem()");
                27425             goto internal_error;
                27426         }
                27427         goto exit;
                27428         }
                27429         if (vctxt->depth >= 0)
                27430         ielem = vctxt->inode;
                27431         else
                27432         ielem = NULL;
                27433     } else if ((nodeType == XML_TEXT_NODE) ||
                27434         (nodeType == XML_CDATA_SECTION_NODE) ||
                27435         (nodeType == WHTSP) ||
                27436         (nodeType == SIGN_WHTSP)) {
                27437         /*
                27438         * Process character content.
                27439         */
                27440         xmlChar *value;
                27441 
                27442         if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
                27443         nodeType = XML_TEXT_NODE;
                27444 
                27445         value = xmlTextReaderValue(vctxt->reader);
                27446         ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
                27447         -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
                27448         if (! consumed)
                27449         xmlFree(value);
                27450         if (ret == -1) {
                27451         VERROR_INT("xmlSchemaVReaderWalk",
                27452             "calling xmlSchemaVPushText()");
                27453         goto internal_error;
                27454         }
                27455     } else if ((nodeType == XML_ENTITY_NODE) ||
                27456         (nodeType == XML_ENTITY_REF_NODE)) {
                27457         /*
                27458         * VAL TODO: What to do with entities?
                27459         */
                27460         TODO
                27461     }
                27462     /*
                27463     * Read next node.
                27464     */
                27465     ret = xmlTextReaderRead(vctxt->reader);
                27466     } while (ret == 1);
                27467 
                27468 exit:
                27469     return (ret);
                27470 internal_error:
                27471     return (-1);
                27472 }
                27473 #endif
                27474 
                27475 /************************************************************************
                27476  *                                  *
                27477  *          SAX validation handlers             *
                27478  *                                  *
                27479  ************************************************************************/
                27480 
                27481 /*
                27482 * Process text content.
                27483 */
                27484 static void
                27485 xmlSchemaSAXHandleText(void *ctx,
                27486                const xmlChar * ch,
                27487                int len)
                27488 {
                27489     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
                27490 
                27491     if (vctxt->depth < 0)
                27492     return;
                27493     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
                27494     return;
                27495     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
                27496     vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
                27497     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
                27498     XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
                27499     VERROR_INT("xmlSchemaSAXHandleCDataSection",
                27500         "calling xmlSchemaVPushText()");
                27501     vctxt->err = -1;
                27502     xmlStopParser(vctxt->parserCtxt);
                27503     }
                27504 }
                27505 
                27506 /*
                27507 * Process CDATA content.
                27508 */
                27509 static void
                27510 xmlSchemaSAXHandleCDataSection(void *ctx,
                27511                  const xmlChar * ch,
                27512                  int len)
                27513 {
                27514     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
                27515 
                27516     if (vctxt->depth < 0)
                27517     return;
                27518     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
                27519     return;
                27520     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
                27521     vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
                27522     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
                27523     XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
                27524     VERROR_INT("xmlSchemaSAXHandleCDataSection",
                27525         "calling xmlSchemaVPushText()");
                27526     vctxt->err = -1;
                27527     xmlStopParser(vctxt->parserCtxt);
                27528     }
                27529 }
                27530 
                27531 static void
                27532 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
                27533                 const xmlChar * name ATTRIBUTE_UNUSED)
                27534 {
                27535     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
                27536 
                27537     if (vctxt->depth < 0)
                27538     return;
                27539     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
                27540     return;
                27541     /* SAX VAL TODO: What to do here? */
                27542     TODO
                27543 }
                27544 
                27545 static void
                27546 xmlSchemaSAXHandleStartElementNs(void *ctx,
                27547                  const xmlChar * localname,
                27548                  const xmlChar * prefix ATTRIBUTE_UNUSED,
                27549                  const xmlChar * URI,
                27550                  int nb_namespaces,
                27551                  const xmlChar ** namespaces,
                27552                  int nb_attributes,
                27553                  int nb_defaulted ATTRIBUTE_UNUSED,
                27554                  const xmlChar ** attributes)
                27555 {
                27556     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
                27557     int ret;
                27558     xmlSchemaNodeInfoPtr ielem;
                27559     int i, j;
                27560 
                27561     /*
                27562     * SAX VAL TODO: What to do with nb_defaulted?
                27563     */
                27564     /*
                27565     * Skip elements if inside a "skip" wildcard or invalid.
                27566     */
                27567     vctxt->depth++;
                27568     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
                27569     return;
                27570     /*
                27571     * Push the element.
                27572     */
                27573     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
                27574     VERROR_INT("xmlSchemaSAXHandleStartElementNs",
                27575         "calling xmlSchemaValidatorPushElem()");
                27576     goto internal_error;
                27577     }
                27578     ielem = vctxt->inode;
                27579     /*
                27580     * TODO: Is this OK?
                27581     */
                27582     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
                27583     ielem->localName = localname;
                27584     ielem->nsName = URI;
                27585     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
                27586     /*
                27587     * Register namespaces on the elem info.
                27588     */
                27589     if (nb_namespaces != 0) {
                27590     /*
                27591     * Although the parser builds its own namespace list,
                27592     * we have no access to it, so we'll use an own one.
                27593     */
                27594         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
                27595         /*
                27596         * Store prefix and namespace name.
                27597         */
                27598         if (ielem->nsBindings == NULL) {
                27599         ielem->nsBindings =
                27600             (const xmlChar **) xmlMalloc(10 *
                27601             sizeof(const xmlChar *));
                27602         if (ielem->nsBindings == NULL) {
                27603             xmlSchemaVErrMemory(vctxt,
                27604             "allocating namespace bindings for SAX validation",
                27605             NULL);
                27606             goto internal_error;
                27607         }
                27608         ielem->nbNsBindings = 0;
                27609         ielem->sizeNsBindings = 5;
                27610         } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
                27611         ielem->sizeNsBindings *= 2;
                27612         ielem->nsBindings =
                27613             (const xmlChar **) xmlRealloc(
                27614             (void *) ielem->nsBindings,
                27615             ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
                27616         if (ielem->nsBindings == NULL) {
                27617             xmlSchemaVErrMemory(vctxt,
                27618             "re-allocating namespace bindings for SAX validation",
                27619             NULL);
                27620             goto internal_error;
                27621         }
                27622         }
                27623 
                27624         ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
                27625         if (namespaces[j+1][0] == 0) {
                27626         /*
                27627         * Handle xmlns="".
                27628         */
                27629         ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
                27630         } else
                27631         ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
                27632             namespaces[j+1];
                27633         ielem->nbNsBindings++;
                27634     }
                27635     }
                27636     /*
                27637     * Register attributes.
                27638     * SAX VAL TODO: We are not adding namespace declaration
                27639     * attributes yet.
                27640     */
                27641     if (nb_attributes != 0) {
                27642     int valueLen, k, l;
                27643     xmlChar *value;
                27644 
                27645         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
                27646         /*
                27647         * Duplicate the value, changing any &#38; to a literal ampersand.
                27648         *
                27649         * libxml2 differs from normal SAX here in that it escapes all ampersands
                27650         * as &#38; instead of delivering the raw converted string. Changing the
                27651         * behavior at this point would break applications that use this API, so
                27652         * we are forced to work around it.
                27653         */
                27654         valueLen = attributes[j+4] - attributes[j+3];
                27655         value = xmlMallocAtomic(valueLen + 1);
                27656         if (value == NULL) {
                27657         xmlSchemaVErrMemory(vctxt,
                27658             "allocating string for decoded attribute",
                27659             NULL);
                27660         goto internal_error;
                27661         }
                27662         for (k = 0, l = 0; k < valueLen; l++) {
                27663         if (k < valueLen - 4 &&
                27664             attributes[j+3][k+0] == '&' &&
                27665             attributes[j+3][k+1] == '#' &&
                27666             attributes[j+3][k+2] == '3' &&
                27667             attributes[j+3][k+3] == '8' &&
                27668             attributes[j+3][k+4] == ';') {
                27669             value[l] = '&';
                27670             k += 5;
                27671         } else {
                27672             value[l] = attributes[j+3][k];
                27673             k++;
                27674         }
                27675         }
                27676         value[l] = '\0';
                27677         /*
                27678         * TODO: Set the node line.
                27679         */
                27680         ret = xmlSchemaValidatorPushAttribute(vctxt,
                27681         NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
                27682         value, 1);
                27683         if (ret == -1) {
                27684         VERROR_INT("xmlSchemaSAXHandleStartElementNs",
                27685             "calling xmlSchemaValidatorPushAttribute()");
                27686         goto internal_error;
                27687         }
                27688     }
                27689     }
                27690     /*
                27691     * Validate the element.
                27692     */
                27693     ret = xmlSchemaValidateElem(vctxt);
                27694     if (ret != 0) {
                27695     if (ret == -1) {
                27696         VERROR_INT("xmlSchemaSAXHandleStartElementNs",
                27697         "calling xmlSchemaValidateElem()");
                27698         goto internal_error;
                27699     }
                27700     goto exit;
                27701     }
                27702 
                27703 exit:
                27704     return;
                27705 internal_error:
                27706     vctxt->err = -1;
                27707     xmlStopParser(vctxt->parserCtxt);
                27708     return;
                27709 }
                27710 
                27711 static void
                27712 xmlSchemaSAXHandleEndElementNs(void *ctx,
                27713                    const xmlChar * localname ATTRIBUTE_UNUSED,
                27714                    const xmlChar * prefix ATTRIBUTE_UNUSED,
                27715                    const xmlChar * URI ATTRIBUTE_UNUSED)
                27716 {
                27717     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
                27718     int res;
                27719 
                27720     /*
                27721     * Skip elements if inside a "skip" wildcard or if invalid.
                27722     */
                27723     if (vctxt->skipDepth != -1) {
                27724     if (vctxt->depth > vctxt->skipDepth) {
                27725         vctxt->depth--;
                27726         return;
                27727     } else
                27728         vctxt->skipDepth = -1;
                27729     }
                27730     /*
                27731     * SAX VAL TODO: Just a temporary check.
                27732     */
                27733     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
                27734     (!xmlStrEqual(vctxt->inode->nsName, URI))) {
                27735     VERROR_INT("xmlSchemaSAXHandleEndElementNs",
                27736         "elem pop mismatch");
                27737     }
                27738     res = xmlSchemaValidatorPopElem(vctxt);
                27739     if (res != 0) {
                27740     if (res < 0) {
                27741         VERROR_INT("xmlSchemaSAXHandleEndElementNs",
                27742         "calling xmlSchemaValidatorPopElem()");
                27743         goto internal_error;
                27744     }
                27745     goto exit;
                27746     }
                27747 exit:
                27748     return;
                27749 internal_error:
                27750     vctxt->err = -1;
                27751     xmlStopParser(vctxt->parserCtxt);
                27752     return;
                27753 }
                27754 
                27755 /************************************************************************
                27756  *                                  *
                27757  *          Validation interfaces               *
                27758  *                                  *
                27759  ************************************************************************/
                27760 
                27761 /**
                27762  * xmlSchemaNewValidCtxt:
                27763  * @schema:  a precompiled XML Schemas
                27764  *
                27765  * Create an XML Schemas validation context based on the given schema.
                27766  *
                27767  * Returns the validation context or NULL in case of error
                27768  */
                27769 xmlSchemaValidCtxtPtr
                27770 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
                27771 {
                27772     xmlSchemaValidCtxtPtr ret;
                27773 
                27774     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
                27775     if (ret == NULL) {
                27776         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
                27777         return (NULL);
                27778     }
                27779     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
                27780     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
                27781     ret->dict = xmlDictCreate();
                27782     ret->nodeQNames = xmlSchemaItemListCreate();
                27783     ret->schema = schema;
                27784     return (ret);
                27785 }
                27786 
                27787 /**
                27788  * xmlSchemaValidateSetFilename:
                27789  * @vctxt: the schema validation context
                27790  * @filename: the file name
                27791  *
                27792  * Workaround to provide file error reporting information when this is
                27793  * not provided by current APIs
                27794  */
                27795 void
                27796 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
                27797     if (vctxt == NULL)
                27798         return;
                27799     if (vctxt->filename != NULL)
                27800         xmlFree(vctxt->filename);
                27801     if (filename != NULL)
                27802         vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
                27803     else
                27804         vctxt->filename = NULL;
                27805 }
                27806 
                27807 /**
                27808  * xmlSchemaClearValidCtxt:
                27809  * @vctxt: the schema validation context
                27810  *
                27811  * Free the resources associated to the schema validation context;
                27812  * leaves some fields alive intended for reuse of the context.
                27813  */
                27814 static void
                27815 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
                27816 {
                27817     if (vctxt == NULL)
                27818         return;
                27819 
                27820     /*
                27821     * TODO: Should we clear the flags?
                27822     *   Might be problematic if one reuses the context
                27823     *   and assumes that the options remain the same.
                27824     */
                27825     vctxt->flags = 0;
                27826     vctxt->validationRoot = NULL;
                27827     vctxt->doc = NULL;
                27828 #ifdef LIBXML_READER_ENABLED
                27829     vctxt->reader = NULL;
                27830 #endif
                27831     vctxt->hasKeyrefs = 0;
                27832 
                27833     if (vctxt->value != NULL) {
                27834         xmlSchemaFreeValue(vctxt->value);
                27835     vctxt->value = NULL;
                27836     }
                27837     /*
                27838     * Augmented IDC information.
                27839     */
                27840     if (vctxt->aidcs != NULL) {
                27841     xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
                27842     do {
                27843         next = cur->next;
                27844         xmlFree(cur);
                27845         cur = next;
                27846     } while (cur != NULL);
                27847     vctxt->aidcs = NULL;
                27848     }
                27849 
                27850     if (vctxt->idcNodes != NULL) {
                27851     int i;
                27852     xmlSchemaPSVIIDCNodePtr item;
                27853 
                27854     for (i = 0; i < vctxt->nbIdcNodes; i++) {
                27855         item = vctxt->idcNodes[i];
                27856         xmlFree(item->keys);
                27857         xmlFree(item);
                27858     }
                27859     xmlFree(vctxt->idcNodes);
                27860     vctxt->idcNodes = NULL;
                27861     vctxt->nbIdcNodes = 0;
                27862     vctxt->sizeIdcNodes = 0;
                27863     }
                27864 
                27865     if (vctxt->idcKeys != NULL) {
                27866     int i;
                27867     for (i = 0; i < vctxt->nbIdcKeys; i++)
                27868         xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
                27869     xmlFree(vctxt->idcKeys);
                27870     vctxt->idcKeys = NULL;
                27871     vctxt->nbIdcKeys = 0;
                27872     vctxt->sizeIdcKeys = 0;
                27873     }
                27874 
                27875     /*
                27876     * Note that we won't delete the XPath state pool here.
                27877     */
                27878     if (vctxt->xpathStates != NULL) {
                27879     xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
                27880     vctxt->xpathStates = NULL;
                27881     }
                27882     /*
                27883     * Attribute info.
                27884     */
                27885     if (vctxt->nbAttrInfos != 0) {
                27886     xmlSchemaClearAttrInfos(vctxt);
                27887     }
                27888     /*
                27889     * Element info.
                27890     */
                27891     if (vctxt->elemInfos != NULL) {
                27892     int i;
                27893     xmlSchemaNodeInfoPtr ei;
                27894 
                27895     for (i = 0; i < vctxt->sizeElemInfos; i++) {
                27896         ei = vctxt->elemInfos[i];
                27897         if (ei == NULL)
                27898         break;
                27899         xmlSchemaClearElemInfo(vctxt, ei);
                27900     }
                27901     }
                27902     xmlSchemaItemListClear(vctxt->nodeQNames);
                27903     /* Recreate the dict. */
                27904     xmlDictFree(vctxt->dict);
                27905     /*
                27906     * TODO: Is is save to recreate it? Do we have a scenario
                27907     * where the user provides the dict?
                27908     */
                27909     vctxt->dict = xmlDictCreate();
                27910 
                27911     if (vctxt->filename != NULL) {
                27912         xmlFree(vctxt->filename);
                27913     vctxt->filename = NULL;
                27914     }
015491ab3 Alex*27915 
                27916     /*
                27917      * Note that some cleanup functions can move items to the cache,
                27918      * so the cache shouldn't be freed too early.
                27919      */
                27920     if (vctxt->idcMatcherCache != NULL) {
                27921     xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
                27922 
                27923     while (matcher) {
                27924         tmp = matcher;
                27925         matcher = matcher->nextCached;
                27926         xmlSchemaIDCFreeMatcherList(tmp);
                27927     }
                27928     vctxt->idcMatcherCache = NULL;
                27929     }
9d9d4fcc3 Alex*27930 }
                27931 
                27932 /**
                27933  * xmlSchemaFreeValidCtxt:
                27934  * @ctxt:  the schema validation context
                27935  *
                27936  * Free the resources associated to the schema validation context
                27937  */
                27938 void
                27939 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
                27940 {
                27941     if (ctxt == NULL)
                27942         return;
                27943     if (ctxt->value != NULL)
                27944         xmlSchemaFreeValue(ctxt->value);
                27945     if (ctxt->pctxt != NULL)
                27946     xmlSchemaFreeParserCtxt(ctxt->pctxt);
                27947     if (ctxt->idcNodes != NULL) {
                27948     int i;
                27949     xmlSchemaPSVIIDCNodePtr item;
                27950 
                27951     for (i = 0; i < ctxt->nbIdcNodes; i++) {
                27952         item = ctxt->idcNodes[i];
                27953         xmlFree(item->keys);
                27954         xmlFree(item);
                27955     }
                27956     xmlFree(ctxt->idcNodes);
                27957     }
                27958     if (ctxt->idcKeys != NULL) {
                27959     int i;
                27960     for (i = 0; i < ctxt->nbIdcKeys; i++)
                27961         xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
                27962     xmlFree(ctxt->idcKeys);
                27963     }
                27964 
                27965     if (ctxt->xpathStates != NULL) {
                27966     xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
                27967     ctxt->xpathStates = NULL;
                27968     }
                27969     if (ctxt->xpathStatePool != NULL) {
                27970     xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
                27971     ctxt->xpathStatePool = NULL;
                27972     }
                27973 
                27974     /*
                27975     * Augmented IDC information.
                27976     */
                27977     if (ctxt->aidcs != NULL) {
                27978     xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
                27979     do {
                27980         next = cur->next;
                27981         xmlFree(cur);
                27982         cur = next;
                27983     } while (cur != NULL);
                27984     }
                27985     if (ctxt->attrInfos != NULL) {
                27986     int i;
                27987     xmlSchemaAttrInfoPtr attr;
                27988 
                27989     /* Just a paranoid call to the cleanup. */
                27990     if (ctxt->nbAttrInfos != 0)
                27991         xmlSchemaClearAttrInfos(ctxt);
                27992     for (i = 0; i < ctxt->sizeAttrInfos; i++) {
                27993         attr = ctxt->attrInfos[i];
                27994         xmlFree(attr);
                27995     }
                27996     xmlFree(ctxt->attrInfos);
                27997     }
                27998     if (ctxt->elemInfos != NULL) {
                27999     int i;
                28000     xmlSchemaNodeInfoPtr ei;
                28001 
                28002     for (i = 0; i < ctxt->sizeElemInfos; i++) {
                28003         ei = ctxt->elemInfos[i];
                28004         if (ei == NULL)
                28005         break;
                28006         xmlSchemaClearElemInfo(ctxt, ei);
                28007         xmlFree(ei);
                28008     }
                28009     xmlFree(ctxt->elemInfos);
                28010     }
                28011     if (ctxt->nodeQNames != NULL)
                28012     xmlSchemaItemListFree(ctxt->nodeQNames);
                28013     if (ctxt->dict != NULL)
                28014     xmlDictFree(ctxt->dict);
                28015     if (ctxt->filename != NULL)
                28016     xmlFree(ctxt->filename);
                28017     xmlFree(ctxt);
                28018 }
                28019 
                28020 /**
                28021  * xmlSchemaIsValid:
                28022  * @ctxt: the schema validation context
                28023  *
                28024  * Check if any error was detected during validation.
                28025  *
                28026  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
                28027  *         of internal error.
                28028  */
                28029 int
                28030 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
                28031 {
                28032     if (ctxt == NULL)
                28033         return(-1);
                28034     return(ctxt->err == 0);
                28035 }
                28036 
                28037 /**
                28038  * xmlSchemaSetValidErrors:
                28039  * @ctxt:  a schema validation context
                28040  * @err:  the error function
                28041  * @warn: the warning function
                28042  * @ctx: the functions context
                28043  *
                28044  * Set the error and warning callback information
                28045  */
                28046 void
                28047 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
                28048                         xmlSchemaValidityErrorFunc err,
                28049                         xmlSchemaValidityWarningFunc warn, void *ctx)
                28050 {
                28051     if (ctxt == NULL)
                28052         return;
                28053     ctxt->error = err;
                28054     ctxt->warning = warn;
                28055     ctxt->errCtxt = ctx;
                28056     if (ctxt->pctxt != NULL)
                28057     xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
                28058 }
                28059 
                28060 /**
                28061  * xmlSchemaSetValidStructuredErrors:
                28062  * @ctxt:  a schema validation context
                28063  * @serror:  the structured error function
                28064  * @ctx: the functions context
                28065  *
                28066  * Set the structured error callback
                28067  */
                28068 void
                28069 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
                28070                   xmlStructuredErrorFunc serror, void *ctx)
                28071 {
                28072     if (ctxt == NULL)
                28073         return;
                28074     ctxt->serror = serror;
                28075     ctxt->error = NULL;
                28076     ctxt->warning = NULL;
                28077     ctxt->errCtxt = ctx;
                28078     if (ctxt->pctxt != NULL)
                28079     xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
                28080 }
                28081 
                28082 /**
                28083  * xmlSchemaGetValidErrors:
                28084  * @ctxt: a XML-Schema validation context
                28085  * @err: the error function result
                28086  * @warn: the warning function result
                28087  * @ctx: the functions context result
                28088  *
                28089  * Get the error and warning callback information
                28090  *
                28091  * Returns -1 in case of error and 0 otherwise
                28092  */
                28093 int
                28094 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
                28095             xmlSchemaValidityErrorFunc * err,
                28096             xmlSchemaValidityWarningFunc * warn, void **ctx)
                28097 {
                28098     if (ctxt == NULL)
                28099         return (-1);
                28100     if (err != NULL)
                28101         *err = ctxt->error;
                28102     if (warn != NULL)
                28103         *warn = ctxt->warning;
                28104     if (ctx != NULL)
                28105         *ctx = ctxt->errCtxt;
                28106     return (0);
                28107 }
                28108 
                28109 
                28110 /**
                28111  * xmlSchemaSetValidOptions:
                28112  * @ctxt:   a schema validation context
                28113  * @options: a combination of xmlSchemaValidOption
                28114  *
                28115  * Sets the options to be used during the validation.
                28116  *
                28117  * Returns 0 in case of success, -1 in case of an
                28118  * API error.
                28119  */
                28120 int
                28121 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
                28122              int options)
                28123 
                28124 {
                28125     int i;
                28126 
                28127     if (ctxt == NULL)
                28128     return (-1);
                28129     /*
                28130     * WARNING: Change the start value if adding to the
                28131     * xmlSchemaValidOption.
                28132     * TODO: Is there an other, more easy to maintain,
                28133     * way?
                28134     */
                28135     for (i = 1; i < (int) sizeof(int) * 8; i++) {
                28136         if (options & 1<<i)
                28137         return (-1);
                28138     }
                28139     ctxt->options = options;
                28140     return (0);
                28141 }
                28142 
                28143 /**
                28144  * xmlSchemaValidCtxtGetOptions:
                28145  * @ctxt: a schema validation context
                28146  *
                28147  * Get the validation context options.
                28148  *
                28149  * Returns the option combination or -1 on error.
                28150  */
                28151 int
                28152 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
                28153 
                28154 {
                28155     if (ctxt == NULL)
                28156     return (-1);
                28157     else
                28158     return (ctxt->options);
                28159 }
                28160 
                28161 static int
                28162 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
                28163 {
                28164     xmlAttrPtr attr;
                28165     int ret = 0;
                28166     xmlSchemaNodeInfoPtr ielem = NULL;
                28167     xmlNodePtr node, valRoot;
                28168     const xmlChar *nsName;
                28169 
                28170     /* DOC VAL TODO: Move this to the start function. */
                28171     if (vctxt->validationRoot != NULL)
                28172         valRoot = vctxt->validationRoot;
                28173     else
                28174     valRoot = xmlDocGetRootElement(vctxt->doc);
                28175     if (valRoot == NULL) {
                28176     /* VAL TODO: Error code? */
                28177     VERROR(1, NULL, "The document has no document element");
                28178     return (1);
                28179     }
                28180     vctxt->depth = -1;
                28181     vctxt->validationRoot = valRoot;
                28182     node = valRoot;
                28183     while (node != NULL) {
                28184     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
                28185         goto next_sibling;
                28186     if (node->type == XML_ELEMENT_NODE) {
                28187 
                28188         /*
                28189         * Init the node-info.
                28190         */
                28191         vctxt->depth++;
                28192         if (xmlSchemaValidatorPushElem(vctxt) == -1)
                28193         goto internal_error;
                28194         ielem = vctxt->inode;
                28195         ielem->node = node;
                28196         ielem->nodeLine = node->line;
                28197         ielem->localName = node->name;
                28198         if (node->ns != NULL)
                28199         ielem->nsName = node->ns->href;
                28200         ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
                28201         /*
                28202         * Register attributes.
                28203         * DOC VAL TODO: We do not register namespace declaration
                28204         * attributes yet.
                28205         */
                28206         vctxt->nbAttrInfos = 0;
                28207         if (node->properties != NULL) {
                28208         attr = node->properties;
                28209         do {
                28210             if (attr->ns != NULL)
                28211             nsName = attr->ns->href;
                28212             else
                28213             nsName = NULL;
                28214             ret = xmlSchemaValidatorPushAttribute(vctxt,
                28215             (xmlNodePtr) attr,
                28216             /*
                28217             * Note that we give it the line number of the
                28218             * parent element.
                28219             */
                28220             ielem->nodeLine,
                28221             attr->name, nsName, 0,
                28222             xmlNodeListGetString(attr->doc, attr->children, 1), 1);
                28223             if (ret == -1) {
                28224             VERROR_INT("xmlSchemaDocWalk",
                28225                 "calling xmlSchemaValidatorPushAttribute()");
                28226             goto internal_error;
                28227             }
                28228             attr = attr->next;
                28229         } while (attr);
                28230         }
                28231         /*
                28232         * Validate the element.
                28233         */
                28234         ret = xmlSchemaValidateElem(vctxt);
                28235         if (ret != 0) {
                28236         if (ret == -1) {
                28237             VERROR_INT("xmlSchemaDocWalk",
                28238             "calling xmlSchemaValidateElem()");
                28239             goto internal_error;
                28240         }
                28241         /*
                28242         * Don't stop validation; just skip the content
                28243         * of this element.
                28244         */
                28245         goto leave_node;
                28246         }
                28247         if ((vctxt->skipDepth != -1) &&
                28248         (vctxt->depth >= vctxt->skipDepth))
                28249         goto leave_node;
                28250     } else if ((node->type == XML_TEXT_NODE) ||
                28251         (node->type == XML_CDATA_SECTION_NODE)) {
                28252         /*
                28253         * Process character content.
                28254         */
                28255         if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
                28256         ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
                28257         ret = xmlSchemaVPushText(vctxt, node->type, node->content,
                28258         -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
                28259         if (ret < 0) {
                28260         VERROR_INT("xmlSchemaVDocWalk",
                28261             "calling xmlSchemaVPushText()");
                28262         goto internal_error;
                28263         }
                28264         /*
                28265         * DOC VAL TODO: Should we skip further validation of the
                28266         * element content here?
                28267         */
                28268     } else if ((node->type == XML_ENTITY_NODE) ||
                28269         (node->type == XML_ENTITY_REF_NODE)) {
                28270         /*
                28271         * DOC VAL TODO: What to do with entities?
                28272         */
                28273         VERROR_INT("xmlSchemaVDocWalk",
                28274         "there is at least one entity reference in the node-tree "
                28275         "currently being validated. Processing of entities with "
                28276         "this XML Schema processor is not supported (yet). Please "
                28277         "substitute entities before validation.");
                28278         goto internal_error;
                28279     } else {
                28280         goto leave_node;
                28281         /*
                28282         * DOC VAL TODO: XInclude nodes, etc.
                28283         */
                28284     }
                28285     /*
                28286     * Walk the doc.
                28287     */
                28288     if (node->children != NULL) {
                28289         node = node->children;
                28290         continue;
                28291     }
                28292 leave_node:
                28293     if (node->type == XML_ELEMENT_NODE) {
                28294         /*
                28295         * Leaving the scope of an element.
                28296         */
                28297         if (node != vctxt->inode->node) {
                28298         VERROR_INT("xmlSchemaVDocWalk",
                28299             "element position mismatch");
                28300         goto internal_error;
                28301         }
                28302         ret = xmlSchemaValidatorPopElem(vctxt);
                28303         if (ret != 0) {
                28304         if (ret < 0) {
                28305             VERROR_INT("xmlSchemaVDocWalk",
                28306             "calling xmlSchemaValidatorPopElem()");
                28307             goto internal_error;
                28308         }
                28309         }
                28310         if (node == valRoot)
                28311         goto exit;
                28312     }
                28313 next_sibling:
                28314     if (node->next != NULL)
                28315         node = node->next;
                28316     else {
                28317         node = node->parent;
                28318         goto leave_node;
                28319     }
                28320     }
                28321 
                28322 exit:
                28323     return (ret);
                28324 internal_error:
                28325     return (-1);
                28326 }
                28327 
                28328 static int
                28329 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
                28330     /*
                28331     * Some initialization.
                28332     */
                28333     vctxt->err = 0;
                28334     vctxt->nberrors = 0;
                28335     vctxt->depth = -1;
                28336     vctxt->skipDepth = -1;
                28337     vctxt->hasKeyrefs = 0;
                28338 #ifdef ENABLE_IDC_NODE_TABLES_TEST
                28339     vctxt->createIDCNodeTables = 1;
                28340 #else
                28341     vctxt->createIDCNodeTables = 0;
                28342 #endif
                28343     /*
                28344     * Create a schema + parser if necessary.
                28345     */
                28346     if (vctxt->schema == NULL) {
                28347     xmlSchemaParserCtxtPtr pctxt;
                28348 
                28349     vctxt->xsiAssemble = 1;
                28350     /*
                28351     * If not schema was given then we will create a schema
                28352     * dynamically using XSI schema locations.
                28353     *
                28354     * Create the schema parser context.
                28355     */
                28356     if ((vctxt->pctxt == NULL) &&
                28357        (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
                28358        return (-1);
                28359     pctxt = vctxt->pctxt;
                28360     pctxt->xsiAssemble = 1;
                28361     /*
                28362     * Create the schema.
                28363     */
                28364     vctxt->schema = xmlSchemaNewSchema(pctxt);
                28365     if (vctxt->schema == NULL)
                28366         return (-1);
                28367     /*
                28368     * Create the schema construction context.
                28369     */
                28370     pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
                28371     if (pctxt->constructor == NULL)
                28372         return(-1);
                28373     pctxt->constructor->mainSchema = vctxt->schema;
                28374     /*
                28375     * Take ownership of the constructor to be able to free it.
                28376     */
                28377     pctxt->ownsConstructor = 1;
                28378     }
                28379     /*
                28380     * Augment the IDC definitions for the main schema and all imported ones
                28381     * NOTE: main schema if the first in the imported list
                28382     */
                28383     xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
                28384                 vctxt);
                28385 
                28386     return(0);
                28387 }
                28388 
                28389 static void
                28390 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
                28391     if (vctxt->xsiAssemble) {
                28392     if (vctxt->schema != NULL) {
                28393         xmlSchemaFree(vctxt->schema);
                28394         vctxt->schema = NULL;
                28395     }
                28396     }
                28397     xmlSchemaClearValidCtxt(vctxt);
                28398 }
                28399 
                28400 static int
                28401 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
                28402 {
                28403     int ret = 0;
                28404 
                28405     if (xmlSchemaPreRun(vctxt) < 0)
                28406         return(-1);
                28407 
                28408     if (vctxt->doc != NULL) {
                28409     /*
                28410      * Tree validation.
                28411      */
                28412     ret = xmlSchemaVDocWalk(vctxt);
                28413 #ifdef LIBXML_READER_ENABLED
                28414     } else if (vctxt->reader != NULL) {
                28415     /*
                28416      * XML Reader validation.
                28417      */
                28418 #ifdef XML_SCHEMA_READER_ENABLED
                28419     ret = xmlSchemaVReaderWalk(vctxt);
                28420 #endif
                28421 #endif
                28422     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
                28423     /*
                28424      * SAX validation.
                28425      */
                28426     ret = xmlParseDocument(vctxt->parserCtxt);
                28427     } else {
                28428     VERROR_INT("xmlSchemaVStart",
                28429         "no instance to validate");
                28430     ret = -1;
                28431     }
                28432 
                28433     xmlSchemaPostRun(vctxt);
                28434     if (ret == 0)
                28435     ret = vctxt->err;
                28436     return (ret);
                28437 }
                28438 
                28439 /**
                28440  * xmlSchemaValidateOneElement:
                28441  * @ctxt:  a schema validation context
                28442  * @elem:  an element node
                28443  *
                28444  * Validate a branch of a tree, starting with the given @elem.
                28445  *
                28446  * Returns 0 if the element and its subtree is valid, a positive error
                28447  * code number otherwise and -1 in case of an internal or API error.
                28448  */
                28449 int
                28450 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
                28451 {
                28452     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
                28453     return (-1);
                28454 
                28455     if (ctxt->schema == NULL)
                28456     return (-1);
                28457 
                28458     ctxt->doc = elem->doc;
                28459     ctxt->node = elem;
                28460     ctxt->validationRoot = elem;
                28461     return(xmlSchemaVStart(ctxt));
                28462 }
                28463 
                28464 /**
                28465  * xmlSchemaValidateDoc:
                28466  * @ctxt:  a schema validation context
                28467  * @doc:  a parsed document tree
                28468  *
                28469  * Validate a document tree in memory.
                28470  *
                28471  * Returns 0 if the document is schemas valid, a positive error code
                28472  *     number otherwise and -1 in case of internal or API error.
                28473  */
                28474 int
                28475 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
                28476 {
                28477     if ((ctxt == NULL) || (doc == NULL))
                28478         return (-1);
                28479 
                28480     ctxt->doc = doc;
                28481     ctxt->node = xmlDocGetRootElement(doc);
                28482     if (ctxt->node == NULL) {
                28483         xmlSchemaCustomErr(ACTXT_CAST ctxt,
                28484         XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
                28485         (xmlNodePtr) doc, NULL,
                28486         "The document has no document element", NULL, NULL);
                28487         return (ctxt->err);
                28488     }
                28489     ctxt->validationRoot = ctxt->node;
                28490     return (xmlSchemaVStart(ctxt));
                28491 }
                28492 
                28493 
                28494 /************************************************************************
                28495  *                                  *
                28496  *      Function and data for SAX streaming API         *
                28497  *                                  *
                28498  ************************************************************************/
                28499 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
                28500 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
                28501 
                28502 struct _xmlSchemaSplitSAXData {
                28503     xmlSAXHandlerPtr      user_sax;
                28504     void                 *user_data;
                28505     xmlSchemaValidCtxtPtr ctxt;
                28506     xmlSAXHandlerPtr      schemas_sax;
                28507 };
                28508 
                28509 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
                28510 
                28511 struct _xmlSchemaSAXPlug {
                28512     unsigned int magic;
                28513 
                28514     /* the original callbacks information */
                28515     xmlSAXHandlerPtr     *user_sax_ptr;
                28516     xmlSAXHandlerPtr      user_sax;
                28517     void                **user_data_ptr;
                28518     void                 *user_data;
                28519 
                28520     /* the block plugged back and validation information */
                28521     xmlSAXHandler         schemas_sax;
                28522     xmlSchemaValidCtxtPtr ctxt;
                28523 };
                28524 
                28525 /* All those functions just bounces to the user provided SAX handlers */
                28526 static void
                28527 internalSubsetSplit(void *ctx, const xmlChar *name,
                28528            const xmlChar *ExternalID, const xmlChar *SystemID)
                28529 {
                28530     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28531     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28532         (ctxt->user_sax->internalSubset != NULL))
                28533     ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
                28534                                    SystemID);
                28535 }
                28536 
                28537 static int
                28538 isStandaloneSplit(void *ctx)
                28539 {
                28540     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28541     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28542         (ctxt->user_sax->isStandalone != NULL))
                28543     return(ctxt->user_sax->isStandalone(ctxt->user_data));
                28544     return(0);
                28545 }
                28546 
                28547 static int
                28548 hasInternalSubsetSplit(void *ctx)
                28549 {
                28550     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28551     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28552         (ctxt->user_sax->hasInternalSubset != NULL))
                28553     return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
                28554     return(0);
                28555 }
                28556 
                28557 static int
                28558 hasExternalSubsetSplit(void *ctx)
                28559 {
                28560     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28561     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28562         (ctxt->user_sax->hasExternalSubset != NULL))
                28563     return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
                28564     return(0);
                28565 }
                28566 
                28567 static void
                28568 externalSubsetSplit(void *ctx, const xmlChar *name,
                28569            const xmlChar *ExternalID, const xmlChar *SystemID)
                28570 {
                28571     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28572     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28573         (ctxt->user_sax->externalSubset != NULL))
                28574     ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
                28575                                    SystemID);
                28576 }
                28577 
                28578 static xmlParserInputPtr
                28579 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
                28580 {
                28581     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28582     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28583         (ctxt->user_sax->resolveEntity != NULL))
                28584     return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
                28585                                          systemId));
                28586     return(NULL);
                28587 }
                28588 
                28589 static xmlEntityPtr
                28590 getEntitySplit(void *ctx, const xmlChar *name)
                28591 {
                28592     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28593     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28594         (ctxt->user_sax->getEntity != NULL))
                28595     return(ctxt->user_sax->getEntity(ctxt->user_data, name));
                28596     return(NULL);
                28597 }
                28598 
                28599 static xmlEntityPtr
                28600 getParameterEntitySplit(void *ctx, const xmlChar *name)
                28601 {
                28602     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28603     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28604         (ctxt->user_sax->getParameterEntity != NULL))
                28605     return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
                28606     return(NULL);
                28607 }
                28608 
                28609 
                28610 static void
                28611 entityDeclSplit(void *ctx, const xmlChar *name, int type,
                28612           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
                28613 {
                28614     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28615     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28616         (ctxt->user_sax->entityDecl != NULL))
                28617     ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
                28618                                systemId, content);
                28619 }
                28620 
                28621 static void
                28622 attributeDeclSplit(void *ctx, const xmlChar * elem,
                28623                    const xmlChar * name, int type, int def,
                28624                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
                28625 {
                28626     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28627     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28628         (ctxt->user_sax->attributeDecl != NULL)) {
                28629     ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
                28630                                   def, defaultValue, tree);
                28631     } else {
                28632     xmlFreeEnumeration(tree);
                28633     }
                28634 }
                28635 
                28636 static void
                28637 elementDeclSplit(void *ctx, const xmlChar *name, int type,
                28638         xmlElementContentPtr content)
                28639 {
                28640     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28641     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28642         (ctxt->user_sax->elementDecl != NULL))
                28643     ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
                28644 }
                28645 
                28646 static void
                28647 notationDeclSplit(void *ctx, const xmlChar *name,
                28648          const xmlChar *publicId, const xmlChar *systemId)
                28649 {
                28650     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28651     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28652         (ctxt->user_sax->notationDecl != NULL))
                28653     ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
                28654                                  systemId);
                28655 }
                28656 
                28657 static void
                28658 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
                28659            const xmlChar *publicId, const xmlChar *systemId,
                28660            const xmlChar *notationName)
                28661 {
                28662     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28663     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28664         (ctxt->user_sax->unparsedEntityDecl != NULL))
                28665     ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
                28666                                        systemId, notationName);
                28667 }
                28668 
                28669 static void
                28670 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
                28671 {
                28672     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28673     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28674         (ctxt->user_sax->setDocumentLocator != NULL))
                28675     ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
                28676 }
                28677 
                28678 static void
                28679 startDocumentSplit(void *ctx)
                28680 {
                28681     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28682     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28683         (ctxt->user_sax->startDocument != NULL))
                28684     ctxt->user_sax->startDocument(ctxt->user_data);
                28685 }
                28686 
                28687 static void
                28688 endDocumentSplit(void *ctx)
                28689 {
                28690     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28691     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28692         (ctxt->user_sax->endDocument != NULL))
                28693     ctxt->user_sax->endDocument(ctxt->user_data);
                28694 }
                28695 
                28696 static void
                28697 processingInstructionSplit(void *ctx, const xmlChar *target,
                28698                       const xmlChar *data)
                28699 {
                28700     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28701     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28702         (ctxt->user_sax->processingInstruction != NULL))
                28703     ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
                28704 }
                28705 
                28706 static void
                28707 commentSplit(void *ctx, const xmlChar *value)
                28708 {
                28709     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28710     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28711         (ctxt->user_sax->comment != NULL))
                28712     ctxt->user_sax->comment(ctxt->user_data, value);
                28713 }
                28714 
                28715 /*
                28716  * Varargs error callbacks to the user application, harder ...
                28717  */
                28718 
da6279058 Alex*28719 static void
9d9d4fcc3 Alex*28720 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
                28721     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28722     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28723         (ctxt->user_sax->warning != NULL)) {
                28724     TODO
                28725     }
                28726 }
da6279058 Alex*28727 static void
9d9d4fcc3 Alex*28728 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
                28729     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28730     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28731         (ctxt->user_sax->error != NULL)) {
                28732     TODO
                28733     }
                28734 }
da6279058 Alex*28735 static void
9d9d4fcc3 Alex*28736 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
                28737     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28738     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28739         (ctxt->user_sax->fatalError != NULL)) {
                28740     TODO
                28741     }
                28742 }
                28743 
                28744 /*
                28745  * Those are function where both the user handler and the schemas handler
                28746  * need to be called.
                28747  */
                28748 static void
                28749 charactersSplit(void *ctx, const xmlChar *ch, int len)
                28750 {
                28751     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28752     if (ctxt == NULL)
                28753         return;
                28754     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
                28755     ctxt->user_sax->characters(ctxt->user_data, ch, len);
                28756     if (ctxt->ctxt != NULL)
                28757     xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
                28758 }
                28759 
                28760 static void
                28761 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
                28762 {
                28763     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28764     if (ctxt == NULL)
                28765         return;
                28766     if ((ctxt->user_sax != NULL) &&
                28767         (ctxt->user_sax->ignorableWhitespace != NULL))
                28768     ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
                28769     if (ctxt->ctxt != NULL)
                28770     xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
                28771 }
                28772 
                28773 static void
                28774 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
                28775 {
                28776     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28777     if (ctxt == NULL)
                28778         return;
                28779     if ((ctxt->user_sax != NULL) &&
                28780         (ctxt->user_sax->cdataBlock != NULL))
                28781     ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
                28782     if (ctxt->ctxt != NULL)
                28783     xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
                28784 }
                28785 
                28786 static void
                28787 referenceSplit(void *ctx, const xmlChar *name)
                28788 {
                28789     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28790     if (ctxt == NULL)
                28791         return;
                28792     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
                28793         (ctxt->user_sax->reference != NULL))
                28794     ctxt->user_sax->reference(ctxt->user_data, name);
                28795     if (ctxt->ctxt != NULL)
                28796         xmlSchemaSAXHandleReference(ctxt->user_data, name);
                28797 }
                28798 
                28799 static void
                28800 startElementNsSplit(void *ctx, const xmlChar * localname,
                28801             const xmlChar * prefix, const xmlChar * URI,
                28802             int nb_namespaces, const xmlChar ** namespaces,
                28803             int nb_attributes, int nb_defaulted,
                28804             const xmlChar ** attributes) {
                28805     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28806     if (ctxt == NULL)
                28807         return;
                28808     if ((ctxt->user_sax != NULL) &&
                28809         (ctxt->user_sax->startElementNs != NULL))
                28810     ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
                28811                                    URI, nb_namespaces, namespaces,
                28812                        nb_attributes, nb_defaulted,
                28813                        attributes);
                28814     if (ctxt->ctxt != NULL)
                28815     xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
                28816                                      URI, nb_namespaces, namespaces,
                28817                      nb_attributes, nb_defaulted,
                28818                      attributes);
                28819 }
                28820 
                28821 static void
                28822 endElementNsSplit(void *ctx, const xmlChar * localname,
                28823             const xmlChar * prefix, const xmlChar * URI) {
                28824     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
                28825     if (ctxt == NULL)
                28826         return;
                28827     if ((ctxt->user_sax != NULL) &&
                28828         (ctxt->user_sax->endElementNs != NULL))
                28829     ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
                28830     if (ctxt->ctxt != NULL)
                28831     xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
                28832 }
                28833 
                28834 /**
                28835  * xmlSchemaSAXPlug:
                28836  * @ctxt:  a schema validation context
                28837  * @sax:  a pointer to the original xmlSAXHandlerPtr
                28838  * @user_data:  a pointer to the original SAX user data pointer
                28839  *
                28840  * Plug a SAX based validation layer in a SAX parsing event flow.
                28841  * The original @saxptr and @dataptr data are replaced by new pointers
                28842  * but the calls to the original will be maintained.
                28843  *
                28844  * Returns a pointer to a data structure needed to unplug the validation layer
                28845  *         or NULL in case of errors.
                28846  */
                28847 xmlSchemaSAXPlugPtr
                28848 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
                28849          xmlSAXHandlerPtr *sax, void **user_data)
                28850 {
                28851     xmlSchemaSAXPlugPtr ret;
                28852     xmlSAXHandlerPtr old_sax;
                28853 
                28854     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
                28855         return(NULL);
                28856 
                28857     /*
                28858      * We only allow to plug into SAX2 event streams
                28859      */
                28860     old_sax = *sax;
                28861     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
                28862         return(NULL);
                28863     if ((old_sax != NULL) &&
                28864         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
                28865         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
                28866         return(NULL);
                28867 
                28868     /*
                28869      * everything seems right allocate the local data needed for that layer
                28870      */
                28871     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
                28872     if (ret == NULL) {
                28873         return(NULL);
                28874     }
                28875     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
                28876     ret->magic = XML_SAX_PLUG_MAGIC;
                28877     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
                28878     ret->ctxt = ctxt;
                28879     ret->user_sax_ptr = sax;
                28880     ret->user_sax = old_sax;
                28881     if (old_sax == NULL) {
                28882         /*
                28883      * go direct, no need for the split block and functions.
                28884      */
                28885     ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
                28886     ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
                28887     /*
                28888      * Note that we use the same text-function for both, to prevent
                28889      * the parser from testing for ignorable whitespace.
                28890      */
                28891     ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
                28892     ret->schemas_sax.characters = xmlSchemaSAXHandleText;
                28893 
                28894     ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
                28895     ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
                28896 
                28897     ret->user_data = ctxt;
                28898     *user_data = ctxt;
                28899     } else {
                28900        /*
                28901         * for each callback unused by Schemas initialize it to the Split
                28902     * routine only if non NULL in the user block, this can speed up
                28903     * things at the SAX level.
                28904     */
                28905         if (old_sax->internalSubset != NULL)
                28906             ret->schemas_sax.internalSubset = internalSubsetSplit;
                28907         if (old_sax->isStandalone != NULL)
                28908             ret->schemas_sax.isStandalone = isStandaloneSplit;
                28909         if (old_sax->hasInternalSubset != NULL)
                28910             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
                28911         if (old_sax->hasExternalSubset != NULL)
                28912             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
                28913         if (old_sax->resolveEntity != NULL)
                28914             ret->schemas_sax.resolveEntity = resolveEntitySplit;
                28915         if (old_sax->getEntity != NULL)
                28916             ret->schemas_sax.getEntity = getEntitySplit;
                28917         if (old_sax->entityDecl != NULL)
                28918             ret->schemas_sax.entityDecl = entityDeclSplit;
                28919         if (old_sax->notationDecl != NULL)
                28920             ret->schemas_sax.notationDecl = notationDeclSplit;
                28921         if (old_sax->attributeDecl != NULL)
                28922             ret->schemas_sax.attributeDecl = attributeDeclSplit;
                28923         if (old_sax->elementDecl != NULL)
                28924             ret->schemas_sax.elementDecl = elementDeclSplit;
                28925         if (old_sax->unparsedEntityDecl != NULL)
                28926             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
                28927         if (old_sax->setDocumentLocator != NULL)
                28928             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
                28929         if (old_sax->startDocument != NULL)
                28930             ret->schemas_sax.startDocument = startDocumentSplit;
                28931         if (old_sax->endDocument != NULL)
                28932             ret->schemas_sax.endDocument = endDocumentSplit;
                28933         if (old_sax->processingInstruction != NULL)
                28934             ret->schemas_sax.processingInstruction = processingInstructionSplit;
                28935         if (old_sax->comment != NULL)
                28936             ret->schemas_sax.comment = commentSplit;
                28937         if (old_sax->warning != NULL)
                28938             ret->schemas_sax.warning = warningSplit;
                28939         if (old_sax->error != NULL)
                28940             ret->schemas_sax.error = errorSplit;
                28941         if (old_sax->fatalError != NULL)
                28942             ret->schemas_sax.fatalError = fatalErrorSplit;
                28943         if (old_sax->getParameterEntity != NULL)
                28944             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
                28945         if (old_sax->externalSubset != NULL)
                28946             ret->schemas_sax.externalSubset = externalSubsetSplit;
                28947 
                28948     /*
                28949      * the 6 schemas callback have to go to the splitter functions
                28950      * Note that we use the same text-function for ignorableWhitespace
                28951      * if possible, to prevent the parser from testing for ignorable
                28952      * whitespace.
                28953      */
                28954         ret->schemas_sax.characters = charactersSplit;
                28955     if ((old_sax->ignorableWhitespace != NULL) &&
                28956         (old_sax->ignorableWhitespace != old_sax->characters))
                28957         ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
                28958     else
                28959         ret->schemas_sax.ignorableWhitespace = charactersSplit;
                28960         ret->schemas_sax.cdataBlock = cdataBlockSplit;
                28961         ret->schemas_sax.reference = referenceSplit;
                28962         ret->schemas_sax.startElementNs = startElementNsSplit;
                28963         ret->schemas_sax.endElementNs = endElementNsSplit;
                28964 
                28965     ret->user_data_ptr = user_data;
                28966     ret->user_data = *user_data;
                28967     *user_data = ret;
                28968     }
                28969 
                28970     /*
                28971      * plug the pointers back.
                28972      */
                28973     *sax = &(ret->schemas_sax);
                28974     ctxt->sax = *sax;
                28975     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
                28976     xmlSchemaPreRun(ctxt);
                28977     return(ret);
                28978 }
                28979 
                28980 /**
                28981  * xmlSchemaSAXUnplug:
                28982  * @plug:  a data structure returned by xmlSchemaSAXPlug
                28983  *
                28984  * Unplug a SAX based validation layer in a SAX parsing event flow.
                28985  * The original pointers used in the call are restored.
                28986  *
                28987  * Returns 0 in case of success and -1 in case of failure.
                28988  */
                28989 int
                28990 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
                28991 {
                28992     xmlSAXHandlerPtr *sax;
                28993     void **user_data;
                28994 
                28995     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
                28996         return(-1);
                28997     plug->magic = 0;
                28998 
                28999     xmlSchemaPostRun(plug->ctxt);
                29000     /* restore the data */
                29001     sax = plug->user_sax_ptr;
                29002     *sax = plug->user_sax;
                29003     if (plug->user_sax != NULL) {
                29004     user_data = plug->user_data_ptr;
                29005     *user_data = plug->user_data;
                29006     }
                29007 
                29008     /* free and return */
                29009     xmlFree(plug);
                29010     return(0);
                29011 }
                29012 
                29013 /**
                29014  * xmlSchemaValidateSetLocator:
                29015  * @vctxt: a schema validation context
                29016  * @f: the locator function pointer
                29017  * @ctxt: the locator context
                29018  *
                29019  * Allows to set a locator function to the validation context,
                29020  * which will be used to provide file and line information since
                29021  * those are not provided as part of the SAX validation flow
                29022  * Setting @f to NULL disable the locator.
                29023  */
                29024 
                29025 void
                29026 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
                29027                             xmlSchemaValidityLocatorFunc f,
                29028                 void *ctxt)
                29029 {
                29030     if (vctxt == NULL) return;
                29031     vctxt->locFunc = f;
                29032     vctxt->locCtxt = ctxt;
                29033 }
                29034 
                29035 /**
                29036  * xmlSchemaValidateStreamLocator:
                29037  * @ctx: the xmlTextReaderPtr used
                29038  * @file: returned file information
                29039  * @line: returned line information
                29040  *
                29041  * Internal locator function for the readers
                29042  *
                29043  * Returns 0 in case the Schema validation could be (de)activated and
                29044  *         -1 in case of error.
                29045  */
                29046 static int
                29047 xmlSchemaValidateStreamLocator(void *ctx, const char **file,
                29048                                unsigned long *line) {
                29049     xmlParserCtxtPtr ctxt;
                29050 
                29051     if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
                29052         return(-1);
                29053 
                29054     if (file != NULL)
                29055         *file = NULL;
                29056     if (line != NULL)
                29057         *line = 0;
                29058 
                29059     ctxt = (xmlParserCtxtPtr) ctx;
                29060     if (ctxt->input != NULL) {
                29061        if (file != NULL)
                29062            *file = ctxt->input->filename;
                29063        if (line != NULL)
                29064            *line = ctxt->input->line;
                29065        return(0);
                29066     }
                29067     return(-1);
                29068 }
                29069 
                29070 /**
                29071  * xmlSchemaValidateStream:
                29072  * @ctxt:  a schema validation context
                29073  * @input:  the input to use for reading the data
                29074  * @enc:  an optional encoding information
                29075  * @sax:  a SAX handler for the resulting events
                29076  * @user_data:  the context to provide to the SAX handler.
                29077  *
                29078  * Validate an input based on a flow of SAX event from the parser
                29079  * and forward the events to the @sax handler with the provided @user_data
                29080  * the user provided @sax handler must be a SAX2 one.
                29081  *
                29082  * Returns 0 if the document is schemas valid, a positive error code
                29083  *     number otherwise and -1 in case of internal or API error.
                29084  */
                29085 int
                29086 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
                29087                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
                29088                         xmlSAXHandlerPtr sax, void *user_data)
                29089 {
                29090     xmlSchemaSAXPlugPtr plug = NULL;
                29091     xmlParserCtxtPtr pctxt = NULL;
                29092     xmlParserInputPtr inputStream = NULL;
                29093     int ret;
                29094 
                29095     if ((ctxt == NULL) || (input == NULL))
                29096         return (-1);
                29097 
                29098     /*
                29099      * prepare the parser
                29100      */
ad7b9726c Alex*29101     if (sax != NULL) {
                29102         pctxt = xmlNewSAXParserCtxt(sax, user_data);
                29103         if (pctxt == NULL)
                29104             return (-1);
                29105     } else {
                29106         pctxt = xmlNewParserCtxt();
                29107         if (pctxt == NULL)
                29108             return (-1);
                29109         /* We really want pctxt->sax to be NULL here. */
                29110         xmlFree(pctxt->sax);
                29111         pctxt->sax = NULL;
                29112     }
9d9d4fcc3 Alex*29113 #if 0
                29114     if (options)
                29115         xmlCtxtUseOptions(pctxt, options);
                29116 #endif
                29117     pctxt->linenumbers = 1;
                29118     xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
                29119 
da6279058 Alex*29120     inputStream = xmlNewIOInputStream(pctxt, input, enc);
9d9d4fcc3 Alex*29121     if (inputStream == NULL) {
                29122         ret = -1;
                29123     goto done;
                29124     }
                29125     inputPush(pctxt, inputStream);
                29126     ctxt->parserCtxt = pctxt;
                29127     ctxt->input = input;
                29128 
                29129     /*
                29130      * Plug the validation and launch the parsing
                29131      */
                29132     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
                29133     if (plug == NULL) {
                29134         ret = -1;
                29135     goto done;
                29136     }
                29137     ctxt->input = input;
                29138     ctxt->enc = enc;
                29139     ctxt->sax = pctxt->sax;
                29140     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
                29141     ret = xmlSchemaVStart(ctxt);
                29142 
                29143     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
                29144     ret = ctxt->parserCtxt->errNo;
                29145     if (ret == 0)
                29146         ret = 1;
                29147     }
                29148 
                29149 done:
                29150     ctxt->parserCtxt = NULL;
                29151     ctxt->sax = NULL;
                29152     ctxt->input = NULL;
                29153     if (plug != NULL) {
                29154         xmlSchemaSAXUnplug(plug);
                29155     }
                29156     /* cleanup */
                29157     if (pctxt != NULL) {
                29158     xmlFreeParserCtxt(pctxt);
                29159     }
                29160     return (ret);
                29161 }
                29162 
                29163 /**
                29164  * xmlSchemaValidateFile:
                29165  * @ctxt: a schema validation context
                29166  * @filename: the URI of the instance
                29167  * @options: a future set of options, currently unused
                29168  *
                29169  * Do a schemas validation of the given resource, it will use the
                29170  * SAX streamable validation internally.
                29171  *
                29172  * Returns 0 if the document is valid, a positive error code
                29173  *     number otherwise and -1 in case of an internal or API error.
                29174  */
                29175 int
                29176 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
                29177                       const char * filename,
                29178               int options ATTRIBUTE_UNUSED)
                29179 {
                29180     int ret;
                29181     xmlParserInputBufferPtr input;
                29182 
                29183     if ((ctxt == NULL) || (filename == NULL))
                29184         return (-1);
                29185 
                29186     input = xmlParserInputBufferCreateFilename(filename,
                29187     XML_CHAR_ENCODING_NONE);
                29188     if (input == NULL)
                29189     return (-1);
                29190     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
                29191     NULL, NULL);
                29192     return (ret);
                29193 }
                29194 
                29195 /**
                29196  * xmlSchemaValidCtxtGetParserCtxt:
                29197  * @ctxt: a schema validation context
                29198  *
                29199  * allow access to the parser context of the schema validation context
                29200  *
                29201  * Returns the parser context of the schema validation context or NULL
                29202  *         in case of error.
                29203  */
                29204 xmlParserCtxtPtr
                29205 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
                29206 {
                29207     if (ctxt == NULL)
                29208         return(NULL);
                29209     return (ctxt->parserCtxt);
                29210 }
                29211 
                29212 #endif /* LIBXML_SCHEMAS_ENABLED */