Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlschemas.c
Go to the documentation of this file.
00001 /* 00002 * schemas.c : implementation of the XML Schema handling and 00003 * schema validity checking 00004 * 00005 * See Copyright for the status of this software. 00006 * 00007 * Daniel Veillard <veillard@redhat.com> 00008 */ 00009 00010 /* 00011 * TODO: 00012 * - when types are redefined in includes, check that all 00013 * types in the redef list are equal 00014 * -> need a type equality operation. 00015 * - if we don't intend to use the schema for schemas, we 00016 * need to validate all schema attributes (ref, type, name) 00017 * against their types. 00018 * - Eliminate item creation for: ?? 00019 * 00020 * URGENT TODO: 00021 * - For xsi-driven schema acquisition, augment the IDCs after every 00022 * acquisition episode (xmlSchemaAugmentIDC). 00023 * 00024 * NOTES: 00025 * - Elimated item creation for: <restriction>, <extension>, 00026 * <simpleContent>, <complexContent>, <list>, <union> 00027 * 00028 * PROBLEMS: 00029 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 00030 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 00031 * XPath will have trouble to resolve to this namespace, since not known. 00032 * 00033 * 00034 * CONSTRAINTS: 00035 * 00036 * Schema Component Constraint: 00037 * All Group Limited (cos-all-limited) 00038 * Status: complete 00039 * (1.2) 00040 * In xmlSchemaGroupDefReferenceTermFixup() and 00041 * (2) 00042 * In xmlSchemaParseModelGroup() 00043 * TODO: Actually this should go to component-level checks, 00044 * but is done here due to performance. Move it to an other layer 00045 * is schema construction via an API is implemented. 00046 */ 00047 #define IN_LIBXML 00048 #include "libxml.h" 00049 00050 #ifdef LIBXML_SCHEMAS_ENABLED 00051 00052 #include <string.h> 00053 #include <libxml/xmlmemory.h> 00054 #include <libxml/parser.h> 00055 #include <libxml/parserInternals.h> 00056 #include <libxml/hash.h> 00057 #include <libxml/uri.h> 00058 #include <libxml/xmlschemas.h> 00059 #include <libxml/schemasInternals.h> 00060 #include <libxml/xmlschemastypes.h> 00061 #include <libxml/xmlautomata.h> 00062 #include <libxml/xmlregexp.h> 00063 #include <libxml/dict.h> 00064 #include <libxml/encoding.h> 00065 #include <libxml/xmlIO.h> 00066 #ifdef LIBXML_PATTERN_ENABLED 00067 #include <libxml/pattern.h> 00068 #endif 00069 #ifdef LIBXML_READER_ENABLED 00070 #include <libxml/xmlreader.h> 00071 #endif 00072 00073 /* #define DEBUG 1 */ 00074 00075 /* #define DEBUG_CONTENT 1 */ 00076 00077 /* #define DEBUG_TYPE 1 */ 00078 00079 /* #define DEBUG_CONTENT_REGEXP 1 */ 00080 00081 /* #define DEBUG_AUTOMATA 1 */ 00082 00083 /* #define DEBUG_IDC */ 00084 00085 /* #define DEBUG_IDC_NODE_TABLE */ 00086 00087 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 00088 00089 #ifdef DEBUG_IDC 00090 #ifndef DEBUG_IDC_NODE_TABLE 00091 #define DEBUG_IDC_NODE_TABLE 00092 #endif 00093 #endif 00094 00095 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 00096 00097 #define ENABLE_REDEFINE 00098 00099 /* #define ENABLE_NAMED_LOCALS */ 00100 00101 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 00102 00103 #define DUMP_CONTENT_MODEL 00104 00105 #ifdef LIBXML_READER_ENABLED 00106 /* #define XML_SCHEMA_READER_ENABLED */ 00107 #endif 00108 00109 #define UNBOUNDED (1 << 30) 00110 #define TODO \ 00111 xmlGenericError(xmlGenericErrorContext, \ 00112 "Unimplemented block at %s:%d\n", \ 00113 __FILE__, __LINE__); 00114 00115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 00116 00117 /* 00118 * The XML Schemas namespaces 00119 */ 00120 static const xmlChar *xmlSchemaNs = (const xmlChar *) 00121 "http://www.w3.org/2001/XMLSchema"; 00122 00123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 00124 "http://www.w3.org/2001/XMLSchema-instance"; 00125 00126 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 00127 "http://www.w3.org/2000/xmlns/"; 00128 00129 /* 00130 * Come casting macros. 00131 */ 00132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 00133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 00134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 00135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 00136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 00137 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 00138 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 00139 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 00140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 00141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 00142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 00143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 00144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 00145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 00146 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 00147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 00148 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 00149 00150 /* 00151 * Macros to query common properties of components. 00152 */ 00153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 00154 00155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 00156 /* 00157 * Macros for element declarations. 00158 */ 00159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 00160 00161 #define WXS_SUBST_HEAD(item) (item)->refDecl 00162 /* 00163 * Macros for attribute declarations. 00164 */ 00165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 00166 /* 00167 * Macros for attribute uses. 00168 */ 00169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl 00170 00171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 00172 00173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 00174 00175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 00176 /* 00177 * Macros for attribute groups. 00178 */ 00179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 00180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 00181 /* 00182 * Macros for particles. 00183 */ 00184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 00185 00186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 00187 00188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 00189 00190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 00191 /* 00192 * Macros for model groups definitions. 00193 */ 00194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 00195 /* 00196 * Macros for model groups. 00197 */ 00198 #define WXS_IS_MODEL_GROUP(i) \ 00199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 00200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 00201 ((i)->type == XML_SCHEMA_TYPE_ALL)) 00202 00203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 00204 /* 00205 * Macros for schema buckets. 00206 */ 00207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 00208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 00209 00210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 00211 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 00212 00213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 00214 00215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 00216 /* 00217 * Macros for complex/simple types. 00218 */ 00219 #define WXS_IS_ANYTYPE(i) \ 00220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 00221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 00222 00223 #define WXS_IS_COMPLEX(i) \ 00224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 00225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 00226 00227 #define WXS_IS_SIMPLE(item) \ 00228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 00229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 00230 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 00231 00232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 00233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 00234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 00235 00236 #define WXS_IS_RESTRICTION(t) \ 00237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 00238 00239 #define WXS_IS_EXTENSION(t) \ 00240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 00241 00242 #define WXS_IS_TYPE_NOT_FIXED(i) \ 00243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 00244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 00245 00246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 00247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 00248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 00249 00250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 00251 00252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 00253 /* 00254 * Macros for exclusively for complex types. 00255 */ 00256 #define WXS_HAS_COMPLEX_CONTENT(item) \ 00257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 00258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 00259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 00260 00261 #define WXS_HAS_SIMPLE_CONTENT(item) \ 00262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 00263 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 00264 00265 #define WXS_HAS_MIXED_CONTENT(item) \ 00266 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 00267 00268 #define WXS_EMPTIABLE(t) \ 00269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 00270 00271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 00272 00273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 00274 00275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 00276 /* 00277 * Macros for exclusively for simple types. 00278 */ 00279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 00280 00281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 00282 00283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 00284 00285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 00286 /* 00287 * Misc parser context macros. 00288 */ 00289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 00290 00291 #define WXS_HAS_BUCKETS(ctx) \ 00292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 00293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 00294 00295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 00296 00297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 00298 00299 #define WXS_SCHEMA(ctx) (ctx)->schema 00300 00301 #define WXS_ADD_LOCAL(ctx, item) \ 00302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 00303 00304 #define WXS_ADD_GLOBAL(ctx, item) \ 00305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 00306 00307 #define WXS_ADD_PENDING(ctx, item) \ 00308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 00309 /* 00310 * xmlSchemaItemList macros. 00311 */ 00312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 00313 /* 00314 * Misc macros. 00315 */ 00316 #define IS_SCHEMA(node, type) \ 00317 ((node != NULL) && (node->ns != NULL) && \ 00318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 00319 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 00320 00321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 00322 00323 /* 00324 * Since we put the default/fixed values into the dict, we can 00325 * use pointer comparison for those values. 00326 * REMOVED: (xmlStrEqual((v1), (v2))) 00327 */ 00328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 00329 00330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 00331 00332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 00333 00334 #define HFAILURE if (res == -1) goto exit_failure; 00335 00336 #define HERROR if (res != 0) goto exit_error; 00337 00338 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 00339 /* 00340 * Some flags used for various schema constraints. 00341 */ 00342 #define SUBSET_RESTRICTION 1<<0 00343 #define SUBSET_EXTENSION 1<<1 00344 #define SUBSET_SUBSTITUTION 1<<2 00345 #define SUBSET_LIST 1<<3 00346 #define SUBSET_UNION 1<<4 00347 00348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 00349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 00350 00351 typedef struct _xmlSchemaItemList xmlSchemaItemList; 00352 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 00353 struct _xmlSchemaItemList { 00354 void **items; /* used for dynamic addition of schemata */ 00355 int nbItems; /* used for dynamic addition of schemata */ 00356 int sizeItems; /* used for dynamic addition of schemata */ 00357 }; 00358 00359 #define XML_SCHEMA_CTXT_PARSER 1 00360 #define XML_SCHEMA_CTXT_VALIDATOR 2 00361 00362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 00363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 00364 struct _xmlSchemaAbstractCtxt { 00365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 00366 }; 00367 00368 typedef struct _xmlSchemaBucket xmlSchemaBucket; 00369 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 00370 00371 #define XML_SCHEMA_SCHEMA_MAIN 0 00372 #define XML_SCHEMA_SCHEMA_IMPORT 1 00373 #define XML_SCHEMA_SCHEMA_INCLUDE 2 00374 #define XML_SCHEMA_SCHEMA_REDEFINE 3 00375 00381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 00382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 00383 struct _xmlSchemaSchemaRelation { 00384 xmlSchemaSchemaRelationPtr next; 00385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 00386 const xmlChar *importNamespace; 00387 xmlSchemaBucketPtr bucket; 00388 }; 00389 00390 #define XML_SCHEMA_BUCKET_MARKED 1<<0 00391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 00392 00393 struct _xmlSchemaBucket { 00394 int type; 00395 int flags; 00396 const xmlChar *schemaLocation; 00397 const xmlChar *origTargetNamespace; 00398 const xmlChar *targetNamespace; 00399 xmlDocPtr doc; 00400 xmlSchemaSchemaRelationPtr relations; 00401 int located; 00402 int parsed; 00403 int imported; 00404 int preserveDoc; 00405 xmlSchemaItemListPtr globals; /* Global components. */ 00406 xmlSchemaItemListPtr locals; /* Local components. */ 00407 }; 00408 00417 typedef struct _xmlSchemaImport xmlSchemaImport; 00418 typedef xmlSchemaImport *xmlSchemaImportPtr; 00419 struct _xmlSchemaImport { 00420 int type; /* Main OR import OR include. */ 00421 int flags; 00422 const xmlChar *schemaLocation; /* The URI of the schema document. */ 00423 /* For chameleon includes, @origTargetNamespace will be NULL */ 00424 const xmlChar *origTargetNamespace; 00425 /* 00426 * For chameleon includes, @targetNamespace will be the 00427 * targetNamespace of the including schema. 00428 */ 00429 const xmlChar *targetNamespace; 00430 xmlDocPtr doc; /* The schema node-tree. */ 00431 /* @relations will hold any included/imported/redefined schemas. */ 00432 xmlSchemaSchemaRelationPtr relations; 00433 int located; 00434 int parsed; 00435 int imported; 00436 int preserveDoc; 00437 xmlSchemaItemListPtr globals; 00438 xmlSchemaItemListPtr locals; 00439 /* The imported schema. */ 00440 xmlSchemaPtr schema; 00441 }; 00442 00443 /* 00444 * (extends xmlSchemaBucket) 00445 */ 00446 typedef struct _xmlSchemaInclude xmlSchemaInclude; 00447 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 00448 struct _xmlSchemaInclude { 00449 int type; 00450 int flags; 00451 const xmlChar *schemaLocation; 00452 const xmlChar *origTargetNamespace; 00453 const xmlChar *targetNamespace; 00454 xmlDocPtr doc; 00455 xmlSchemaSchemaRelationPtr relations; 00456 int located; 00457 int parsed; 00458 int imported; 00459 int preserveDoc; 00460 xmlSchemaItemListPtr globals; /* Global components. */ 00461 xmlSchemaItemListPtr locals; /* Local components. */ 00462 00463 /* The owning main or import schema bucket. */ 00464 xmlSchemaImportPtr ownerImport; 00465 }; 00466 00472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 00473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 00474 struct _xmlSchemaBasicItem { 00475 xmlSchemaTypeType type; 00476 }; 00477 00484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 00485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 00486 struct _xmlSchemaAnnotItem { 00487 xmlSchemaTypeType type; 00488 xmlSchemaAnnotPtr annot; 00489 }; 00490 00497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 00498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 00499 struct _xmlSchemaTreeItem { 00500 xmlSchemaTypeType type; 00501 xmlSchemaAnnotPtr annot; 00502 xmlSchemaTreeItemPtr next; 00503 xmlSchemaTreeItemPtr children; 00504 }; 00505 00506 00507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 00508 00514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 00515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 00516 struct _xmlSchemaAttributeUse { 00517 xmlSchemaTypeType type; 00518 xmlSchemaAnnotPtr annot; 00519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 00520 /* 00521 * The attr. decl. OR a QName-ref. to an attr. decl. OR 00522 * a QName-ref. to an attribute group definition. 00523 */ 00524 xmlSchemaAttributePtr attrDecl; 00525 00526 int flags; 00527 xmlNodePtr node; 00528 int occurs; /* required, optional */ 00529 const xmlChar * defValue; 00530 xmlSchemaValPtr defVal; 00531 }; 00532 00539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 00540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 00541 struct _xmlSchemaAttributeUseProhib { 00542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 00543 xmlNodePtr node; 00544 const xmlChar *name; 00545 const xmlChar *targetNamespace; 00546 int isRef; 00547 }; 00548 00552 typedef struct _xmlSchemaRedef xmlSchemaRedef; 00553 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 00554 struct _xmlSchemaRedef { 00555 xmlSchemaRedefPtr next; 00556 xmlSchemaBasicItemPtr item; /* The redefining component. */ 00557 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 00558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 00559 const xmlChar *refName; /* The name of the to-be-redefined component. */ 00560 const xmlChar *refTargetNs; /* The target namespace of the 00561 to-be-redefined comp. */ 00562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 00563 }; 00564 00568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 00569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 00570 struct _xmlSchemaConstructionCtxt { 00571 xmlSchemaPtr mainSchema; /* The main schema. */ 00572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 00573 xmlDictPtr dict; 00574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 00575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 00576 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 00577 xmlSchemaItemListPtr pending; /* All Components of all schemas that 00578 need to be fixed. */ 00579 xmlHashTablePtr substGroups; 00580 xmlSchemaRedefPtr redefs; 00581 xmlSchemaRedefPtr lastRedef; 00582 }; 00583 00584 #define XML_SCHEMAS_PARSE_ERROR 1 00585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 00586 00587 struct _xmlSchemaParserCtxt { 00588 int type; 00589 void *errCtxt; /* user specific error context */ 00590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 00591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 00592 int err; 00593 int nberrors; 00594 xmlStructuredErrorFunc serror; 00595 00596 xmlSchemaConstructionCtxtPtr constructor; 00597 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 00598 00599 /* xmlSchemaPtr topschema; */ 00600 /* xmlHashTablePtr namespaces; */ 00601 00602 xmlSchemaPtr schema; /* The main schema in use */ 00603 int counter; 00604 00605 const xmlChar *URL; 00606 xmlDocPtr doc; 00607 int preserve; /* Whether the doc should be freed */ 00608 00609 const char *buffer; 00610 int size; 00611 00612 /* 00613 * Used to build complex element content models 00614 */ 00615 xmlAutomataPtr am; 00616 xmlAutomataStatePtr start; 00617 xmlAutomataStatePtr end; 00618 xmlAutomataStatePtr state; 00619 00620 xmlDictPtr dict; /* dictionnary for interned string names */ 00621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 00622 int options; 00623 xmlSchemaValidCtxtPtr vctxt; 00624 int isS4S; 00625 int isRedefine; 00626 int xsiAssemble; 00627 int stop; /* If the parser should stop; i.e. a critical error. */ 00628 const xmlChar *targetNamespace; 00629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 00630 00631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 00632 int redefCounter; /* Used for redefinitions. */ 00633 xmlSchemaItemListPtr attrProhibs; 00634 }; 00635 00642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 00643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 00644 struct _xmlSchemaQNameRef { 00645 xmlSchemaTypeType type; 00646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 00647 xmlSchemaTypeType itemType; 00648 const xmlChar *name; 00649 const xmlChar *targetNamespace; 00650 xmlNodePtr node; 00651 }; 00652 00659 typedef struct _xmlSchemaParticle xmlSchemaParticle; 00660 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 00661 struct _xmlSchemaParticle { 00662 xmlSchemaTypeType type; 00663 xmlSchemaAnnotPtr annot; 00664 xmlSchemaTreeItemPtr next; /* next particle */ 00665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 00666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 00667 etc.) */ 00668 int minOccurs; 00669 int maxOccurs; 00670 xmlNodePtr node; 00671 }; 00672 00679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 00680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 00681 struct _xmlSchemaModelGroup { 00682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 00683 xmlSchemaAnnotPtr annot; 00684 xmlSchemaTreeItemPtr next; /* not used */ 00685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 00686 xmlNodePtr node; 00687 }; 00688 00689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 00690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 00691 00697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 00698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 00699 struct _xmlSchemaModelGroupDef { 00700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 00701 xmlSchemaAnnotPtr annot; 00702 xmlSchemaTreeItemPtr next; /* not used */ 00703 xmlSchemaTreeItemPtr children; /* the "model group" */ 00704 const xmlChar *name; 00705 const xmlChar *targetNamespace; 00706 xmlNodePtr node; 00707 int flags; 00708 }; 00709 00710 typedef struct _xmlSchemaIDC xmlSchemaIDC; 00711 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 00712 00719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 00720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 00721 struct _xmlSchemaIDCSelect { 00722 xmlSchemaIDCSelectPtr next; 00723 xmlSchemaIDCPtr idc; 00724 int index; /* an index position if significant for IDC key-sequences */ 00725 const xmlChar *xpath; /* the XPath expression */ 00726 void *xpathComp; /* the compiled XPath expression */ 00727 }; 00728 00736 struct _xmlSchemaIDC { 00737 xmlSchemaTypeType type; 00738 xmlSchemaAnnotPtr annot; 00739 xmlSchemaIDCPtr next; 00740 xmlNodePtr node; 00741 const xmlChar *name; 00742 const xmlChar *targetNamespace; 00743 xmlSchemaIDCSelectPtr selector; 00744 xmlSchemaIDCSelectPtr fields; 00745 int nbFields; 00746 xmlSchemaQNameRefPtr ref; 00747 }; 00748 00754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 00755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 00756 struct _xmlSchemaIDCAug { 00757 xmlSchemaIDCAugPtr next; /* next in a list */ 00758 xmlSchemaIDCPtr def; /* the IDC definition */ 00759 int keyrefDepth; /* the lowest tree level to which IDC 00760 tables need to be bubbled upwards */ 00761 }; 00762 00768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 00769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 00770 struct _xmlSchemaPSVIIDCKey { 00771 xmlSchemaTypePtr type; 00772 xmlSchemaValPtr val; 00773 }; 00774 00780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 00781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 00782 struct _xmlSchemaPSVIIDCNode { 00783 xmlNodePtr node; 00784 xmlSchemaPSVIIDCKeyPtr *keys; 00785 int nodeLine; 00786 int nodeQNameID; 00787 00788 }; 00789 00795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 00796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 00797 struct _xmlSchemaPSVIIDCBinding { 00798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 00799 xmlSchemaIDCPtr definition; /* the IDC definition */ 00800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 00801 int nbNodes; /* number of entries in the node table */ 00802 int sizeNodes; /* size of the node table */ 00803 xmlSchemaItemListPtr dupls; 00804 }; 00805 00806 00807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 00808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 00809 00810 #define XPATH_STATE_OBJ_MATCHES -2 00811 #define XPATH_STATE_OBJ_BLOCKED -3 00812 00813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 00814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 00815 00821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 00822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 00823 struct _xmlSchemaIDCStateObj { 00824 int type; 00825 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 00826 int depth; /* depth of creation */ 00827 int *history; /* list of (depth, state-id) tuples */ 00828 int nbHistory; 00829 int sizeHistory; 00830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 00831 matcher */ 00832 xmlSchemaIDCSelectPtr sel; 00833 void *xpathCtxt; 00834 }; 00835 00836 #define IDC_MATCHER 0 00837 00843 struct _xmlSchemaIDCMatcher { 00844 int type; 00845 int depth; /* the tree depth at creation time */ 00846 xmlSchemaIDCMatcherPtr next; /* next in the list */ 00847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 00848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 00849 int idcType; 00850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 00851 elements */ 00852 int sizeKeySeqs; 00853 xmlSchemaItemListPtr targets; /* list of target-node 00854 (xmlSchemaPSVIIDCNodePtr) entries */ 00855 }; 00856 00857 /* 00858 * Element info flags. 00859 */ 00860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 00861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 00862 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 00863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 00864 00865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 00866 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 00867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 00868 00869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 00870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 00871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 00872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 00873 00879 struct _xmlSchemaNodeInfo { 00880 int nodeType; 00881 xmlNodePtr node; 00882 int nodeLine; 00883 const xmlChar *localName; 00884 const xmlChar *nsName; 00885 const xmlChar *value; 00886 xmlSchemaValPtr val; /* the pre-computed value if any */ 00887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 00888 00889 int flags; /* combination of node info flags */ 00890 00891 int valNeeded; 00892 int normVal; 00893 00894 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 00895 int depth; 00896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 00897 for the scope element*/ 00898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 00899 element */ 00900 xmlRegExecCtxtPtr regexCtxt; 00901 00902 const xmlChar **nsBindings; /* Namespace bindings on this element */ 00903 int nbNsBindings; 00904 int sizeNsBindings; 00905 00906 int hasKeyrefs; 00907 int appliedXPath; /* Indicates that an XPath has been applied. */ 00908 }; 00909 00910 #define XML_SCHEMAS_ATTR_UNKNOWN 1 00911 #define XML_SCHEMAS_ATTR_ASSESSED 2 00912 #define XML_SCHEMAS_ATTR_PROHIBITED 3 00913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 00914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 00915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 00916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 00917 #define XML_SCHEMAS_ATTR_DEFAULT 8 00918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 00919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 00920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 00921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 00922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 00923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 00924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 00925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 00926 #define XML_SCHEMAS_ATTR_META 17 00927 /* 00928 * @metaType values of xmlSchemaAttrInfo. 00929 */ 00930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 00931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 00932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 00933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 00934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 00935 00936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 00937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 00938 struct _xmlSchemaAttrInfo { 00939 int nodeType; 00940 xmlNodePtr node; 00941 int nodeLine; 00942 const xmlChar *localName; 00943 const xmlChar *nsName; 00944 const xmlChar *value; 00945 xmlSchemaValPtr val; /* the pre-computed value if any */ 00946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 00947 int flags; /* combination of node info flags */ 00948 00949 xmlSchemaAttributePtr decl; /* the attribute declaration */ 00950 xmlSchemaAttributeUsePtr use; /* the attribute use */ 00951 int state; 00952 int metaType; 00953 const xmlChar *vcValue; /* the value constraint value */ 00954 xmlSchemaNodeInfoPtr parent; 00955 }; 00956 00957 00958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 00959 00964 struct _xmlSchemaValidCtxt { 00965 int type; 00966 void *errCtxt; /* user specific data block */ 00967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 00968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 00969 xmlStructuredErrorFunc serror; 00970 00971 xmlSchemaPtr schema; /* The schema in use */ 00972 xmlDocPtr doc; 00973 xmlParserInputBufferPtr input; 00974 xmlCharEncoding enc; 00975 xmlSAXHandlerPtr sax; 00976 xmlParserCtxtPtr parserCtxt; 00977 void *user_data; /* TODO: What is this for? */ 00978 00979 int err; 00980 int nberrors; 00981 00982 xmlNodePtr node; 00983 xmlNodePtr cur; 00984 /* xmlSchemaTypePtr type; */ 00985 00986 xmlRegExecCtxtPtr regexp; 00987 xmlSchemaValPtr value; 00988 00989 int valueWS; 00990 int options; 00991 xmlNodePtr validationRoot; 00992 xmlSchemaParserCtxtPtr pctxt; 00993 int xsiAssemble; 00994 00995 int depth; 00996 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 00997 int sizeElemInfos; 00998 xmlSchemaNodeInfoPtr inode; /* the current element information */ 00999 01000 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 01001 01002 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 01003 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 01004 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 01005 01006 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 01007 int nbIdcNodes; 01008 int sizeIdcNodes; 01009 01010 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 01011 int nbIdcKeys; 01012 int sizeIdcKeys; 01013 01014 int flags; 01015 01016 xmlDictPtr dict; 01017 01018 #ifdef LIBXML_READER_ENABLED 01019 xmlTextReaderPtr reader; 01020 #endif 01021 01022 xmlSchemaAttrInfoPtr *attrInfos; 01023 int nbAttrInfos; 01024 int sizeAttrInfos; 01025 01026 int skipDepth; 01027 xmlSchemaItemListPtr nodeQNames; 01028 int hasKeyrefs; 01029 int createIDCNodeTables; 01030 int psviExposeIDCNodeTables; 01031 }; 01032 01038 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 01039 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 01040 struct _xmlSchemaSubstGroup { 01041 xmlSchemaElementPtr head; 01042 xmlSchemaItemListPtr members; 01043 }; 01044 01045 /************************************************************************ 01046 * * 01047 * Some predeclarations * 01048 * * 01049 ************************************************************************/ 01050 01051 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 01052 xmlSchemaPtr schema, 01053 xmlNodePtr node); 01054 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 01055 xmlSchemaPtr schema, 01056 xmlNodePtr node); 01057 static int 01058 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 01059 xmlSchemaAbstractCtxtPtr ctxt); 01060 static const xmlChar * 01061 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 01062 static int 01063 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 01064 xmlNodePtr node); 01065 static int 01066 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 01067 xmlSchemaParserCtxtPtr ctxt); 01068 static void 01069 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 01070 static xmlSchemaWhitespaceValueType 01071 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 01072 static xmlSchemaTreeItemPtr 01073 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 01074 xmlNodePtr node, xmlSchemaTypeType type, 01075 int withParticle); 01076 static const xmlChar * 01077 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 01078 static xmlSchemaTypeLinkPtr 01079 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 01080 static void 01081 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 01082 const char *funcName, 01083 const char *message); 01084 static int 01085 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 01086 xmlSchemaTypePtr type, 01087 xmlSchemaTypePtr baseType, 01088 int subset); 01089 static void 01090 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 01091 xmlSchemaParserCtxtPtr ctxt); 01092 static void 01093 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 01094 static xmlSchemaQNameRefPtr 01095 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 01096 xmlSchemaPtr schema, 01097 xmlNodePtr node); 01098 01099 /************************************************************************ 01100 * * 01101 * Helper functions * 01102 * * 01103 ************************************************************************/ 01104 01111 static const xmlChar * 01112 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 01113 { 01114 switch (type) { 01115 case XML_SCHEMA_TYPE_BASIC: 01116 return(BAD_CAST "simple type definition"); 01117 case XML_SCHEMA_TYPE_SIMPLE: 01118 return(BAD_CAST "simple type definition"); 01119 case XML_SCHEMA_TYPE_COMPLEX: 01120 return(BAD_CAST "complex type definition"); 01121 case XML_SCHEMA_TYPE_ELEMENT: 01122 return(BAD_CAST "element declaration"); 01123 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 01124 return(BAD_CAST "attribute use"); 01125 case XML_SCHEMA_TYPE_ATTRIBUTE: 01126 return(BAD_CAST "attribute declaration"); 01127 case XML_SCHEMA_TYPE_GROUP: 01128 return(BAD_CAST "model group definition"); 01129 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 01130 return(BAD_CAST "attribute group definition"); 01131 case XML_SCHEMA_TYPE_NOTATION: 01132 return(BAD_CAST "notation declaration"); 01133 case XML_SCHEMA_TYPE_SEQUENCE: 01134 return(BAD_CAST "model group (sequence)"); 01135 case XML_SCHEMA_TYPE_CHOICE: 01136 return(BAD_CAST "model group (choice)"); 01137 case XML_SCHEMA_TYPE_ALL: 01138 return(BAD_CAST "model group (all)"); 01139 case XML_SCHEMA_TYPE_PARTICLE: 01140 return(BAD_CAST "particle"); 01141 case XML_SCHEMA_TYPE_IDC_UNIQUE: 01142 return(BAD_CAST "unique identity-constraint"); 01143 /* return(BAD_CAST "IDC (unique)"); */ 01144 case XML_SCHEMA_TYPE_IDC_KEY: 01145 return(BAD_CAST "key identity-constraint"); 01146 /* return(BAD_CAST "IDC (key)"); */ 01147 case XML_SCHEMA_TYPE_IDC_KEYREF: 01148 return(BAD_CAST "keyref identity-constraint"); 01149 /* return(BAD_CAST "IDC (keyref)"); */ 01150 case XML_SCHEMA_TYPE_ANY: 01151 return(BAD_CAST "wildcard (any)"); 01152 case XML_SCHEMA_EXTRA_QNAMEREF: 01153 return(BAD_CAST "[helper component] QName reference"); 01154 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 01155 return(BAD_CAST "[helper component] attribute use prohibition"); 01156 default: 01157 return(BAD_CAST "Not a schema component"); 01158 } 01159 } 01160 01167 static const xmlChar * 01168 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 01169 { 01170 switch (item->type) { 01171 case XML_SCHEMA_TYPE_BASIC: 01172 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 01173 return(BAD_CAST "complex type definition"); 01174 else 01175 return(BAD_CAST "simple type definition"); 01176 default: 01177 return(xmlSchemaItemTypeToStr(item->type)); 01178 } 01179 } 01180 01191 static xmlNodePtr 01192 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 01193 { 01194 switch (item->type) { 01195 case XML_SCHEMA_TYPE_ELEMENT: 01196 return (((xmlSchemaElementPtr) item)->node); 01197 case XML_SCHEMA_TYPE_ATTRIBUTE: 01198 return (((xmlSchemaAttributePtr) item)->node); 01199 case XML_SCHEMA_TYPE_COMPLEX: 01200 case XML_SCHEMA_TYPE_SIMPLE: 01201 return (((xmlSchemaTypePtr) item)->node); 01202 case XML_SCHEMA_TYPE_ANY: 01203 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 01204 return (((xmlSchemaWildcardPtr) item)->node); 01205 case XML_SCHEMA_TYPE_PARTICLE: 01206 return (((xmlSchemaParticlePtr) item)->node); 01207 case XML_SCHEMA_TYPE_SEQUENCE: 01208 case XML_SCHEMA_TYPE_CHOICE: 01209 case XML_SCHEMA_TYPE_ALL: 01210 return (((xmlSchemaModelGroupPtr) item)->node); 01211 case XML_SCHEMA_TYPE_GROUP: 01212 return (((xmlSchemaModelGroupDefPtr) item)->node); 01213 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 01214 return (((xmlSchemaAttributeGroupPtr) item)->node); 01215 case XML_SCHEMA_TYPE_IDC_UNIQUE: 01216 case XML_SCHEMA_TYPE_IDC_KEY: 01217 case XML_SCHEMA_TYPE_IDC_KEYREF: 01218 return (((xmlSchemaIDCPtr) item)->node); 01219 case XML_SCHEMA_EXTRA_QNAMEREF: 01220 return(((xmlSchemaQNameRefPtr) item)->node); 01221 /* TODO: What to do with NOTATIONs? 01222 case XML_SCHEMA_TYPE_NOTATION: 01223 return (((xmlSchemaNotationPtr) item)->node); 01224 */ 01225 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 01226 return (((xmlSchemaAttributeUsePtr) item)->node); 01227 default: 01228 return (NULL); 01229 } 01230 } 01231 01232 #if 0 01233 01239 static xmlSchemaBasicItemPtr 01240 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 01241 { 01242 switch (item->type) { 01243 case XML_SCHEMA_TYPE_ELEMENT: 01244 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 01245 case XML_SCHEMA_TYPE_ATTRIBUTE: 01246 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 01247 case XML_SCHEMA_TYPE_COMPLEX: 01248 case XML_SCHEMA_TYPE_SIMPLE: 01249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 01250 case XML_SCHEMA_TYPE_ANY: 01251 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 01252 return (NULL); 01253 case XML_SCHEMA_TYPE_PARTICLE: 01254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 01255 case XML_SCHEMA_TYPE_SEQUENCE: 01256 case XML_SCHEMA_TYPE_CHOICE: 01257 case XML_SCHEMA_TYPE_ALL: 01258 return (NULL); 01259 case XML_SCHEMA_TYPE_GROUP: 01260 return (NULL); 01261 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 01262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 01263 case XML_SCHEMA_TYPE_IDC_UNIQUE: 01264 case XML_SCHEMA_TYPE_IDC_KEY: 01265 case XML_SCHEMA_TYPE_IDC_KEYREF: 01266 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 01267 default: 01268 return (NULL); 01269 } 01270 } 01271 #endif 01272 01273 01286 static const xmlChar* 01287 xmlSchemaFormatQName(xmlChar **buf, 01288 const xmlChar *namespaceName, 01289 const xmlChar *localName) 01290 { 01291 FREE_AND_NULL(*buf) 01292 if (namespaceName != NULL) { 01293 *buf = xmlStrdup(BAD_CAST "{"); 01294 *buf = xmlStrcat(*buf, namespaceName); 01295 *buf = xmlStrcat(*buf, BAD_CAST "}"); 01296 } 01297 if (localName != NULL) { 01298 if (namespaceName == NULL) 01299 return(localName); 01300 *buf = xmlStrcat(*buf, localName); 01301 } else { 01302 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 01303 } 01304 return ((const xmlChar *) *buf); 01305 } 01306 01307 static const xmlChar* 01308 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 01309 { 01310 if (ns != NULL) 01311 return (xmlSchemaFormatQName(buf, ns->href, localName)); 01312 else 01313 return (xmlSchemaFormatQName(buf, NULL, localName)); 01314 } 01315 01316 static const xmlChar * 01317 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 01318 { 01319 switch (item->type) { 01320 case XML_SCHEMA_TYPE_ELEMENT: 01321 return (((xmlSchemaElementPtr) item)->name); 01322 case XML_SCHEMA_TYPE_ATTRIBUTE: 01323 return (((xmlSchemaAttributePtr) item)->name); 01324 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 01325 return (((xmlSchemaAttributeGroupPtr) item)->name); 01326 case XML_SCHEMA_TYPE_BASIC: 01327 case XML_SCHEMA_TYPE_SIMPLE: 01328 case XML_SCHEMA_TYPE_COMPLEX: 01329 return (((xmlSchemaTypePtr) item)->name); 01330 case XML_SCHEMA_TYPE_GROUP: 01331 return (((xmlSchemaModelGroupDefPtr) item)->name); 01332 case XML_SCHEMA_TYPE_IDC_KEY: 01333 case XML_SCHEMA_TYPE_IDC_UNIQUE: 01334 case XML_SCHEMA_TYPE_IDC_KEYREF: 01335 return (((xmlSchemaIDCPtr) item)->name); 01336 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 01337 if (WXS_ATTRUSE_DECL(item) != NULL) { 01338 return(xmlSchemaGetComponentName( 01339 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 01340 } else 01341 return(NULL); 01342 case XML_SCHEMA_EXTRA_QNAMEREF: 01343 return (((xmlSchemaQNameRefPtr) item)->name); 01344 case XML_SCHEMA_TYPE_NOTATION: 01345 return (((xmlSchemaNotationPtr) item)->name); 01346 default: 01347 /* 01348 * Other components cannot have names. 01349 */ 01350 break; 01351 } 01352 return (NULL); 01353 } 01354 01355 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 01356 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 01357 /* 01358 static const xmlChar * 01359 xmlSchemaGetQNameRefName(void *ref) 01360 { 01361 return(((xmlSchemaQNameRefPtr) ref)->name); 01362 } 01363 01364 static const xmlChar * 01365 xmlSchemaGetQNameRefTargetNs(void *ref) 01366 { 01367 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 01368 } 01369 */ 01370 01371 static const xmlChar * 01372 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 01373 { 01374 switch (item->type) { 01375 case XML_SCHEMA_TYPE_ELEMENT: 01376 return (((xmlSchemaElementPtr) item)->targetNamespace); 01377 case XML_SCHEMA_TYPE_ATTRIBUTE: 01378 return (((xmlSchemaAttributePtr) item)->targetNamespace); 01379 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 01380 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 01381 case XML_SCHEMA_TYPE_BASIC: 01382 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 01383 case XML_SCHEMA_TYPE_SIMPLE: 01384 case XML_SCHEMA_TYPE_COMPLEX: 01385 return (((xmlSchemaTypePtr) item)->targetNamespace); 01386 case XML_SCHEMA_TYPE_GROUP: 01387 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 01388 case XML_SCHEMA_TYPE_IDC_KEY: 01389 case XML_SCHEMA_TYPE_IDC_UNIQUE: 01390 case XML_SCHEMA_TYPE_IDC_KEYREF: 01391 return (((xmlSchemaIDCPtr) item)->targetNamespace); 01392 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 01393 if (WXS_ATTRUSE_DECL(item) != NULL) { 01394 return(xmlSchemaGetComponentTargetNs( 01395 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 01396 } 01397 /* TODO: Will returning NULL break something? */ 01398 break; 01399 case XML_SCHEMA_EXTRA_QNAMEREF: 01400 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 01401 case XML_SCHEMA_TYPE_NOTATION: 01402 return (((xmlSchemaNotationPtr) item)->targetNamespace); 01403 default: 01404 /* 01405 * Other components cannot have names. 01406 */ 01407 break; 01408 } 01409 return (NULL); 01410 } 01411 01412 static const xmlChar* 01413 xmlSchemaGetComponentQName(xmlChar **buf, 01414 void *item) 01415 { 01416 return (xmlSchemaFormatQName(buf, 01417 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 01418 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 01419 } 01420 01421 static const xmlChar* 01422 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 01423 { 01424 xmlChar *str = NULL; 01425 01426 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 01427 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01428 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 01429 (xmlSchemaBasicItemPtr) item)); 01430 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01431 FREE_AND_NULL(str); 01432 return(*buf); 01433 } 01434 01435 static const xmlChar* 01436 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 01437 { 01438 return(xmlSchemaGetComponentDesignation(buf, idc)); 01439 } 01440 01448 static const xmlChar * 01449 xmlSchemaWildcardPCToString(int pc) 01450 { 01451 switch (pc) { 01452 case XML_SCHEMAS_ANY_SKIP: 01453 return (BAD_CAST "skip"); 01454 case XML_SCHEMAS_ANY_LAX: 01455 return (BAD_CAST "lax"); 01456 case XML_SCHEMAS_ANY_STRICT: 01457 return (BAD_CAST "strict"); 01458 default: 01459 return (BAD_CAST "invalid process contents"); 01460 } 01461 } 01462 01475 static int 01476 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 01477 xmlSchemaWhitespaceValueType ws, 01478 xmlChar **retValue) 01479 { 01480 int list; 01481 xmlSchemaValType valType; 01482 const xmlChar *value, *value2 = NULL; 01483 01484 01485 if ((retValue == NULL) || (val == NULL)) 01486 return (-1); 01487 list = xmlSchemaValueGetNext(val) ? 1 : 0; 01488 *retValue = NULL; 01489 do { 01490 value = NULL; 01491 valType = xmlSchemaGetValType(val); 01492 switch (valType) { 01493 case XML_SCHEMAS_STRING: 01494 case XML_SCHEMAS_NORMSTRING: 01495 case XML_SCHEMAS_ANYSIMPLETYPE: 01496 value = xmlSchemaValueGetAsString(val); 01497 if (value != NULL) { 01498 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 01499 value2 = xmlSchemaCollapseString(value); 01500 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 01501 value2 = xmlSchemaWhiteSpaceReplace(value); 01502 if (value2 != NULL) 01503 value = value2; 01504 } 01505 break; 01506 default: 01507 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 01508 if (value2 != NULL) 01509 xmlFree((xmlChar *) value2); 01510 goto internal_error; 01511 } 01512 value = value2; 01513 } 01514 if (*retValue == NULL) 01515 if (value == NULL) { 01516 if (! list) 01517 *retValue = xmlStrdup(BAD_CAST ""); 01518 } else 01519 *retValue = xmlStrdup(value); 01520 else if (value != NULL) { 01521 /* List. */ 01522 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 01523 *retValue = xmlStrcat((xmlChar *) *retValue, value); 01524 } 01525 FREE_AND_NULL(value2) 01526 val = xmlSchemaValueGetNext(val); 01527 } while (val != NULL); 01528 01529 return (0); 01530 internal_error: 01531 if (*retValue != NULL) 01532 xmlFree((xmlChar *) (*retValue)); 01533 if (value2 != NULL) 01534 xmlFree((xmlChar *) value2); 01535 return (-1); 01536 } 01537 01564 static xmlChar* 01565 xmlSchemaFormatItemForReport(xmlChar **buf, 01566 const xmlChar *itemDes, 01567 xmlSchemaBasicItemPtr item, 01568 xmlNodePtr itemNode) 01569 { 01570 xmlChar *str = NULL; 01571 int named = 1; 01572 01573 if (*buf != NULL) { 01574 xmlFree(*buf); 01575 *buf = NULL; 01576 } 01577 01578 if (itemDes != NULL) { 01579 *buf = xmlStrdup(itemDes); 01580 } else if (item != NULL) { 01581 switch (item->type) { 01582 case XML_SCHEMA_TYPE_BASIC: { 01583 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 01584 01585 if (WXS_IS_ATOMIC(type)) 01586 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 01587 else if (WXS_IS_LIST(type)) 01588 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 01589 else if (WXS_IS_UNION(type)) 01590 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 01591 else 01592 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 01593 *buf = xmlStrcat(*buf, type->name); 01594 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01595 } 01596 break; 01597 case XML_SCHEMA_TYPE_SIMPLE: { 01598 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 01599 01600 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 01601 *buf = xmlStrdup(BAD_CAST""); 01602 } else { 01603 *buf = xmlStrdup(BAD_CAST "local "); 01604 } 01605 if (WXS_IS_ATOMIC(type)) 01606 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 01607 else if (WXS_IS_LIST(type)) 01608 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 01609 else if (WXS_IS_UNION(type)) 01610 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 01611 else 01612 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 01613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 01614 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01615 *buf = xmlStrcat(*buf, type->name); 01616 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01617 } 01618 } 01619 break; 01620 case XML_SCHEMA_TYPE_COMPLEX: { 01621 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 01622 01623 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 01624 *buf = xmlStrdup(BAD_CAST ""); 01625 else 01626 *buf = xmlStrdup(BAD_CAST "local "); 01627 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 01628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 01629 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01630 *buf = xmlStrcat(*buf, type->name); 01631 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01632 } 01633 } 01634 break; 01635 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 01636 xmlSchemaAttributeUsePtr ause; 01637 01638 ause = WXS_ATTR_USE_CAST item; 01639 *buf = xmlStrdup(BAD_CAST "attribute use "); 01640 if (WXS_ATTRUSE_DECL(ause) != NULL) { 01641 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01642 *buf = xmlStrcat(*buf, 01643 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 01644 FREE_AND_NULL(str) 01645 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01646 } else { 01647 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 01648 } 01649 } 01650 break; 01651 case XML_SCHEMA_TYPE_ATTRIBUTE: { 01652 xmlSchemaAttributePtr attr; 01653 01654 attr = (xmlSchemaAttributePtr) item; 01655 *buf = xmlStrdup(BAD_CAST "attribute decl."); 01656 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01657 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 01658 attr->targetNamespace, attr->name)); 01659 FREE_AND_NULL(str) 01660 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01661 } 01662 break; 01663 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 01664 xmlSchemaGetComponentDesignation(buf, item); 01665 break; 01666 case XML_SCHEMA_TYPE_ELEMENT: { 01667 xmlSchemaElementPtr elem; 01668 01669 elem = (xmlSchemaElementPtr) item; 01670 *buf = xmlStrdup(BAD_CAST "element decl."); 01671 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01672 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 01673 elem->targetNamespace, elem->name)); 01674 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01675 } 01676 break; 01677 case XML_SCHEMA_TYPE_IDC_UNIQUE: 01678 case XML_SCHEMA_TYPE_IDC_KEY: 01679 case XML_SCHEMA_TYPE_IDC_KEYREF: 01680 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 01681 *buf = xmlStrdup(BAD_CAST "unique '"); 01682 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 01683 *buf = xmlStrdup(BAD_CAST "key '"); 01684 else 01685 *buf = xmlStrdup(BAD_CAST "keyRef '"); 01686 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 01687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01688 break; 01689 case XML_SCHEMA_TYPE_ANY: 01690 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 01691 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 01692 ((xmlSchemaWildcardPtr) item)->processContents)); 01693 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 01694 break; 01695 case XML_SCHEMA_FACET_MININCLUSIVE: 01696 case XML_SCHEMA_FACET_MINEXCLUSIVE: 01697 case XML_SCHEMA_FACET_MAXINCLUSIVE: 01698 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 01699 case XML_SCHEMA_FACET_TOTALDIGITS: 01700 case XML_SCHEMA_FACET_FRACTIONDIGITS: 01701 case XML_SCHEMA_FACET_PATTERN: 01702 case XML_SCHEMA_FACET_ENUMERATION: 01703 case XML_SCHEMA_FACET_WHITESPACE: 01704 case XML_SCHEMA_FACET_LENGTH: 01705 case XML_SCHEMA_FACET_MAXLENGTH: 01706 case XML_SCHEMA_FACET_MINLENGTH: 01707 *buf = xmlStrdup(BAD_CAST "facet '"); 01708 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 01709 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01710 break; 01711 case XML_SCHEMA_TYPE_GROUP: { 01712 *buf = xmlStrdup(BAD_CAST "model group def."); 01713 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01714 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 01715 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01716 FREE_AND_NULL(str) 01717 } 01718 break; 01719 case XML_SCHEMA_TYPE_SEQUENCE: 01720 case XML_SCHEMA_TYPE_CHOICE: 01721 case XML_SCHEMA_TYPE_ALL: 01722 case XML_SCHEMA_TYPE_PARTICLE: 01723 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 01724 break; 01725 case XML_SCHEMA_TYPE_NOTATION: { 01726 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 01727 *buf = xmlStrcat(*buf, BAD_CAST " '"); 01728 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 01729 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01730 FREE_AND_NULL(str); 01731 } 01732 default: 01733 named = 0; 01734 } 01735 } else 01736 named = 0; 01737 01738 if ((named == 0) && (itemNode != NULL)) { 01739 xmlNodePtr elem; 01740 01741 if (itemNode->type == XML_ATTRIBUTE_NODE) 01742 elem = itemNode->parent; 01743 else 01744 elem = itemNode; 01745 *buf = xmlStrdup(BAD_CAST "Element '"); 01746 if (elem->ns != NULL) { 01747 *buf = xmlStrcat(*buf, 01748 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 01749 FREE_AND_NULL(str) 01750 } else 01751 *buf = xmlStrcat(*buf, elem->name); 01752 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01753 01754 } 01755 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 01756 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 01757 if (itemNode->ns != NULL) { 01758 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 01759 itemNode->ns->href, itemNode->name)); 01760 FREE_AND_NULL(str) 01761 } else 01762 *buf = xmlStrcat(*buf, itemNode->name); 01763 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01764 } 01765 FREE_AND_NULL(str) 01766 01767 return (*buf); 01768 } 01769 01779 static const xmlChar * 01780 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 01781 xmlChar **buf, xmlSchemaTypePtr type) 01782 { 01783 xmlSchemaFacetPtr facet; 01784 xmlSchemaWhitespaceValueType ws; 01785 xmlChar *value = NULL; 01786 int res, found = 0; 01787 01788 if (*buf != NULL) 01789 xmlFree(*buf); 01790 *buf = NULL; 01791 01792 do { 01793 /* 01794 * Use the whitespace type of the base type. 01795 */ 01796 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 01797 for (facet = type->facets; facet != NULL; facet = facet->next) { 01798 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 01799 continue; 01800 found = 1; 01801 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 01802 ws, &value); 01803 if (res == -1) { 01804 xmlSchemaInternalErr(actxt, 01805 "xmlSchemaFormatFacetEnumSet", 01806 "compute the canonical lexical representation"); 01807 if (*buf != NULL) 01808 xmlFree(*buf); 01809 *buf = NULL; 01810 return (NULL); 01811 } 01812 if (*buf == NULL) 01813 *buf = xmlStrdup(BAD_CAST "'"); 01814 else 01815 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 01816 *buf = xmlStrcat(*buf, BAD_CAST value); 01817 *buf = xmlStrcat(*buf, BAD_CAST "'"); 01818 if (value != NULL) { 01819 xmlFree((xmlChar *)value); 01820 value = NULL; 01821 } 01822 } 01823 /* 01824 * The enumeration facet of a type restricts the enumeration 01825 * facet of the ancestor type; i.e., such restricted enumerations 01826 * do not belong to the set of the given type. Thus we break 01827 * on the first found enumeration. 01828 */ 01829 if (found) 01830 break; 01831 type = type->baseType; 01832 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 01833 01834 return ((const xmlChar *) *buf); 01835 } 01836 01837 /************************************************************************ 01838 * * 01839 * Error functions * 01840 * * 01841 ************************************************************************/ 01842 01843 #if 0 01844 static void 01845 xmlSchemaErrMemory(const char *msg) 01846 { 01847 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 01848 msg); 01849 } 01850 #endif 01851 01852 static void 01853 xmlSchemaPSimpleErr(const char *msg) 01854 { 01855 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 01856 msg); 01857 } 01858 01866 static void 01867 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 01868 const char *extra, xmlNodePtr node) 01869 { 01870 if (ctxt != NULL) 01871 ctxt->nberrors++; 01872 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 01873 extra); 01874 } 01875 01887 static void 01888 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 01889 const char *msg, const xmlChar * str1, const xmlChar * str2) 01890 { 01891 xmlGenericErrorFunc channel = NULL; 01892 xmlStructuredErrorFunc schannel = NULL; 01893 void *data = NULL; 01894 01895 if (ctxt != NULL) { 01896 ctxt->nberrors++; 01897 ctxt->err = error; 01898 channel = ctxt->error; 01899 data = ctxt->errCtxt; 01900 schannel = ctxt->serror; 01901 } 01902 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 01903 error, XML_ERR_ERROR, NULL, 0, 01904 (const char *) str1, (const char *) str2, NULL, 0, 0, 01905 msg, str1, str2); 01906 } 01907 01920 static void 01921 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 01922 xmlNodePtr child, int error, 01923 const char *msg, const xmlChar * str1, const xmlChar * str2) 01924 { 01925 if (child != NULL) 01926 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 01927 else 01928 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 01929 } 01930 01931 01949 static void 01950 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 01951 const xmlChar * strData1, const xmlChar * strData2, 01952 const xmlChar * strData3, const char *msg, const xmlChar * str1, 01953 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 01954 const xmlChar * str5) 01955 { 01956 01957 xmlGenericErrorFunc channel = NULL; 01958 xmlStructuredErrorFunc schannel = NULL; 01959 void *data = NULL; 01960 01961 if (ctxt != NULL) { 01962 ctxt->nberrors++; 01963 ctxt->err = error; 01964 channel = ctxt->error; 01965 data = ctxt->errCtxt; 01966 schannel = ctxt->serror; 01967 } 01968 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 01969 error, XML_ERR_ERROR, NULL, 0, 01970 (const char *) strData1, (const char *) strData2, 01971 (const char *) strData3, 0, 0, msg, str1, str2, 01972 str3, str4, str5); 01973 } 01974 01975 /************************************************************************ 01976 * * 01977 * Allround error functions * 01978 * * 01979 ************************************************************************/ 01980 01988 static void 01989 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 01990 const char *extra, xmlNodePtr node) 01991 { 01992 if (ctxt != NULL) { 01993 ctxt->nberrors++; 01994 ctxt->err = XML_SCHEMAV_INTERNAL; 01995 } 01996 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 01997 extra); 01998 } 01999 02000 static void 02001 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 02002 const char *msg, const xmlChar *str) 02003 { 02004 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 02005 msg, (const char *) str); 02006 } 02007 02008 #define WXS_ERROR_TYPE_ERROR 1 02009 #define WXS_ERROR_TYPE_WARNING 2 02010 02022 static void 02023 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 02024 xmlErrorLevel errorLevel, 02025 int error, xmlNodePtr node, int line, const char *msg, 02026 const xmlChar *str1, const xmlChar *str2, 02027 const xmlChar *str3, const xmlChar *str4) 02028 { 02029 xmlStructuredErrorFunc schannel = NULL; 02030 xmlGenericErrorFunc channel = NULL; 02031 void *data = NULL; 02032 02033 if (ctxt != NULL) { 02034 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 02035 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 02036 const char *file = NULL; 02037 if (errorLevel != XML_ERR_WARNING) { 02038 vctxt->nberrors++; 02039 vctxt->err = error; 02040 channel = vctxt->error; 02041 } else { 02042 channel = vctxt->warning; 02043 } 02044 schannel = vctxt->serror; 02045 data = vctxt->errCtxt; 02046 02047 /* 02048 * Error node. If we specify a line number, then 02049 * do not channel any node to the error function. 02050 */ 02051 if (line == 0) { 02052 if ((node == NULL) && 02053 (vctxt->depth >= 0) && 02054 (vctxt->inode != NULL)) { 02055 node = vctxt->inode->node; 02056 } 02057 /* 02058 * Get filename and line if no node-tree. 02059 */ 02060 if ((node == NULL) && 02061 (vctxt->parserCtxt != NULL) && 02062 (vctxt->parserCtxt->input != NULL)) { 02063 file = vctxt->parserCtxt->input->filename; 02064 line = vctxt->parserCtxt->input->line; 02065 } 02066 } else { 02067 /* 02068 * Override the given node's (if any) position 02069 * and channel only the given line number. 02070 */ 02071 node = NULL; 02072 /* 02073 * Get filename. 02074 */ 02075 if (vctxt->doc != NULL) 02076 file = (const char *) vctxt->doc->URL; 02077 else if ((vctxt->parserCtxt != NULL) && 02078 (vctxt->parserCtxt->input != NULL)) 02079 file = vctxt->parserCtxt->input->filename; 02080 } 02081 __xmlRaiseError(schannel, channel, data, ctxt, 02082 node, XML_FROM_SCHEMASV, 02083 error, errorLevel, file, line, 02084 (const char *) str1, (const char *) str2, 02085 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 02086 02087 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 02088 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 02089 if (errorLevel != XML_ERR_WARNING) { 02090 pctxt->nberrors++; 02091 pctxt->err = error; 02092 channel = pctxt->error; 02093 } else { 02094 channel = pctxt->warning; 02095 } 02096 schannel = pctxt->serror; 02097 data = pctxt->errCtxt; 02098 __xmlRaiseError(schannel, channel, data, ctxt, 02099 node, XML_FROM_SCHEMASP, error, 02100 errorLevel, NULL, 0, 02101 (const char *) str1, (const char *) str2, 02102 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 02103 } else { 02104 TODO 02105 } 02106 } 02107 } 02108 02121 static void 02122 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 02123 int error, xmlNodePtr node, const char *msg, 02124 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 02125 { 02126 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 02127 msg, str1, str2, str3, NULL); 02128 } 02129 02130 static void 02131 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 02132 int error, xmlNodePtr node, const char *msg, 02133 const xmlChar *str1, const xmlChar *str2, 02134 const xmlChar *str3, const xmlChar *str4) 02135 { 02136 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 02137 msg, str1, str2, str3, str4); 02138 } 02139 02140 static void 02141 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 02142 int error, xmlNodePtr node, const char *msg, 02143 const xmlChar *str1, const xmlChar *str2) 02144 { 02145 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 02146 } 02147 02148 static xmlChar * 02149 xmlSchemaFormatNodeForError(xmlChar ** msg, 02150 xmlSchemaAbstractCtxtPtr actxt, 02151 xmlNodePtr node) 02152 { 02153 xmlChar *str = NULL; 02154 02155 *msg = NULL; 02156 if ((node != NULL) && 02157 (node->type != XML_ELEMENT_NODE) && 02158 (node->type != XML_ATTRIBUTE_NODE)) 02159 { 02160 /* 02161 * Don't try to format other nodes than element and 02162 * attribute nodes. 02163 * Play save and return an empty string. 02164 */ 02165 *msg = xmlStrdup(BAD_CAST ""); 02166 return(*msg); 02167 } 02168 if (node != NULL) { 02169 /* 02170 * Work on tree nodes. 02171 */ 02172 if (node->type == XML_ATTRIBUTE_NODE) { 02173 xmlNodePtr elem = node->parent; 02174 02175 *msg = xmlStrdup(BAD_CAST "Element '"); 02176 if (elem->ns != NULL) 02177 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 02178 elem->ns->href, elem->name)); 02179 else 02180 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 02181 NULL, elem->name)); 02182 FREE_AND_NULL(str); 02183 *msg = xmlStrcat(*msg, BAD_CAST "', "); 02184 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 02185 } else { 02186 *msg = xmlStrdup(BAD_CAST "Element '"); 02187 } 02188 if (node->ns != NULL) 02189 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 02190 node->ns->href, node->name)); 02191 else 02192 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 02193 NULL, node->name)); 02194 FREE_AND_NULL(str); 02195 *msg = xmlStrcat(*msg, BAD_CAST "': "); 02196 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 02197 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 02198 /* 02199 * Work on node infos. 02200 */ 02201 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 02202 xmlSchemaNodeInfoPtr ielem = 02203 vctxt->elemInfos[vctxt->depth]; 02204 02205 *msg = xmlStrdup(BAD_CAST "Element '"); 02206 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 02207 ielem->nsName, ielem->localName)); 02208 FREE_AND_NULL(str); 02209 *msg = xmlStrcat(*msg, BAD_CAST "', "); 02210 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 02211 } else { 02212 *msg = xmlStrdup(BAD_CAST "Element '"); 02213 } 02214 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 02215 vctxt->inode->nsName, vctxt->inode->localName)); 02216 FREE_AND_NULL(str); 02217 *msg = xmlStrcat(*msg, BAD_CAST "': "); 02218 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 02219 /* 02220 * Hmm, no node while parsing? 02221 * Return an empty string, in case NULL will break something. 02222 */ 02223 *msg = xmlStrdup(BAD_CAST ""); 02224 } else { 02225 TODO 02226 return (NULL); 02227 } 02228 /* 02229 * VAL TODO: The output of the given schema component is currently 02230 * disabled. 02231 */ 02232 #if 0 02233 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 02234 *msg = xmlStrcat(*msg, BAD_CAST " ["); 02235 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 02236 NULL, type, NULL, 0)); 02237 FREE_AND_NULL(str) 02238 *msg = xmlStrcat(*msg, BAD_CAST "]"); 02239 } 02240 #endif 02241 return (*msg); 02242 } 02243 02244 static void 02245 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 02246 const char *funcName, 02247 const char *message, 02248 const xmlChar *str1, 02249 const xmlChar *str2) 02250 { 02251 xmlChar *msg = NULL; 02252 02253 if (actxt == NULL) 02254 return; 02255 msg = xmlStrdup(BAD_CAST "Internal error: "); 02256 msg = xmlStrcat(msg, BAD_CAST funcName); 02257 msg = xmlStrcat(msg, BAD_CAST ", "); 02258 msg = xmlStrcat(msg, BAD_CAST message); 02259 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02260 02261 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 02262 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL, 02263 (const char *) msg, str1, str2); 02264 02265 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 02266 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL, 02267 (const char *) msg, str1, str2); 02268 02269 FREE_AND_NULL(msg) 02270 } 02271 02272 static void 02273 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 02274 const char *funcName, 02275 const char *message) 02276 { 02277 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 02278 } 02279 02280 #if 0 02281 static void 02282 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 02283 const char *funcName, 02284 const char *message, 02285 const xmlChar *str1, 02286 const xmlChar *str2) 02287 { 02288 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 02289 str1, str2); 02290 } 02291 #endif 02292 02293 static void 02294 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 02295 xmlParserErrors error, 02296 xmlNodePtr node, 02297 xmlSchemaBasicItemPtr item, 02298 const char *message, 02299 const xmlChar *str1, const xmlChar *str2, 02300 const xmlChar *str3, const xmlChar *str4) 02301 { 02302 xmlChar *msg = NULL; 02303 02304 if ((node == NULL) && (item != NULL) && 02305 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 02306 node = WXS_ITEM_NODE(item); 02307 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 02308 msg = xmlStrcat(msg, BAD_CAST ": "); 02309 } else 02310 xmlSchemaFormatNodeForError(&msg, actxt, node); 02311 msg = xmlStrcat(msg, (const xmlChar *) message); 02312 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02313 xmlSchemaErr4(actxt, error, node, 02314 (const char *) msg, str1, str2, str3, str4); 02315 FREE_AND_NULL(msg) 02316 } 02317 02318 static void 02319 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 02320 xmlParserErrors error, 02321 xmlNodePtr node, 02322 xmlSchemaBasicItemPtr item, 02323 const char *message, 02324 const xmlChar *str1, 02325 const xmlChar *str2) 02326 { 02327 xmlSchemaCustomErr4(actxt, error, node, item, 02328 message, str1, str2, NULL, NULL); 02329 } 02330 02331 02332 02333 static void 02334 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 02335 xmlParserErrors error, 02336 xmlNodePtr node, 02337 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 02338 const char *message, 02339 const xmlChar *str1, 02340 const xmlChar *str2, 02341 const xmlChar *str3) 02342 { 02343 xmlChar *msg = NULL; 02344 02345 xmlSchemaFormatNodeForError(&msg, actxt, node); 02346 msg = xmlStrcat(msg, (const xmlChar *) message); 02347 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02348 02349 /* URGENT TODO: Set the error code to something sane. */ 02350 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 02351 (const char *) msg, str1, str2, str3, NULL); 02352 02353 FREE_AND_NULL(msg) 02354 } 02355 02356 02357 02358 static void 02359 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 02360 xmlParserErrors error, 02361 xmlSchemaPSVIIDCNodePtr idcNode, 02362 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 02363 const char *message, 02364 const xmlChar *str1, 02365 const xmlChar *str2) 02366 { 02367 xmlChar *msg = NULL, *qname = NULL; 02368 02369 msg = xmlStrdup(BAD_CAST "Element '%s': "); 02370 msg = xmlStrcat(msg, (const xmlChar *) message); 02371 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02372 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 02373 error, NULL, idcNode->nodeLine, (const char *) msg, 02374 xmlSchemaFormatQName(&qname, 02375 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 02376 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 02377 str1, str2, NULL); 02378 FREE_AND_NULL(qname); 02379 FREE_AND_NULL(msg); 02380 } 02381 02382 static int 02383 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 02384 xmlNodePtr node) 02385 { 02386 if (node != NULL) 02387 return (node->type); 02388 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 02389 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 02390 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 02391 return (-1); 02392 } 02393 02394 static int 02395 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 02396 { 02397 switch (item->type) { 02398 case XML_SCHEMA_TYPE_COMPLEX: 02399 case XML_SCHEMA_TYPE_SIMPLE: 02400 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 02401 return(1); 02402 break; 02403 case XML_SCHEMA_TYPE_GROUP: 02404 return (1); 02405 case XML_SCHEMA_TYPE_ELEMENT: 02406 if ( ((xmlSchemaElementPtr) item)->flags & 02407 XML_SCHEMAS_ELEM_GLOBAL) 02408 return(1); 02409 break; 02410 case XML_SCHEMA_TYPE_ATTRIBUTE: 02411 if ( ((xmlSchemaAttributePtr) item)->flags & 02412 XML_SCHEMAS_ATTR_GLOBAL) 02413 return(1); 02414 break; 02415 /* Note that attribute groups are always global. */ 02416 default: 02417 return(1); 02418 } 02419 return (0); 02420 } 02421 02422 static void 02423 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 02424 xmlParserErrors error, 02425 xmlNodePtr node, 02426 const xmlChar *value, 02427 xmlSchemaTypePtr type, 02428 int displayValue) 02429 { 02430 xmlChar *msg = NULL; 02431 02432 xmlSchemaFormatNodeForError(&msg, actxt, node); 02433 02434 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 02435 XML_ATTRIBUTE_NODE)) 02436 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 02437 else 02438 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 02439 "value of "); 02440 02441 if (! xmlSchemaIsGlobalItem(type)) 02442 msg = xmlStrcat(msg, BAD_CAST "the local "); 02443 else 02444 msg = xmlStrcat(msg, BAD_CAST "the "); 02445 02446 if (WXS_IS_ATOMIC(type)) 02447 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 02448 else if (WXS_IS_LIST(type)) 02449 msg = xmlStrcat(msg, BAD_CAST "list type"); 02450 else if (WXS_IS_UNION(type)) 02451 msg = xmlStrcat(msg, BAD_CAST "union type"); 02452 02453 if (xmlSchemaIsGlobalItem(type)) { 02454 xmlChar *str = NULL; 02455 msg = xmlStrcat(msg, BAD_CAST " '"); 02456 if (type->builtInType != 0) { 02457 msg = xmlStrcat(msg, BAD_CAST "xs:"); 02458 msg = xmlStrcat(msg, type->name); 02459 } else 02460 msg = xmlStrcat(msg, 02461 xmlSchemaFormatQName(&str, 02462 type->targetNamespace, type->name)); 02463 msg = xmlStrcat(msg, BAD_CAST "'"); 02464 FREE_AND_NULL(str); 02465 } 02466 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02467 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 02468 XML_ATTRIBUTE_NODE)) 02469 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 02470 else 02471 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 02472 FREE_AND_NULL(msg) 02473 } 02474 02475 static const xmlChar * 02476 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 02477 xmlSchemaNodeInfoPtr ni, 02478 xmlNodePtr node) 02479 { 02480 if (node != NULL) { 02481 if (node->ns != NULL) 02482 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 02483 else 02484 return (xmlSchemaFormatQName(str, NULL, node->name)); 02485 } else if (ni != NULL) 02486 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 02487 return (NULL); 02488 } 02489 02490 static void 02491 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 02492 xmlParserErrors error, 02493 xmlSchemaAttrInfoPtr ni, 02494 xmlNodePtr node) 02495 { 02496 xmlChar *msg = NULL, *str = NULL; 02497 02498 xmlSchemaFormatNodeForError(&msg, actxt, node); 02499 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 02500 xmlSchemaErr(actxt, error, node, (const char *) msg, 02501 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 02502 NULL); 02503 FREE_AND_NULL(str) 02504 FREE_AND_NULL(msg) 02505 } 02506 02507 static void 02508 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 02509 xmlParserErrors error, 02510 xmlNodePtr node, 02511 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 02512 const char *message, 02513 int nbval, 02514 int nbneg, 02515 xmlChar **values) 02516 { 02517 xmlChar *str = NULL, *msg = NULL; 02518 xmlChar *localName, *nsName; 02519 const xmlChar *cur, *end; 02520 int i; 02521 02522 xmlSchemaFormatNodeForError(&msg, actxt, node); 02523 msg = xmlStrcat(msg, (const xmlChar *) message); 02524 msg = xmlStrcat(msg, BAD_CAST "."); 02525 /* 02526 * Note that is does not make sense to report that we have a 02527 * wildcard here, since the wildcard might be unfolded into 02528 * multiple transitions. 02529 */ 02530 if (nbval + nbneg > 0) { 02531 if (nbval + nbneg > 1) { 02532 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 02533 } else 02534 str = xmlStrdup(BAD_CAST " Expected is ( "); 02535 nsName = NULL; 02536 02537 for (i = 0; i < nbval + nbneg; i++) { 02538 cur = values[i]; 02539 if (cur == NULL) 02540 continue; 02541 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 02542 (cur[3] == ' ')) { 02543 cur += 4; 02544 str = xmlStrcat(str, BAD_CAST "##other"); 02545 } 02546 /* 02547 * Get the local name. 02548 */ 02549 localName = NULL; 02550 02551 end = cur; 02552 if (*end == '*') { 02553 localName = xmlStrdup(BAD_CAST "*"); 02554 end++; 02555 } else { 02556 while ((*end != 0) && (*end != '|')) 02557 end++; 02558 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 02559 } 02560 if (*end != 0) { 02561 end++; 02562 /* 02563 * Skip "*|*" if they come with negated expressions, since 02564 * they represent the same negated wildcard. 02565 */ 02566 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 02567 /* 02568 * Get the namespace name. 02569 */ 02570 cur = end; 02571 if (*end == '*') { 02572 nsName = xmlStrdup(BAD_CAST "{*}"); 02573 } else { 02574 while (*end != 0) 02575 end++; 02576 02577 if (i >= nbval) 02578 nsName = xmlStrdup(BAD_CAST "{##other:"); 02579 else 02580 nsName = xmlStrdup(BAD_CAST "{"); 02581 02582 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 02583 nsName = xmlStrcat(nsName, BAD_CAST "}"); 02584 } 02585 str = xmlStrcat(str, BAD_CAST nsName); 02586 FREE_AND_NULL(nsName) 02587 } else { 02588 FREE_AND_NULL(localName); 02589 continue; 02590 } 02591 } 02592 str = xmlStrcat(str, BAD_CAST localName); 02593 FREE_AND_NULL(localName); 02594 02595 if (i < nbval + nbneg -1) 02596 str = xmlStrcat(str, BAD_CAST ", "); 02597 } 02598 str = xmlStrcat(str, BAD_CAST " ).\n"); 02599 msg = xmlStrcat(msg, BAD_CAST str); 02600 FREE_AND_NULL(str) 02601 } else 02602 msg = xmlStrcat(msg, BAD_CAST "\n"); 02603 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 02604 xmlFree(msg); 02605 } 02606 02607 static void 02608 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 02609 xmlParserErrors error, 02610 xmlNodePtr node, 02611 const xmlChar *value, 02612 unsigned long length, 02613 xmlSchemaTypePtr type, 02614 xmlSchemaFacetPtr facet, 02615 const char *message, 02616 const xmlChar *str1, 02617 const xmlChar *str2) 02618 { 02619 xmlChar *str = NULL, *msg = NULL; 02620 xmlSchemaTypeType facetType; 02621 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 02622 02623 xmlSchemaFormatNodeForError(&msg, actxt, node); 02624 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 02625 facetType = XML_SCHEMA_FACET_ENUMERATION; 02626 /* 02627 * If enumerations are validated, one must not expect the 02628 * facet to be given. 02629 */ 02630 } else 02631 facetType = facet->type; 02632 msg = xmlStrcat(msg, BAD_CAST "["); 02633 msg = xmlStrcat(msg, BAD_CAST "facet '"); 02634 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 02635 msg = xmlStrcat(msg, BAD_CAST "'] "); 02636 if (message == NULL) { 02637 /* 02638 * Use a default message. 02639 */ 02640 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 02641 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 02642 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 02643 02644 char len[25], actLen[25]; 02645 02646 /* FIXME, TODO: What is the max expected string length of the 02647 * this value? 02648 */ 02649 if (nodeType == XML_ATTRIBUTE_NODE) 02650 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 02651 else 02652 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 02653 02654 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 02655 snprintf(actLen, 24, "%lu", length); 02656 02657 if (facetType == XML_SCHEMA_FACET_LENGTH) 02658 msg = xmlStrcat(msg, 02659 BAD_CAST "this differs from the allowed length of '%s'.\n"); 02660 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 02661 msg = xmlStrcat(msg, 02662 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 02663 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 02664 msg = xmlStrcat(msg, 02665 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 02666 02667 if (nodeType == XML_ATTRIBUTE_NODE) 02668 xmlSchemaErr3(actxt, error, node, (const char *) msg, 02669 value, (const xmlChar *) actLen, (const xmlChar *) len); 02670 else 02671 xmlSchemaErr(actxt, error, node, (const char *) msg, 02672 (const xmlChar *) actLen, (const xmlChar *) len); 02673 02674 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 02675 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 02676 "of the set {%s}.\n"); 02677 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 02678 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 02679 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 02680 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 02681 "by the pattern '%s'.\n"); 02682 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 02683 facet->value); 02684 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 02685 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 02686 "minimum value allowed ('%s').\n"); 02687 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 02688 facet->value); 02689 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 02690 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 02691 "maximum value allowed ('%s').\n"); 02692 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 02693 facet->value); 02694 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 02695 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 02696 "'%s'.\n"); 02697 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 02698 facet->value); 02699 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 02700 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 02701 "'%s'.\n"); 02702 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 02703 facet->value); 02704 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 02705 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 02706 "digits than are allowed ('%s').\n"); 02707 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 02708 facet->value); 02709 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 02710 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 02711 "digits than are allowed ('%s').\n"); 02712 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 02713 facet->value); 02714 } else if (nodeType == XML_ATTRIBUTE_NODE) { 02715 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 02716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 02717 } else { 02718 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 02719 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 02720 } 02721 } else { 02722 msg = xmlStrcat(msg, (const xmlChar *) message); 02723 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02724 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 02725 } 02726 FREE_AND_NULL(str) 02727 xmlFree(msg); 02728 } 02729 02730 #define VERROR(err, type, msg) \ 02731 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 02732 02733 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 02734 02735 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 02736 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 02737 02738 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 02739 02740 02753 static void 02754 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 02755 xmlParserErrors error, 02756 xmlSchemaBasicItemPtr ownerItem, 02757 xmlNodePtr ownerElem, 02758 const char *name, 02759 const char *message) 02760 { 02761 xmlChar *des = NULL; 02762 02763 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 02764 02765 if (message != NULL) 02766 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 02767 else 02768 xmlSchemaPErr(ctxt, ownerElem, error, 02769 "%s: The attribute '%s' is required but missing.\n", 02770 BAD_CAST des, BAD_CAST name); 02771 FREE_AND_NULL(des); 02772 } 02773 02774 02790 static void 02791 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 02792 xmlParserErrors error, 02793 xmlSchemaBasicItemPtr ownerItem, 02794 xmlNodePtr ownerElem, 02795 const char *name, 02796 const xmlChar *refName, 02797 const xmlChar *refURI, 02798 xmlSchemaTypeType refType, 02799 const char *refTypeStr) 02800 { 02801 xmlChar *des = NULL, *strA = NULL; 02802 02803 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 02804 if (refTypeStr == NULL) 02805 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 02806 xmlSchemaPErrExt(ctxt, ownerElem, error, 02807 NULL, NULL, NULL, 02808 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 02809 "%s.\n", BAD_CAST des, BAD_CAST name, 02810 xmlSchemaFormatQName(&strA, refURI, refName), 02811 BAD_CAST refTypeStr, NULL); 02812 FREE_AND_NULL(des) 02813 FREE_AND_NULL(strA) 02814 } 02815 02826 static void 02827 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 02828 xmlParserErrors error, 02829 xmlChar **ownerDes, 02830 xmlSchemaBasicItemPtr ownerItem, 02831 xmlAttrPtr attr, 02832 const char *msg) 02833 { 02834 xmlChar *des = NULL; 02835 02836 if (ownerDes == NULL) 02837 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 02838 else if (*ownerDes == NULL) { 02839 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 02840 des = *ownerDes; 02841 } else 02842 des = *ownerDes; 02843 if (attr == NULL) { 02844 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 02845 "%s, attribute '%s': %s.\n", 02846 BAD_CAST des, (const xmlChar *) "Unknown", 02847 (const xmlChar *) msg, NULL, NULL); 02848 } else { 02849 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 02850 "%s, attribute '%s': %s.\n", 02851 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 02852 } 02853 if (ownerDes == NULL) 02854 FREE_AND_NULL(des); 02855 } 02856 02867 static void 02868 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 02869 xmlParserErrors error, 02870 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 02871 xmlAttrPtr attr) 02872 { 02873 xmlChar *strA = NULL, *strB = NULL; 02874 02875 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 02876 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 02877 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 02878 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 02879 NULL, NULL); 02880 FREE_AND_NULL(strA); 02881 FREE_AND_NULL(strB); 02882 } 02883 02898 static void 02899 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 02900 xmlParserErrors error, 02901 xmlSchemaBasicItemPtr item, 02902 xmlNodePtr itemElem, 02903 const char *message, 02904 const xmlChar *str1, 02905 const xmlChar *str2, 02906 const xmlChar *str3) 02907 { 02908 xmlChar *des = NULL, *msg = NULL; 02909 02910 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 02911 msg = xmlStrdup(BAD_CAST "%s: "); 02912 msg = xmlStrcat(msg, (const xmlChar *) message); 02913 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02914 if ((itemElem == NULL) && (item != NULL)) 02915 itemElem = WXS_ITEM_NODE(item); 02916 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 02917 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 02918 FREE_AND_NULL(des); 02919 FREE_AND_NULL(msg); 02920 } 02921 02934 static void 02935 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 02936 xmlParserErrors error, 02937 xmlSchemaBasicItemPtr item, 02938 xmlNodePtr itemElem, 02939 const char *message, 02940 const xmlChar *str1) 02941 { 02942 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 02943 str1, NULL, NULL); 02944 } 02945 02959 static void 02960 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 02961 xmlParserErrors error, 02962 xmlNodePtr node, 02963 xmlSchemaBasicItemPtr ownerItem, 02964 const xmlSchemaAttributeUsePtr attruse, 02965 const char *message, 02966 const xmlChar *str1, const xmlChar *str2, 02967 const xmlChar *str3,const xmlChar *str4) 02968 { 02969 xmlChar *str = NULL, *msg = NULL; 02970 02971 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 02972 msg = xmlStrcat(msg, BAD_CAST ", "); 02973 msg = xmlStrcat(msg, 02974 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 02975 WXS_BASIC_CAST attruse, NULL)); 02976 FREE_AND_NULL(str); 02977 msg = xmlStrcat(msg, BAD_CAST ": "); 02978 msg = xmlStrcat(msg, (const xmlChar *) message); 02979 msg = xmlStrcat(msg, BAD_CAST ".\n"); 02980 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 02981 (const char *) msg, str1, str2, str3, str4); 02982 xmlFree(msg); 02983 } 02984 02995 static void 02996 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 02997 xmlParserErrors error, 02998 xmlSchemaTypePtr type, 02999 xmlSchemaTypePtr baseType, 03000 xmlSchemaFacetPtr facet) 03001 { 03002 xmlChar *des = NULL, *strT = NULL; 03003 03004 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 03005 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 03006 "%s: The facet '%s' is not allowed on types derived from the " 03007 "type %s.\n", 03008 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 03009 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 03010 NULL, NULL); 03011 FREE_AND_NULL(des); 03012 FREE_AND_NULL(strT); 03013 } 03014 03025 static void 03026 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 03027 xmlParserErrors error, 03028 xmlSchemaTypePtr type, 03029 xmlSchemaFacetPtr facet) 03030 { 03031 xmlChar *des = NULL; 03032 03033 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 03034 type->node); 03035 xmlSchemaPErr(ctxt, type->node, error, 03036 "%s: The facet '%s' is not allowed.\n", 03037 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 03038 FREE_AND_NULL(des); 03039 } 03040 03051 static void 03052 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 03053 xmlParserErrors error, 03054 xmlSchemaBasicItemPtr ownerItem, 03055 xmlAttrPtr attr, 03056 const char *name1, 03057 const char *name2) 03058 { 03059 xmlChar *des = NULL; 03060 03061 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 03062 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 03063 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 03064 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 03065 FREE_AND_NULL(des); 03066 } 03067 03081 static void 03082 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 03083 xmlParserErrors error, 03084 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 03085 xmlNodePtr node, 03086 xmlSchemaTypePtr type, 03087 const char *expected, 03088 const xmlChar *value, 03089 const char *message, 03090 const xmlChar *str1, 03091 const xmlChar *str2) 03092 { 03093 xmlChar *msg = NULL; 03094 03095 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 03096 if (message == NULL) { 03097 /* 03098 * Use default messages. 03099 */ 03100 if (type != NULL) { 03101 if (node->type == XML_ATTRIBUTE_NODE) 03102 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 03103 else 03104 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 03105 "valid value of "); 03106 if (! xmlSchemaIsGlobalItem(type)) 03107 msg = xmlStrcat(msg, BAD_CAST "the local "); 03108 else 03109 msg = xmlStrcat(msg, BAD_CAST "the "); 03110 03111 if (WXS_IS_ATOMIC(type)) 03112 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 03113 else if (WXS_IS_LIST(type)) 03114 msg = xmlStrcat(msg, BAD_CAST "list type"); 03115 else if (WXS_IS_UNION(type)) 03116 msg = xmlStrcat(msg, BAD_CAST "union type"); 03117 03118 if (xmlSchemaIsGlobalItem(type)) { 03119 xmlChar *str = NULL; 03120 msg = xmlStrcat(msg, BAD_CAST " '"); 03121 if (type->builtInType != 0) { 03122 msg = xmlStrcat(msg, BAD_CAST "xs:"); 03123 msg = xmlStrcat(msg, type->name); 03124 } else 03125 msg = xmlStrcat(msg, 03126 xmlSchemaFormatQName(&str, 03127 type->targetNamespace, type->name)); 03128 msg = xmlStrcat(msg, BAD_CAST "'."); 03129 FREE_AND_NULL(str); 03130 } 03131 } else { 03132 if (node->type == XML_ATTRIBUTE_NODE) 03133 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 03134 else 03135 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 03136 "valid."); 03137 } 03138 if (expected) { 03139 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 03140 msg = xmlStrcat(msg, BAD_CAST expected); 03141 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 03142 } else 03143 msg = xmlStrcat(msg, BAD_CAST "\n"); 03144 if (node->type == XML_ATTRIBUTE_NODE) 03145 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 03146 else 03147 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 03148 } else { 03149 msg = xmlStrcat(msg, BAD_CAST message); 03150 msg = xmlStrcat(msg, BAD_CAST ".\n"); 03151 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 03152 (const char*) msg, str1, str2, NULL, NULL, NULL); 03153 } 03154 /* Cleanup. */ 03155 FREE_AND_NULL(msg) 03156 } 03157 03171 static void 03172 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 03173 xmlParserErrors error, 03174 xmlSchemaBasicItemPtr ownerItem, 03175 xmlNodePtr ownerElem, 03176 xmlNodePtr child, 03177 const char *message, 03178 const char *content) 03179 { 03180 xmlChar *des = NULL; 03181 03182 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 03183 if (message != NULL) 03184 xmlSchemaPErr2(ctxt, ownerElem, child, error, 03185 "%s: %s.\n", 03186 BAD_CAST des, BAD_CAST message); 03187 else { 03188 if (content != NULL) { 03189 xmlSchemaPErr2(ctxt, ownerElem, child, error, 03190 "%s: The content is not valid. Expected is %s.\n", 03191 BAD_CAST des, BAD_CAST content); 03192 } else { 03193 xmlSchemaPErr2(ctxt, ownerElem, child, error, 03194 "%s: The content is not valid.\n", 03195 BAD_CAST des, NULL); 03196 } 03197 } 03198 FREE_AND_NULL(des) 03199 } 03200 03201 /************************************************************************ 03202 * * 03203 * Streamable error functions * 03204 * * 03205 ************************************************************************/ 03206 03207 03208 03209 03210 /************************************************************************ 03211 * * 03212 * Validation helper functions * 03213 * * 03214 ************************************************************************/ 03215 03216 03217 /************************************************************************ 03218 * * 03219 * Allocation functions * 03220 * * 03221 ************************************************************************/ 03222 03231 static xmlSchemaPtr 03232 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 03233 { 03234 xmlSchemaPtr ret; 03235 03236 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 03237 if (ret == NULL) { 03238 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 03239 return (NULL); 03240 } 03241 memset(ret, 0, sizeof(xmlSchema)); 03242 ret->dict = ctxt->dict; 03243 xmlDictReference(ret->dict); 03244 03245 return (ret); 03246 } 03247 03255 xmlSchemaFacetPtr 03256 xmlSchemaNewFacet(void) 03257 { 03258 xmlSchemaFacetPtr ret; 03259 03260 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 03261 if (ret == NULL) { 03262 return (NULL); 03263 } 03264 memset(ret, 0, sizeof(xmlSchemaFacet)); 03265 03266 return (ret); 03267 } 03268 03278 static xmlSchemaAnnotPtr 03279 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 03280 { 03281 xmlSchemaAnnotPtr ret; 03282 03283 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 03284 if (ret == NULL) { 03285 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 03286 return (NULL); 03287 } 03288 memset(ret, 0, sizeof(xmlSchemaAnnot)); 03289 ret->content = node; 03290 return (ret); 03291 } 03292 03293 static xmlSchemaItemListPtr 03294 xmlSchemaItemListCreate(void) 03295 { 03296 xmlSchemaItemListPtr ret; 03297 03298 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 03299 if (ret == NULL) { 03300 xmlSchemaPErrMemory(NULL, 03301 "allocating an item list structure", NULL); 03302 return (NULL); 03303 } 03304 memset(ret, 0, sizeof(xmlSchemaItemList)); 03305 return (ret); 03306 } 03307 03308 static void 03309 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 03310 { 03311 if (list->items != NULL) { 03312 xmlFree(list->items); 03313 list->items = NULL; 03314 } 03315 list->nbItems = 0; 03316 list->sizeItems = 0; 03317 } 03318 03319 static int 03320 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 03321 { 03322 if (list->items == NULL) { 03323 list->items = (void **) xmlMalloc( 03324 20 * sizeof(void *)); 03325 if (list->items == NULL) { 03326 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 03327 return(-1); 03328 } 03329 list->sizeItems = 20; 03330 } else if (list->sizeItems <= list->nbItems) { 03331 list->sizeItems *= 2; 03332 list->items = (void **) xmlRealloc(list->items, 03333 list->sizeItems * sizeof(void *)); 03334 if (list->items == NULL) { 03335 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 03336 list->sizeItems = 0; 03337 return(-1); 03338 } 03339 } 03340 list->items[list->nbItems++] = item; 03341 return(0); 03342 } 03343 03344 static int 03345 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 03346 int initialSize, 03347 void *item) 03348 { 03349 if (list->items == NULL) { 03350 if (initialSize <= 0) 03351 initialSize = 1; 03352 list->items = (void **) xmlMalloc( 03353 initialSize * sizeof(void *)); 03354 if (list->items == NULL) { 03355 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 03356 return(-1); 03357 } 03358 list->sizeItems = initialSize; 03359 } else if (list->sizeItems <= list->nbItems) { 03360 list->sizeItems *= 2; 03361 list->items = (void **) xmlRealloc(list->items, 03362 list->sizeItems * sizeof(void *)); 03363 if (list->items == NULL) { 03364 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 03365 list->sizeItems = 0; 03366 return(-1); 03367 } 03368 } 03369 list->items[list->nbItems++] = item; 03370 return(0); 03371 } 03372 03373 static int 03374 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 03375 { 03376 if (list->items == NULL) { 03377 list->items = (void **) xmlMalloc( 03378 20 * sizeof(void *)); 03379 if (list->items == NULL) { 03380 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 03381 return(-1); 03382 } 03383 list->sizeItems = 20; 03384 } else if (list->sizeItems <= list->nbItems) { 03385 list->sizeItems *= 2; 03386 list->items = (void **) xmlRealloc(list->items, 03387 list->sizeItems * sizeof(void *)); 03388 if (list->items == NULL) { 03389 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 03390 list->sizeItems = 0; 03391 return(-1); 03392 } 03393 } 03394 /* 03395 * Just append if the index is greater/equal than the item count. 03396 */ 03397 if (idx >= list->nbItems) { 03398 list->items[list->nbItems++] = item; 03399 } else { 03400 int i; 03401 for (i = list->nbItems; i > idx; i--) 03402 list->items[i] = list->items[i-1]; 03403 list->items[idx] = item; 03404 list->nbItems++; 03405 } 03406 return(0); 03407 } 03408 03409 #if 0 /* enable if ever needed */ 03410 static int 03411 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 03412 int initialSize, 03413 void *item, 03414 int idx) 03415 { 03416 if (list->items == NULL) { 03417 if (initialSize <= 0) 03418 initialSize = 1; 03419 list->items = (void **) xmlMalloc( 03420 initialSize * sizeof(void *)); 03421 if (list->items == NULL) { 03422 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 03423 return(-1); 03424 } 03425 list->sizeItems = initialSize; 03426 } else if (list->sizeItems <= list->nbItems) { 03427 list->sizeItems *= 2; 03428 list->items = (void **) xmlRealloc(list->items, 03429 list->sizeItems * sizeof(void *)); 03430 if (list->items == NULL) { 03431 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 03432 list->sizeItems = 0; 03433 return(-1); 03434 } 03435 } 03436 /* 03437 * Just append if the index is greater/equal than the item count. 03438 */ 03439 if (idx >= list->nbItems) { 03440 list->items[list->nbItems++] = item; 03441 } else { 03442 int i; 03443 for (i = list->nbItems; i > idx; i--) 03444 list->items[i] = list->items[i-1]; 03445 list->items[idx] = item; 03446 list->nbItems++; 03447 } 03448 return(0); 03449 } 03450 #endif 03451 03452 static int 03453 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 03454 { 03455 int i; 03456 if ((list->items == NULL) || (idx >= list->nbItems)) { 03457 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 03458 "index error.\n"); 03459 return(-1); 03460 } 03461 03462 if (list->nbItems == 1) { 03463 /* TODO: Really free the list? */ 03464 xmlFree(list->items); 03465 list->items = NULL; 03466 list->nbItems = 0; 03467 list->sizeItems = 0; 03468 } else if (list->nbItems -1 == idx) { 03469 list->nbItems--; 03470 } else { 03471 for (i = idx; i < list->nbItems -1; i++) 03472 list->items[i] = list->items[i+1]; 03473 list->nbItems--; 03474 } 03475 return(0); 03476 } 03477 03484 static void 03485 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 03486 { 03487 if (list == NULL) 03488 return; 03489 if (list->items != NULL) 03490 xmlFree(list->items); 03491 xmlFree(list); 03492 } 03493 03494 static void 03495 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 03496 { 03497 if (bucket == NULL) 03498 return; 03499 if (bucket->globals != NULL) { 03500 xmlSchemaComponentListFree(bucket->globals); 03501 xmlSchemaItemListFree(bucket->globals); 03502 } 03503 if (bucket->locals != NULL) { 03504 xmlSchemaComponentListFree(bucket->locals); 03505 xmlSchemaItemListFree(bucket->locals); 03506 } 03507 if (bucket->relations != NULL) { 03508 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 03509 do { 03510 prev = cur; 03511 cur = cur->next; 03512 xmlFree(prev); 03513 } while (cur != NULL); 03514 } 03515 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 03516 xmlFreeDoc(bucket->doc); 03517 } 03518 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 03519 if (WXS_IMPBUCKET(bucket)->schema != NULL) 03520 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 03521 } 03522 xmlFree(bucket); 03523 } 03524 03525 static xmlSchemaBucketPtr 03526 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 03527 int type, const xmlChar *targetNamespace) 03528 { 03529 xmlSchemaBucketPtr ret; 03530 int size; 03531 xmlSchemaPtr mainSchema; 03532 03533 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 03534 PERROR_INT("xmlSchemaBucketCreate", 03535 "no main schema on constructor"); 03536 return(NULL); 03537 } 03538 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 03539 /* Create the schema bucket. */ 03540 if (WXS_IS_BUCKET_INCREDEF(type)) 03541 size = sizeof(xmlSchemaInclude); 03542 else 03543 size = sizeof(xmlSchemaImport); 03544 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 03545 if (ret == NULL) { 03546 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 03547 return(NULL); 03548 } 03549 memset(ret, 0, size); 03550 ret->targetNamespace = targetNamespace; 03551 ret->type = type; 03552 ret->globals = xmlSchemaItemListCreate(); 03553 if (ret->globals == NULL) { 03554 xmlFree(ret); 03555 return(NULL); 03556 } 03557 ret->locals = xmlSchemaItemListCreate(); 03558 if (ret->locals == NULL) { 03559 xmlFree(ret); 03560 return(NULL); 03561 } 03562 /* 03563 * The following will assure that only the first bucket is marked as 03564 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 03565 * For each following import buckets an xmlSchema will be created. 03566 * An xmlSchema will be created for every distinct targetNamespace. 03567 * We assign the targetNamespace to the schemata here. 03568 */ 03569 if (! WXS_HAS_BUCKETS(pctxt)) { 03570 if (WXS_IS_BUCKET_INCREDEF(type)) { 03571 PERROR_INT("xmlSchemaBucketCreate", 03572 "first bucket but it's an include or redefine"); 03573 xmlSchemaBucketFree(ret); 03574 return(NULL); 03575 } 03576 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 03577 ret->type = XML_SCHEMA_SCHEMA_MAIN; 03578 /* Point to the *main* schema. */ 03579 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 03580 WXS_IMPBUCKET(ret)->schema = mainSchema; 03581 /* 03582 * Ensure that the main schema gets a targetNamespace. 03583 */ 03584 mainSchema->targetNamespace = targetNamespace; 03585 } else { 03586 if (type == XML_SCHEMA_SCHEMA_MAIN) { 03587 PERROR_INT("xmlSchemaBucketCreate", 03588 "main bucket but it's not the first one"); 03589 xmlSchemaBucketFree(ret); 03590 return(NULL); 03591 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 03592 /* 03593 * Create a schema for imports and assign the 03594 * targetNamespace. 03595 */ 03596 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 03597 if (WXS_IMPBUCKET(ret)->schema == NULL) { 03598 xmlSchemaBucketFree(ret); 03599 return(NULL); 03600 } 03601 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 03602 } 03603 } 03604 if (WXS_IS_BUCKET_IMPMAIN(type)) { 03605 int res; 03606 /* 03607 * Imports go into the "schemasImports" slot of the main *schema*. 03608 * Note that we create an import entry for the main schema as well; i.e., 03609 * even if there's only one schema, we'll get an import. 03610 */ 03611 if (mainSchema->schemasImports == NULL) { 03612 mainSchema->schemasImports = xmlHashCreateDict(5, 03613 WXS_CONSTRUCTOR(pctxt)->dict); 03614 if (mainSchema->schemasImports == NULL) { 03615 xmlSchemaBucketFree(ret); 03616 return(NULL); 03617 } 03618 } 03619 if (targetNamespace == NULL) 03620 res = xmlHashAddEntry(mainSchema->schemasImports, 03621 XML_SCHEMAS_NO_NAMESPACE, ret); 03622 else 03623 res = xmlHashAddEntry(mainSchema->schemasImports, 03624 targetNamespace, ret); 03625 if (res != 0) { 03626 PERROR_INT("xmlSchemaBucketCreate", 03627 "failed to add the schema bucket to the hash"); 03628 xmlSchemaBucketFree(ret); 03629 return(NULL); 03630 } 03631 } else { 03632 /* Set the @ownerImport of an include bucket. */ 03633 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 03634 WXS_INCBUCKET(ret)->ownerImport = 03635 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 03636 else 03637 WXS_INCBUCKET(ret)->ownerImport = 03638 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 03639 03640 /* Includes got into the "includes" slot of the *main* schema. */ 03641 if (mainSchema->includes == NULL) { 03642 mainSchema->includes = xmlSchemaItemListCreate(); 03643 if (mainSchema->includes == NULL) { 03644 xmlSchemaBucketFree(ret); 03645 return(NULL); 03646 } 03647 } 03648 xmlSchemaItemListAdd(mainSchema->includes, ret); 03649 } 03650 /* 03651 * Add to list of all buckets; this is used for lookup 03652 * during schema construction time only. 03653 */ 03654 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 03655 return(NULL); 03656 return(ret); 03657 } 03658 03659 static int 03660 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 03661 { 03662 if (*list == NULL) { 03663 *list = xmlSchemaItemListCreate(); 03664 if (*list == NULL) 03665 return(-1); 03666 } 03667 xmlSchemaItemListAddSize(*list, initialSize, item); 03668 return(0); 03669 } 03670 03677 static void 03678 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 03679 { 03680 if (annot == NULL) 03681 return; 03682 if (annot->next == NULL) { 03683 xmlFree(annot); 03684 } else { 03685 xmlSchemaAnnotPtr prev; 03686 03687 do { 03688 prev = annot; 03689 annot = annot->next; 03690 xmlFree(prev); 03691 } while (annot != NULL); 03692 } 03693 } 03694 03701 static void 03702 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 03703 { 03704 if (nota == NULL) 03705 return; 03706 xmlFree(nota); 03707 } 03708 03715 static void 03716 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 03717 { 03718 if (attr == NULL) 03719 return; 03720 if (attr->annot != NULL) 03721 xmlSchemaFreeAnnot(attr->annot); 03722 if (attr->defVal != NULL) 03723 xmlSchemaFreeValue(attr->defVal); 03724 xmlFree(attr); 03725 } 03726 03733 static void 03734 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 03735 { 03736 if (use == NULL) 03737 return; 03738 if (use->annot != NULL) 03739 xmlSchemaFreeAnnot(use->annot); 03740 if (use->defVal != NULL) 03741 xmlSchemaFreeValue(use->defVal); 03742 xmlFree(use); 03743 } 03744 03751 static void 03752 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 03753 { 03754 if (prohib == NULL) 03755 return; 03756 xmlFree(prohib); 03757 } 03758 03765 static void 03766 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 03767 { 03768 xmlSchemaWildcardNsPtr next; 03769 03770 while (set != NULL) { 03771 next = set->next; 03772 xmlFree(set); 03773 set = next; 03774 } 03775 } 03776 03783 void 03784 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 03785 { 03786 if (wildcard == NULL) 03787 return; 03788 if (wildcard->annot != NULL) 03789 xmlSchemaFreeAnnot(wildcard->annot); 03790 if (wildcard->nsSet != NULL) 03791 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 03792 if (wildcard->negNsSet != NULL) 03793 xmlFree(wildcard->negNsSet); 03794 xmlFree(wildcard); 03795 } 03796 03803 static void 03804 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 03805 { 03806 if (attrGr == NULL) 03807 return; 03808 if (attrGr->annot != NULL) 03809 xmlSchemaFreeAnnot(attrGr->annot); 03810 if (attrGr->attrUses != NULL) 03811 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 03812 xmlFree(attrGr); 03813 } 03814 03821 static void 03822 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 03823 { 03824 xmlFree(item); 03825 } 03826 03833 static void 03834 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 03835 { 03836 xmlSchemaTypeLinkPtr next; 03837 03838 while (link != NULL) { 03839 next = link->next; 03840 xmlFree(link); 03841 link = next; 03842 } 03843 } 03844 03845 static void 03846 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 03847 { 03848 xmlSchemaIDCStateObjPtr next; 03849 while (sto != NULL) { 03850 next = sto->next; 03851 if (sto->history != NULL) 03852 xmlFree(sto->history); 03853 if (sto->xpathCtxt != NULL) 03854 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 03855 xmlFree(sto); 03856 sto = next; 03857 } 03858 } 03859 03866 static void 03867 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 03868 { 03869 xmlSchemaIDCSelectPtr cur, prev; 03870 03871 if (idcDef == NULL) 03872 return; 03873 if (idcDef->annot != NULL) 03874 xmlSchemaFreeAnnot(idcDef->annot); 03875 /* Selector */ 03876 if (idcDef->selector != NULL) { 03877 if (idcDef->selector->xpathComp != NULL) 03878 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 03879 xmlFree(idcDef->selector); 03880 } 03881 /* Fields */ 03882 if (idcDef->fields != NULL) { 03883 cur = idcDef->fields; 03884 do { 03885 prev = cur; 03886 cur = cur->next; 03887 if (prev->xpathComp != NULL) 03888 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 03889 xmlFree(prev); 03890 } while (cur != NULL); 03891 } 03892 xmlFree(idcDef); 03893 } 03894 03901 static void 03902 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 03903 { 03904 if (elem == NULL) 03905 return; 03906 if (elem->annot != NULL) 03907 xmlSchemaFreeAnnot(elem->annot); 03908 if (elem->contModel != NULL) 03909 xmlRegFreeRegexp(elem->contModel); 03910 if (elem->defVal != NULL) 03911 xmlSchemaFreeValue(elem->defVal); 03912 xmlFree(elem); 03913 } 03914 03921 void 03922 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 03923 { 03924 if (facet == NULL) 03925 return; 03926 if (facet->val != NULL) 03927 xmlSchemaFreeValue(facet->val); 03928 if (facet->regexp != NULL) 03929 xmlRegFreeRegexp(facet->regexp); 03930 if (facet->annot != NULL) 03931 xmlSchemaFreeAnnot(facet->annot); 03932 xmlFree(facet); 03933 } 03934 03941 void 03942 xmlSchemaFreeType(xmlSchemaTypePtr type) 03943 { 03944 if (type == NULL) 03945 return; 03946 if (type->annot != NULL) 03947 xmlSchemaFreeAnnot(type->annot); 03948 if (type->facets != NULL) { 03949 xmlSchemaFacetPtr facet, next; 03950 03951 facet = type->facets; 03952 while (facet != NULL) { 03953 next = facet->next; 03954 xmlSchemaFreeFacet(facet); 03955 facet = next; 03956 } 03957 } 03958 if (type->attrUses != NULL) 03959 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 03960 if (type->memberTypes != NULL) 03961 xmlSchemaFreeTypeLinkList(type->memberTypes); 03962 if (type->facetSet != NULL) { 03963 xmlSchemaFacetLinkPtr next, link; 03964 03965 link = type->facetSet; 03966 do { 03967 next = link->next; 03968 xmlFree(link); 03969 link = next; 03970 } while (link != NULL); 03971 } 03972 if (type->contModel != NULL) 03973 xmlRegFreeRegexp(type->contModel); 03974 xmlFree(type); 03975 } 03976 03983 static void 03984 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 03985 { 03986 if (item->annot != NULL) 03987 xmlSchemaFreeAnnot(item->annot); 03988 xmlFree(item); 03989 } 03990 03997 static void 03998 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 03999 { 04000 if (item->annot != NULL) 04001 xmlSchemaFreeAnnot(item->annot); 04002 xmlFree(item); 04003 } 04004 04005 static void 04006 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 04007 { 04008 if ((list == NULL) || (list->nbItems == 0)) 04009 return; 04010 { 04011 xmlSchemaTreeItemPtr item; 04012 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 04013 int i; 04014 04015 for (i = 0; i < list->nbItems; i++) { 04016 item = items[i]; 04017 if (item == NULL) 04018 continue; 04019 switch (item->type) { 04020 case XML_SCHEMA_TYPE_SIMPLE: 04021 case XML_SCHEMA_TYPE_COMPLEX: 04022 xmlSchemaFreeType((xmlSchemaTypePtr) item); 04023 break; 04024 case XML_SCHEMA_TYPE_ATTRIBUTE: 04025 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 04026 break; 04027 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 04028 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 04029 break; 04030 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 04031 xmlSchemaFreeAttributeUseProhib( 04032 (xmlSchemaAttributeUseProhibPtr) item); 04033 break; 04034 case XML_SCHEMA_TYPE_ELEMENT: 04035 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 04036 break; 04037 case XML_SCHEMA_TYPE_PARTICLE: 04038 if (item->annot != NULL) 04039 xmlSchemaFreeAnnot(item->annot); 04040 xmlFree(item); 04041 break; 04042 case XML_SCHEMA_TYPE_SEQUENCE: 04043 case XML_SCHEMA_TYPE_CHOICE: 04044 case XML_SCHEMA_TYPE_ALL: 04045 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 04046 break; 04047 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 04048 xmlSchemaFreeAttributeGroup( 04049 (xmlSchemaAttributeGroupPtr) item); 04050 break; 04051 case XML_SCHEMA_TYPE_GROUP: 04052 xmlSchemaFreeModelGroupDef( 04053 (xmlSchemaModelGroupDefPtr) item); 04054 break; 04055 case XML_SCHEMA_TYPE_ANY: 04056 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 04057 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 04058 break; 04059 case XML_SCHEMA_TYPE_IDC_KEY: 04060 case XML_SCHEMA_TYPE_IDC_UNIQUE: 04061 case XML_SCHEMA_TYPE_IDC_KEYREF: 04062 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 04063 break; 04064 case XML_SCHEMA_TYPE_NOTATION: 04065 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 04066 break; 04067 case XML_SCHEMA_EXTRA_QNAMEREF: 04068 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 04069 break; 04070 default: { 04071 /* TODO: This should never be hit. */ 04072 xmlSchemaPSimpleInternalErr(NULL, 04073 "Internal error: xmlSchemaComponentListFree, " 04074 "unexpected component type '%s'\n", 04075 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 04076 } 04077 break; 04078 } 04079 } 04080 list->nbItems = 0; 04081 } 04082 } 04083 04090 void 04091 xmlSchemaFree(xmlSchemaPtr schema) 04092 { 04093 if (schema == NULL) 04094 return; 04095 /* @volatiles is not used anymore :-/ */ 04096 if (schema->volatiles != NULL) 04097 TODO 04098 /* 04099 * Note that those slots are not responsible for freeing 04100 * schema components anymore; this will now be done by 04101 * the schema buckets. 04102 */ 04103 if (schema->notaDecl != NULL) 04104 xmlHashFree(schema->notaDecl, NULL); 04105 if (schema->attrDecl != NULL) 04106 xmlHashFree(schema->attrDecl, NULL); 04107 if (schema->attrgrpDecl != NULL) 04108 xmlHashFree(schema->attrgrpDecl, NULL); 04109 if (schema->elemDecl != NULL) 04110 xmlHashFree(schema->elemDecl, NULL); 04111 if (schema->typeDecl != NULL) 04112 xmlHashFree(schema->typeDecl, NULL); 04113 if (schema->groupDecl != NULL) 04114 xmlHashFree(schema->groupDecl, NULL); 04115 if (schema->idcDef != NULL) 04116 xmlHashFree(schema->idcDef, NULL); 04117 04118 if (schema->schemasImports != NULL) 04119 xmlHashFree(schema->schemasImports, 04120 (xmlHashDeallocator) xmlSchemaBucketFree); 04121 if (schema->includes != NULL) { 04122 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 04123 int i; 04124 for (i = 0; i < list->nbItems; i++) { 04125 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 04126 } 04127 xmlSchemaItemListFree(list); 04128 } 04129 if (schema->annot != NULL) 04130 xmlSchemaFreeAnnot(schema->annot); 04131 /* Never free the doc here, since this will be done by the buckets. */ 04132 04133 xmlDictFree(schema->dict); 04134 xmlFree(schema); 04135 } 04136 04137 /************************************************************************ 04138 * * 04139 * Debug functions * 04140 * * 04141 ************************************************************************/ 04142 04143 #ifdef LIBXML_OUTPUT_ENABLED 04144 04145 static void 04146 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 04147 04155 static void 04156 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 04157 const xmlChar * name ATTRIBUTE_UNUSED, 04158 const xmlChar * namespace ATTRIBUTE_UNUSED, 04159 const xmlChar * context ATTRIBUTE_UNUSED) 04160 { 04161 if (elem == NULL) 04162 return; 04163 04164 04165 fprintf(output, "Element"); 04166 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 04167 fprintf(output, " (global)"); 04168 fprintf(output, ": '%s' ", elem->name); 04169 if (namespace != NULL) 04170 fprintf(output, "ns '%s'", namespace); 04171 fprintf(output, "\n"); 04172 #if 0 04173 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 04174 fprintf(output, " min %d ", elem->minOccurs); 04175 if (elem->maxOccurs >= UNBOUNDED) 04176 fprintf(output, "max: unbounded\n"); 04177 else if (elem->maxOccurs != 1) 04178 fprintf(output, "max: %d\n", elem->maxOccurs); 04179 else 04180 fprintf(output, "\n"); 04181 } 04182 #endif 04183 /* 04184 * Misc other properties. 04185 */ 04186 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 04187 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 04188 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 04189 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 04190 fprintf(output, " props: "); 04191 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 04192 fprintf(output, "[fixed] "); 04193 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 04194 fprintf(output, "[default] "); 04195 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 04196 fprintf(output, "[abstract] "); 04197 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 04198 fprintf(output, "[nillable] "); 04199 fprintf(output, "\n"); 04200 } 04201 /* 04202 * Default/fixed value. 04203 */ 04204 if (elem->value != NULL) 04205 fprintf(output, " value: '%s'\n", elem->value); 04206 /* 04207 * Type. 04208 */ 04209 if (elem->namedType != NULL) { 04210 fprintf(output, " type: '%s' ", elem->namedType); 04211 if (elem->namedTypeNs != NULL) 04212 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 04213 else 04214 fprintf(output, "\n"); 04215 } else if (elem->subtypes != NULL) { 04216 /* 04217 * Dump local types. 04218 */ 04219 xmlSchemaTypeDump(elem->subtypes, output); 04220 } 04221 /* 04222 * Substitution group. 04223 */ 04224 if (elem->substGroup != NULL) { 04225 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 04226 if (elem->substGroupNs != NULL) 04227 fprintf(output, "ns '%s'\n", elem->substGroupNs); 04228 else 04229 fprintf(output, "\n"); 04230 } 04231 } 04232 04240 static void 04241 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 04242 { 04243 xmlChar *content; 04244 04245 if (annot == NULL) 04246 return; 04247 04248 content = xmlNodeGetContent(annot->content); 04249 if (content != NULL) { 04250 fprintf(output, " Annot: %s\n", content); 04251 xmlFree(content); 04252 } else 04253 fprintf(output, " Annot: empty\n"); 04254 } 04255 04264 static void 04265 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 04266 { 04267 xmlChar *str = NULL; 04268 xmlSchemaTreeItemPtr term; 04269 char shift[100]; 04270 int i; 04271 04272 if (particle == NULL) 04273 return; 04274 for (i = 0;((i < depth) && (i < 25));i++) 04275 shift[2 * i] = shift[2 * i + 1] = ' '; 04276 shift[2 * i] = shift[2 * i + 1] = 0; 04277 fprintf(output, "%s", shift); 04278 if (particle->children == NULL) { 04279 fprintf(output, "MISSING particle term\n"); 04280 return; 04281 } 04282 term = particle->children; 04283 if (term == NULL) { 04284 fprintf(output, "(NULL)"); 04285 } else { 04286 switch (term->type) { 04287 case XML_SCHEMA_TYPE_ELEMENT: 04288 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 04289 ((xmlSchemaElementPtr)term)->targetNamespace, 04290 ((xmlSchemaElementPtr)term)->name)); 04291 FREE_AND_NULL(str); 04292 break; 04293 case XML_SCHEMA_TYPE_SEQUENCE: 04294 fprintf(output, "SEQUENCE"); 04295 break; 04296 case XML_SCHEMA_TYPE_CHOICE: 04297 fprintf(output, "CHOICE"); 04298 break; 04299 case XML_SCHEMA_TYPE_ALL: 04300 fprintf(output, "ALL"); 04301 break; 04302 case XML_SCHEMA_TYPE_ANY: 04303 fprintf(output, "ANY"); 04304 break; 04305 default: 04306 fprintf(output, "UNKNOWN\n"); 04307 return; 04308 } 04309 } 04310 if (particle->minOccurs != 1) 04311 fprintf(output, " min: %d", particle->minOccurs); 04312 if (particle->maxOccurs >= UNBOUNDED) 04313 fprintf(output, " max: unbounded"); 04314 else if (particle->maxOccurs != 1) 04315 fprintf(output, " max: %d", particle->maxOccurs); 04316 fprintf(output, "\n"); 04317 if (term && 04318 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 04319 (term->type == XML_SCHEMA_TYPE_CHOICE) || 04320 (term->type == XML_SCHEMA_TYPE_ALL)) && 04321 (term->children != NULL)) { 04322 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 04323 output, depth +1); 04324 } 04325 if (particle->next != NULL) 04326 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 04327 output, depth); 04328 } 04329 04337 static void 04338 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 04339 { 04340 xmlSchemaAttributeUsePtr use; 04341 xmlSchemaAttributeUseProhibPtr prohib; 04342 xmlSchemaQNameRefPtr ref; 04343 const xmlChar *name, *tns; 04344 xmlChar *str = NULL; 04345 int i; 04346 04347 if ((uses == NULL) || (uses->nbItems == 0)) 04348 return; 04349 04350 fprintf(output, " attributes:\n"); 04351 for (i = 0; i < uses->nbItems; i++) { 04352 use = uses->items[i]; 04353 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 04354 fprintf(output, " [prohibition] "); 04355 prohib = (xmlSchemaAttributeUseProhibPtr) use; 04356 name = prohib->name; 04357 tns = prohib->targetNamespace; 04358 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 04359 fprintf(output, " [reference] "); 04360 ref = (xmlSchemaQNameRefPtr) use; 04361 name = ref->name; 04362 tns = ref->targetNamespace; 04363 } else { 04364 fprintf(output, " [use] "); 04365 name = WXS_ATTRUSE_DECL_NAME(use); 04366 tns = WXS_ATTRUSE_DECL_TNS(use); 04367 } 04368 fprintf(output, "'%s'\n", 04369 (const char *) xmlSchemaFormatQName(&str, tns, name)); 04370 FREE_AND_NULL(str); 04371 } 04372 } 04373 04381 static void 04382 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 04383 { 04384 if (type == NULL) { 04385 fprintf(output, "Type: NULL\n"); 04386 return; 04387 } 04388 fprintf(output, "Type: "); 04389 if (type->name != NULL) 04390 fprintf(output, "'%s' ", type->name); 04391 else 04392 fprintf(output, "(no name) "); 04393 if (type->targetNamespace != NULL) 04394 fprintf(output, "ns '%s' ", type->targetNamespace); 04395 switch (type->type) { 04396 case XML_SCHEMA_TYPE_BASIC: 04397 fprintf(output, "[basic] "); 04398 break; 04399 case XML_SCHEMA_TYPE_SIMPLE: 04400 fprintf(output, "[simple] "); 04401 break; 04402 case XML_SCHEMA_TYPE_COMPLEX: 04403 fprintf(output, "[complex] "); 04404 break; 04405 case XML_SCHEMA_TYPE_SEQUENCE: 04406 fprintf(output, "[sequence] "); 04407 break; 04408 case XML_SCHEMA_TYPE_CHOICE: 04409 fprintf(output, "[choice] "); 04410 break; 04411 case XML_SCHEMA_TYPE_ALL: 04412 fprintf(output, "[all] "); 04413 break; 04414 case XML_SCHEMA_TYPE_UR: 04415 fprintf(output, "[ur] "); 04416 break; 04417 case XML_SCHEMA_TYPE_RESTRICTION: 04418 fprintf(output, "[restriction] "); 04419 break; 04420 case XML_SCHEMA_TYPE_EXTENSION: 04421 fprintf(output, "[extension] "); 04422 break; 04423 default: 04424 fprintf(output, "[unknown type %d] ", type->type); 04425 break; 04426 } 04427 fprintf(output, "content: "); 04428 switch (type->contentType) { 04429 case XML_SCHEMA_CONTENT_UNKNOWN: 04430 fprintf(output, "[unknown] "); 04431 break; 04432 case XML_SCHEMA_CONTENT_EMPTY: 04433 fprintf(output, "[empty] "); 04434 break; 04435 case XML_SCHEMA_CONTENT_ELEMENTS: 04436 fprintf(output, "[element] "); 04437 break; 04438 case XML_SCHEMA_CONTENT_MIXED: 04439 fprintf(output, "[mixed] "); 04440 break; 04441 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 04442 /* not used. */ 04443 break; 04444 case XML_SCHEMA_CONTENT_BASIC: 04445 fprintf(output, "[basic] "); 04446 break; 04447 case XML_SCHEMA_CONTENT_SIMPLE: 04448 fprintf(output, "[simple] "); 04449 break; 04450 case XML_SCHEMA_CONTENT_ANY: 04451 fprintf(output, "[any] "); 04452 break; 04453 } 04454 fprintf(output, "\n"); 04455 if (type->base != NULL) { 04456 fprintf(output, " base type: '%s'", type->base); 04457 if (type->baseNs != NULL) 04458 fprintf(output, " ns '%s'\n", type->baseNs); 04459 else 04460 fprintf(output, "\n"); 04461 } 04462 if (type->attrUses != NULL) 04463 xmlSchemaAttrUsesDump(type->attrUses, output); 04464 if (type->annot != NULL) 04465 xmlSchemaAnnotDump(output, type->annot); 04466 #ifdef DUMP_CONTENT_MODEL 04467 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 04468 (type->subtypes != NULL)) { 04469 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 04470 output, 1); 04471 } 04472 #endif 04473 } 04474 04482 void 04483 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 04484 { 04485 if (output == NULL) 04486 return; 04487 if (schema == NULL) { 04488 fprintf(output, "Schemas: NULL\n"); 04489 return; 04490 } 04491 fprintf(output, "Schemas: "); 04492 if (schema->name != NULL) 04493 fprintf(output, "%s, ", schema->name); 04494 else 04495 fprintf(output, "no name, "); 04496 if (schema->targetNamespace != NULL) 04497 fprintf(output, "%s", (const char *) schema->targetNamespace); 04498 else 04499 fprintf(output, "no target namespace"); 04500 fprintf(output, "\n"); 04501 if (schema->annot != NULL) 04502 xmlSchemaAnnotDump(output, schema->annot); 04503 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 04504 output); 04505 xmlHashScanFull(schema->elemDecl, 04506 (xmlHashScannerFull) xmlSchemaElementDump, output); 04507 } 04508 04509 #ifdef DEBUG_IDC_NODE_TABLE 04510 04516 static void 04517 xmlSchemaDebugDumpIDCTable(FILE * output, 04518 const xmlChar *namespaceName, 04519 const xmlChar *localName, 04520 xmlSchemaPSVIIDCBindingPtr bind) 04521 { 04522 xmlChar *str = NULL; 04523 const xmlChar *value; 04524 xmlSchemaPSVIIDCNodePtr tab; 04525 xmlSchemaPSVIIDCKeyPtr key; 04526 int i, j, res; 04527 04528 fprintf(output, "IDC: TABLES on '%s'\n", 04529 xmlSchemaFormatQName(&str, namespaceName, localName)); 04530 FREE_AND_NULL(str) 04531 04532 if (bind == NULL) 04533 return; 04534 do { 04535 fprintf(output, "IDC: BINDING '%s' (%d)\n", 04536 xmlSchemaGetComponentQName(&str, 04537 bind->definition), bind->nbNodes); 04538 FREE_AND_NULL(str) 04539 for (i = 0; i < bind->nbNodes; i++) { 04540 tab = bind->nodeTable[i]; 04541 fprintf(output, " ( "); 04542 for (j = 0; j < bind->definition->nbFields; j++) { 04543 key = tab->keys[j]; 04544 if ((key != NULL) && (key->val != NULL)) { 04545 res = xmlSchemaGetCanonValue(key->val, &value); 04546 if (res >= 0) 04547 fprintf(output, "'%s' ", value); 04548 else 04549 fprintf(output, "CANON-VALUE-FAILED "); 04550 if (res == 0) 04551 FREE_AND_NULL(value) 04552 } else if (key != NULL) 04553 fprintf(output, "(no val), "); 04554 else 04555 fprintf(output, "(key missing), "); 04556 } 04557 fprintf(output, ")\n"); 04558 } 04559 if (bind->dupls && bind->dupls->nbItems) { 04560 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 04561 for (i = 0; i < bind->dupls->nbItems; i++) { 04562 tab = bind->dupls->items[i]; 04563 fprintf(output, " ( "); 04564 for (j = 0; j < bind->definition->nbFields; j++) { 04565 key = tab->keys[j]; 04566 if ((key != NULL) && (key->val != NULL)) { 04567 res = xmlSchemaGetCanonValue(key->val, &value); 04568 if (res >= 0) 04569 fprintf(output, "'%s' ", value); 04570 else 04571 fprintf(output, "CANON-VALUE-FAILED "); 04572 if (res == 0) 04573 FREE_AND_NULL(value) 04574 } else if (key != NULL) 04575 fprintf(output, "(no val), "); 04576 else 04577 fprintf(output, "(key missing), "); 04578 } 04579 fprintf(output, ")\n"); 04580 } 04581 } 04582 bind = bind->next; 04583 } while (bind != NULL); 04584 } 04585 #endif /* DEBUG_IDC */ 04586 #endif /* LIBXML_OUTPUT_ENABLED */ 04587 04588 /************************************************************************ 04589 * * 04590 * Utilities * 04591 * * 04592 ************************************************************************/ 04593 04604 static xmlAttrPtr 04605 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 04606 { 04607 xmlAttrPtr prop; 04608 04609 if ((node == NULL) || (name == NULL)) 04610 return(NULL); 04611 prop = node->properties; 04612 while (prop != NULL) { 04613 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 04614 return(prop); 04615 prop = prop->next; 04616 } 04617 return (NULL); 04618 } 04619 04631 static xmlAttrPtr 04632 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 04633 { 04634 xmlAttrPtr prop; 04635 04636 if ((node == NULL) || (name == NULL)) 04637 return(NULL); 04638 prop = node->properties; 04639 while (prop != NULL) { 04640 if ((prop->ns != NULL) && 04641 xmlStrEqual(prop->name, BAD_CAST name) && 04642 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 04643 return(prop); 04644 prop = prop->next; 04645 } 04646 return (NULL); 04647 } 04648 04649 static const xmlChar * 04650 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 04651 { 04652 xmlChar *val; 04653 const xmlChar *ret; 04654 04655 val = xmlNodeGetContent(node); 04656 if (val == NULL) 04657 val = xmlStrdup((xmlChar *)""); 04658 ret = xmlDictLookup(ctxt->dict, val, -1); 04659 xmlFree(val); 04660 return(ret); 04661 } 04662 04663 static const xmlChar * 04664 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 04665 { 04666 return((const xmlChar*) xmlNodeGetContent(node)); 04667 } 04668 04679 static const xmlChar * 04680 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 04681 const char *name) 04682 { 04683 xmlChar *val; 04684 const xmlChar *ret; 04685 04686 val = xmlGetNoNsProp(node, BAD_CAST name); 04687 if (val == NULL) 04688 return(NULL); 04689 ret = xmlDictLookup(ctxt->dict, val, -1); 04690 xmlFree(val); 04691 return(ret); 04692 } 04693 04694 /************************************************************************ 04695 * * 04696 * Parsing functions * 04697 * * 04698 ************************************************************************/ 04699 04700 #define WXS_FIND_GLOBAL_ITEM(slot) \ 04701 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 04702 ret = xmlHashLookup(schema->slot, name); \ 04703 if (ret != NULL) goto exit; \ 04704 } \ 04705 if (xmlHashSize(schema->schemasImports) > 1) { \ 04706 xmlSchemaImportPtr import; \ 04707 if (nsName == NULL) \ 04708 import = xmlHashLookup(schema->schemasImports, \ 04709 XML_SCHEMAS_NO_NAMESPACE); \ 04710 else \ 04711 import = xmlHashLookup(schema->schemasImports, nsName); \ 04712 if (import == NULL) \ 04713 goto exit; \ 04714 ret = xmlHashLookup(import->schema->slot, name); \ 04715 } 04716 04727 static xmlSchemaElementPtr 04728 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 04729 const xmlChar * nsName) 04730 { 04731 xmlSchemaElementPtr ret = NULL; 04732 04733 if ((name == NULL) || (schema == NULL)) 04734 return(NULL); 04735 if (schema != NULL) { 04736 WXS_FIND_GLOBAL_ITEM(elemDecl) 04737 } 04738 exit: 04739 #ifdef DEBUG 04740 if (ret == NULL) { 04741 if (nsName == NULL) 04742 fprintf(stderr, "Unable to lookup element decl. %s", name); 04743 else 04744 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 04745 nsName); 04746 } 04747 #endif 04748 return (ret); 04749 } 04750 04761 static xmlSchemaTypePtr 04762 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 04763 const xmlChar * nsName) 04764 { 04765 xmlSchemaTypePtr ret = NULL; 04766 04767 if (name == NULL) 04768 return (NULL); 04769 /* First try the built-in types. */ 04770 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 04771 ret = xmlSchemaGetPredefinedType(name, nsName); 04772 if (ret != NULL) 04773 goto exit; 04774 /* 04775 * Note that we try the parsed schemas as well here 04776 * since one might have parsed the S4S, which contain more 04777 * than the built-in types. 04778 * TODO: Can we optimize this? 04779 */ 04780 } 04781 if (schema != NULL) { 04782 WXS_FIND_GLOBAL_ITEM(typeDecl) 04783 } 04784 exit: 04785 04786 #ifdef DEBUG 04787 if (ret == NULL) { 04788 if (nsName == NULL) 04789 fprintf(stderr, "Unable to lookup type %s", name); 04790 else 04791 fprintf(stderr, "Unable to lookup type %s:%s", name, 04792 nsName); 04793 } 04794 #endif 04795 return (ret); 04796 } 04797 04808 static xmlSchemaAttributePtr 04809 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 04810 const xmlChar * nsName) 04811 { 04812 xmlSchemaAttributePtr ret = NULL; 04813 04814 if ((name == NULL) || (schema == NULL)) 04815 return (NULL); 04816 if (schema != NULL) { 04817 WXS_FIND_GLOBAL_ITEM(attrDecl) 04818 } 04819 exit: 04820 #ifdef DEBUG 04821 if (ret == NULL) { 04822 if (nsName == NULL) 04823 fprintf(stderr, "Unable to lookup attribute %s", name); 04824 else 04825 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 04826 nsName); 04827 } 04828 #endif 04829 return (ret); 04830 } 04831 04842 static xmlSchemaAttributeGroupPtr 04843 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 04844 const xmlChar * nsName) 04845 { 04846 xmlSchemaAttributeGroupPtr ret = NULL; 04847 04848 if ((name == NULL) || (schema == NULL)) 04849 return (NULL); 04850 if (schema != NULL) { 04851 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 04852 } 04853 exit: 04854 /* TODO: 04855 if ((ret != NULL) && (ret->redef != NULL)) { 04856 * Return the last redefinition. * 04857 ret = ret->redef; 04858 } 04859 */ 04860 #ifdef DEBUG 04861 if (ret == NULL) { 04862 if (nsName == NULL) 04863 fprintf(stderr, "Unable to lookup attribute group %s", name); 04864 else 04865 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 04866 nsName); 04867 } 04868 #endif 04869 return (ret); 04870 } 04871 04882 static xmlSchemaModelGroupDefPtr 04883 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 04884 const xmlChar * nsName) 04885 { 04886 xmlSchemaModelGroupDefPtr ret = NULL; 04887 04888 if ((name == NULL) || (schema == NULL)) 04889 return (NULL); 04890 if (schema != NULL) { 04891 WXS_FIND_GLOBAL_ITEM(groupDecl) 04892 } 04893 exit: 04894 04895 #ifdef DEBUG 04896 if (ret == NULL) { 04897 if (nsName == NULL) 04898 fprintf(stderr, "Unable to lookup group %s", name); 04899 else 04900 fprintf(stderr, "Unable to lookup group %s:%s", name, 04901 nsName); 04902 } 04903 #endif 04904 return (ret); 04905 } 04906 04907 static xmlSchemaNotationPtr 04908 xmlSchemaGetNotation(xmlSchemaPtr schema, 04909 const xmlChar *name, 04910 const xmlChar *nsName) 04911 { 04912 xmlSchemaNotationPtr ret = NULL; 04913 04914 if ((name == NULL) || (schema == NULL)) 04915 return (NULL); 04916 if (schema != NULL) { 04917 WXS_FIND_GLOBAL_ITEM(notaDecl) 04918 } 04919 exit: 04920 return (ret); 04921 } 04922 04923 static xmlSchemaIDCPtr 04924 xmlSchemaGetIDC(xmlSchemaPtr schema, 04925 const xmlChar *name, 04926 const xmlChar *nsName) 04927 { 04928 xmlSchemaIDCPtr ret = NULL; 04929 04930 if ((name == NULL) || (schema == NULL)) 04931 return (NULL); 04932 if (schema != NULL) { 04933 WXS_FIND_GLOBAL_ITEM(idcDef) 04934 } 04935 exit: 04936 return (ret); 04937 } 04938 04949 static xmlSchemaBasicItemPtr 04950 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 04951 xmlSchemaTypeType itemType, 04952 const xmlChar *name, 04953 const xmlChar *targetNs) 04954 { 04955 switch (itemType) { 04956 case XML_SCHEMA_TYPE_GROUP: 04957 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 04958 name, targetNs)); 04959 case XML_SCHEMA_TYPE_ELEMENT: 04960 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 04961 name, targetNs)); 04962 default: 04963 TODO 04964 return (NULL); 04965 } 04966 } 04967 04968 /************************************************************************ 04969 * * 04970 * Parsing functions * 04971 * * 04972 ************************************************************************/ 04973 04974 #define IS_BLANK_NODE(n) \ 04975 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 04976 04986 static int 04987 xmlSchemaIsBlank(xmlChar * str, int len) 04988 { 04989 if (str == NULL) 04990 return (1); 04991 if (len < 0) { 04992 while (*str != 0) { 04993 if (!(IS_BLANK_CH(*str))) 04994 return (0); 04995 str++; 04996 } 04997 } else while ((*str != 0) && (len != 0)) { 04998 if (!(IS_BLANK_CH(*str))) 04999 return (0); 05000 str++; 05001 len--; 05002 } 05003 05004 return (1); 05005 } 05006 05007 #define WXS_COMP_NAME(c, t) ((t) (c))->name 05008 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 05009 /* 05010 * xmlSchemaFindRedefCompInGraph: 05011 * ATTENTION TODO: This uses pointer comp. for strings. 05012 */ 05013 static xmlSchemaBasicItemPtr 05014 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 05015 xmlSchemaTypeType type, 05016 const xmlChar *name, 05017 const xmlChar *nsName) 05018 { 05019 xmlSchemaBasicItemPtr ret; 05020 int i; 05021 05022 if ((bucket == NULL) || (name == NULL)) 05023 return(NULL); 05024 if ((bucket->globals == NULL) || 05025 (bucket->globals->nbItems == 0)) 05026 goto subschemas; 05027 /* 05028 * Search in global components. 05029 */ 05030 for (i = 0; i < bucket->globals->nbItems; i++) { 05031 ret = bucket->globals->items[i]; 05032 if (ret->type == type) { 05033 switch (type) { 05034 case XML_SCHEMA_TYPE_COMPLEX: 05035 case XML_SCHEMA_TYPE_SIMPLE: 05036 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 05037 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 05038 nsName)) 05039 { 05040 return(ret); 05041 } 05042 break; 05043 case XML_SCHEMA_TYPE_GROUP: 05044 if ((WXS_COMP_NAME(ret, 05045 xmlSchemaModelGroupDefPtr) == name) && 05046 (WXS_COMP_TNS(ret, 05047 xmlSchemaModelGroupDefPtr) == nsName)) 05048 { 05049 return(ret); 05050 } 05051 break; 05052 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 05053 if ((WXS_COMP_NAME(ret, 05054 xmlSchemaAttributeGroupPtr) == name) && 05055 (WXS_COMP_TNS(ret, 05056 xmlSchemaAttributeGroupPtr) == nsName)) 05057 { 05058 return(ret); 05059 } 05060 break; 05061 default: 05062 /* Should not be hit. */ 05063 return(NULL); 05064 } 05065 } 05066 } 05067 subschemas: 05068 /* 05069 * Process imported/included schemas. 05070 */ 05071 if (bucket->relations != NULL) { 05072 xmlSchemaSchemaRelationPtr rel = bucket->relations; 05073 05074 /* 05075 * TODO: Marking the bucket will not avoid multiple searches 05076 * in the same schema, but avoids at least circularity. 05077 */ 05078 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 05079 do { 05080 if ((rel->bucket != NULL) && 05081 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 05082 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 05083 type, name, nsName); 05084 if (ret != NULL) 05085 return(ret); 05086 } 05087 rel = rel->next; 05088 } while (rel != NULL); 05089 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 05090 } 05091 return(NULL); 05092 } 05093 05105 static xmlSchemaNotationPtr 05106 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 05107 const xmlChar *name, const xmlChar *nsName, 05108 xmlNodePtr node ATTRIBUTE_UNUSED) 05109 { 05110 xmlSchemaNotationPtr ret = NULL; 05111 05112 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 05113 return (NULL); 05114 05115 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 05116 if (ret == NULL) { 05117 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 05118 return (NULL); 05119 } 05120 memset(ret, 0, sizeof(xmlSchemaNotation)); 05121 ret->type = XML_SCHEMA_TYPE_NOTATION; 05122 ret->name = name; 05123 ret->targetNamespace = nsName; 05124 /* TODO: do we need the node to be set? 05125 * ret->node = node;*/ 05126 WXS_ADD_GLOBAL(ctxt, ret); 05127 return (ret); 05128 } 05129 05142 static xmlSchemaAttributePtr 05143 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 05144 const xmlChar * name, const xmlChar * nsName, 05145 xmlNodePtr node, int topLevel) 05146 { 05147 xmlSchemaAttributePtr ret = NULL; 05148 05149 if ((ctxt == NULL) || (schema == NULL)) 05150 return (NULL); 05151 05152 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 05153 if (ret == NULL) { 05154 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 05155 return (NULL); 05156 } 05157 memset(ret, 0, sizeof(xmlSchemaAttribute)); 05158 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 05159 ret->node = node; 05160 ret->name = name; 05161 ret->targetNamespace = nsName; 05162 05163 if (topLevel) 05164 WXS_ADD_GLOBAL(ctxt, ret); 05165 else 05166 WXS_ADD_LOCAL(ctxt, ret); 05167 WXS_ADD_PENDING(ctxt, ret); 05168 return (ret); 05169 } 05170 05183 static xmlSchemaAttributeUsePtr 05184 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 05185 xmlNodePtr node) 05186 { 05187 xmlSchemaAttributeUsePtr ret = NULL; 05188 05189 if (pctxt == NULL) 05190 return (NULL); 05191 05192 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 05193 if (ret == NULL) { 05194 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 05195 return (NULL); 05196 } 05197 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 05198 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 05199 ret->node = node; 05200 05201 WXS_ADD_LOCAL(pctxt, ret); 05202 return (ret); 05203 } 05204 05205 /* 05206 * xmlSchemaAddRedef: 05207 * 05208 * Adds a redefinition information. This is used at a later stage to: 05209 * resolve references to the redefined components and to check constraints. 05210 */ 05211 static xmlSchemaRedefPtr 05212 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 05213 xmlSchemaBucketPtr targetBucket, 05214 void *item, 05215 const xmlChar *refName, 05216 const xmlChar *refTargetNs) 05217 { 05218 xmlSchemaRedefPtr ret; 05219 05220 ret = (xmlSchemaRedefPtr) 05221 xmlMalloc(sizeof(xmlSchemaRedef)); 05222 if (ret == NULL) { 05223 xmlSchemaPErrMemory(pctxt, 05224 "allocating redefinition info", NULL); 05225 return (NULL); 05226 } 05227 memset(ret, 0, sizeof(xmlSchemaRedef)); 05228 ret->item = item; 05229 ret->targetBucket = targetBucket; 05230 ret->refName = refName; 05231 ret->refTargetNs = refTargetNs; 05232 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 05233 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 05234 else 05235 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 05236 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 05237 05238 return (ret); 05239 } 05240 05253 static xmlSchemaAttributeGroupPtr 05254 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 05255 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 05256 const xmlChar *name, 05257 const xmlChar *nsName, 05258 xmlNodePtr node) 05259 { 05260 xmlSchemaAttributeGroupPtr ret = NULL; 05261 05262 if ((pctxt == NULL) || (name == NULL)) 05263 return (NULL); 05264 05265 ret = (xmlSchemaAttributeGroupPtr) 05266 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 05267 if (ret == NULL) { 05268 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 05269 return (NULL); 05270 } 05271 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 05272 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 05273 ret->name = name; 05274 ret->targetNamespace = nsName; 05275 ret->node = node; 05276 05277 /* TODO: Remove the flag. */ 05278 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 05279 if (pctxt->isRedefine) { 05280 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 05281 ret, name, nsName); 05282 if (pctxt->redef == NULL) { 05283 xmlFree(ret); 05284 return(NULL); 05285 } 05286 pctxt->redefCounter = 0; 05287 } 05288 WXS_ADD_GLOBAL(pctxt, ret); 05289 WXS_ADD_PENDING(pctxt, ret); 05290 return (ret); 05291 } 05292 05305 static xmlSchemaElementPtr 05306 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 05307 const xmlChar * name, const xmlChar * nsName, 05308 xmlNodePtr node, int topLevel) 05309 { 05310 xmlSchemaElementPtr ret = NULL; 05311 05312 if ((ctxt == NULL) || (name == NULL)) 05313 return (NULL); 05314 05315 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 05316 if (ret == NULL) { 05317 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 05318 return (NULL); 05319 } 05320 memset(ret, 0, sizeof(xmlSchemaElement)); 05321 ret->type = XML_SCHEMA_TYPE_ELEMENT; 05322 ret->name = name; 05323 ret->targetNamespace = nsName; 05324 ret->node = node; 05325 05326 if (topLevel) 05327 WXS_ADD_GLOBAL(ctxt, ret); 05328 else 05329 WXS_ADD_LOCAL(ctxt, ret); 05330 WXS_ADD_PENDING(ctxt, ret); 05331 return (ret); 05332 } 05333 05346 static xmlSchemaTypePtr 05347 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 05348 xmlSchemaTypeType type, 05349 const xmlChar * name, const xmlChar * nsName, 05350 xmlNodePtr node, int topLevel) 05351 { 05352 xmlSchemaTypePtr ret = NULL; 05353 05354 if ((ctxt == NULL) || (schema == NULL)) 05355 return (NULL); 05356 05357 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 05358 if (ret == NULL) { 05359 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 05360 return (NULL); 05361 } 05362 memset(ret, 0, sizeof(xmlSchemaType)); 05363 ret->type = type; 05364 ret->name = name; 05365 ret->targetNamespace = nsName; 05366 ret->node = node; 05367 if (topLevel) { 05368 if (ctxt->isRedefine) { 05369 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 05370 ret, name, nsName); 05371 if (ctxt->redef == NULL) { 05372 xmlFree(ret); 05373 return(NULL); 05374 } 05375 ctxt->redefCounter = 0; 05376 } 05377 WXS_ADD_GLOBAL(ctxt, ret); 05378 } else 05379 WXS_ADD_LOCAL(ctxt, ret); 05380 WXS_ADD_PENDING(ctxt, ret); 05381 return (ret); 05382 } 05383 05384 static xmlSchemaQNameRefPtr 05385 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 05386 xmlSchemaTypeType refType, 05387 const xmlChar *refName, 05388 const xmlChar *refNs) 05389 { 05390 xmlSchemaQNameRefPtr ret; 05391 05392 ret = (xmlSchemaQNameRefPtr) 05393 xmlMalloc(sizeof(xmlSchemaQNameRef)); 05394 if (ret == NULL) { 05395 xmlSchemaPErrMemory(pctxt, 05396 "allocating QName reference item", NULL); 05397 return (NULL); 05398 } 05399 ret->node = NULL; 05400 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 05401 ret->name = refName; 05402 ret->targetNamespace = refNs; 05403 ret->item = NULL; 05404 ret->itemType = refType; 05405 /* 05406 * Store the reference item in the schema. 05407 */ 05408 WXS_ADD_LOCAL(pctxt, ret); 05409 return (ret); 05410 } 05411 05412 static xmlSchemaAttributeUseProhibPtr 05413 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 05414 { 05415 xmlSchemaAttributeUseProhibPtr ret; 05416 05417 ret = (xmlSchemaAttributeUseProhibPtr) 05418 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 05419 if (ret == NULL) { 05420 xmlSchemaPErrMemory(pctxt, 05421 "allocating attribute use prohibition", NULL); 05422 return (NULL); 05423 } 05424 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 05425 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 05426 WXS_ADD_LOCAL(pctxt, ret); 05427 return (ret); 05428 } 05429 05430 05443 static xmlSchemaModelGroupPtr 05444 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 05445 xmlSchemaPtr schema, 05446 xmlSchemaTypeType type, 05447 xmlNodePtr node) 05448 { 05449 xmlSchemaModelGroupPtr ret = NULL; 05450 05451 if ((ctxt == NULL) || (schema == NULL)) 05452 return (NULL); 05453 05454 ret = (xmlSchemaModelGroupPtr) 05455 xmlMalloc(sizeof(xmlSchemaModelGroup)); 05456 if (ret == NULL) { 05457 xmlSchemaPErrMemory(ctxt, "allocating model group component", 05458 NULL); 05459 return (NULL); 05460 } 05461 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 05462 ret->type = type; 05463 ret->node = node; 05464 WXS_ADD_LOCAL(ctxt, ret); 05465 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 05466 (type == XML_SCHEMA_TYPE_CHOICE)) 05467 WXS_ADD_PENDING(ctxt, ret); 05468 return (ret); 05469 } 05470 05471 05485 static xmlSchemaParticlePtr 05486 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 05487 xmlNodePtr node, int min, int max) 05488 { 05489 xmlSchemaParticlePtr ret = NULL; 05490 if (ctxt == NULL) 05491 return (NULL); 05492 05493 #ifdef DEBUG 05494 fprintf(stderr, "Adding particle component\n"); 05495 #endif 05496 ret = (xmlSchemaParticlePtr) 05497 xmlMalloc(sizeof(xmlSchemaParticle)); 05498 if (ret == NULL) { 05499 xmlSchemaPErrMemory(ctxt, "allocating particle component", 05500 NULL); 05501 return (NULL); 05502 } 05503 ret->type = XML_SCHEMA_TYPE_PARTICLE; 05504 ret->annot = NULL; 05505 ret->node = node; 05506 ret->minOccurs = min; 05507 ret->maxOccurs = max; 05508 ret->next = NULL; 05509 ret->children = NULL; 05510 05511 WXS_ADD_LOCAL(ctxt, ret); 05512 /* 05513 * Note that addition to pending components will be done locally 05514 * to the specific parsing function, since the most particles 05515 * need not to be fixed up (i.e. the reference to be resolved). 05516 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 05517 */ 05518 return (ret); 05519 } 05520 05531 static xmlSchemaModelGroupDefPtr 05532 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 05533 xmlSchemaPtr schema, 05534 const xmlChar *name, 05535 const xmlChar *nsName, 05536 xmlNodePtr node) 05537 { 05538 xmlSchemaModelGroupDefPtr ret = NULL; 05539 05540 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 05541 return (NULL); 05542 05543 ret = (xmlSchemaModelGroupDefPtr) 05544 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 05545 if (ret == NULL) { 05546 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 05547 return (NULL); 05548 } 05549 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 05550 ret->name = name; 05551 ret->type = XML_SCHEMA_TYPE_GROUP; 05552 ret->node = node; 05553 ret->targetNamespace = nsName; 05554 05555 if (ctxt->isRedefine) { 05556 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 05557 ret, name, nsName); 05558 if (ctxt->redef == NULL) { 05559 xmlFree(ret); 05560 return(NULL); 05561 } 05562 ctxt->redefCounter = 0; 05563 } 05564 WXS_ADD_GLOBAL(ctxt, ret); 05565 WXS_ADD_PENDING(ctxt, ret); 05566 return (ret); 05567 } 05568 05577 static xmlSchemaWildcardNsPtr 05578 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 05579 { 05580 xmlSchemaWildcardNsPtr ret; 05581 05582 ret = (xmlSchemaWildcardNsPtr) 05583 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 05584 if (ret == NULL) { 05585 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 05586 return (NULL); 05587 } 05588 ret->value = NULL; 05589 ret->next = NULL; 05590 return (ret); 05591 } 05592 05593 static xmlSchemaIDCPtr 05594 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 05595 const xmlChar *name, const xmlChar *nsName, 05596 int category, xmlNodePtr node) 05597 { 05598 xmlSchemaIDCPtr ret = NULL; 05599 05600 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 05601 return (NULL); 05602 05603 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 05604 if (ret == NULL) { 05605 xmlSchemaPErrMemory(ctxt, 05606 "allocating an identity-constraint definition", NULL); 05607 return (NULL); 05608 } 05609 memset(ret, 0, sizeof(xmlSchemaIDC)); 05610 /* The target namespace of the parent element declaration. */ 05611 ret->targetNamespace = nsName; 05612 ret->name = name; 05613 ret->type = category; 05614 ret->node = node; 05615 05616 WXS_ADD_GLOBAL(ctxt, ret); 05617 /* 05618 * Only keyrefs need to be fixup up. 05619 */ 05620 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 05621 WXS_ADD_PENDING(ctxt, ret); 05622 return (ret); 05623 } 05624 05635 static xmlSchemaWildcardPtr 05636 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 05637 xmlSchemaTypeType type, xmlNodePtr node) 05638 { 05639 xmlSchemaWildcardPtr ret = NULL; 05640 05641 if ((ctxt == NULL) || (schema == NULL)) 05642 return (NULL); 05643 05644 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 05645 if (ret == NULL) { 05646 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 05647 return (NULL); 05648 } 05649 memset(ret, 0, sizeof(xmlSchemaWildcard)); 05650 ret->type = type; 05651 ret->node = node; 05652 WXS_ADD_LOCAL(ctxt, ret); 05653 return (ret); 05654 } 05655 05656 static void 05657 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 05658 { 05659 if (group == NULL) 05660 return; 05661 if (group->members != NULL) 05662 xmlSchemaItemListFree(group->members); 05663 xmlFree(group); 05664 } 05665 05666 static xmlSchemaSubstGroupPtr 05667 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 05668 xmlSchemaElementPtr head) 05669 { 05670 xmlSchemaSubstGroupPtr ret; 05671 05672 /* Init subst group hash. */ 05673 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 05674 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 05675 if (WXS_SUBST_GROUPS(pctxt) == NULL) 05676 return(NULL); 05677 } 05678 /* Create a new substitution group. */ 05679 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 05680 if (ret == NULL) { 05681 xmlSchemaPErrMemory(NULL, 05682 "allocating a substitution group container", NULL); 05683 return(NULL); 05684 } 05685 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 05686 ret->head = head; 05687 /* Create list of members. */ 05688 ret->members = xmlSchemaItemListCreate(); 05689 if (ret->members == NULL) { 05690 xmlSchemaSubstGroupFree(ret); 05691 return(NULL); 05692 } 05693 /* Add subst group to hash. */ 05694 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 05695 head->name, head->targetNamespace, ret) != 0) { 05696 PERROR_INT("xmlSchemaSubstGroupAdd", 05697 "failed to add a new substitution container"); 05698 xmlSchemaSubstGroupFree(ret); 05699 return(NULL); 05700 } 05701 return(ret); 05702 } 05703 05704 static xmlSchemaSubstGroupPtr 05705 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 05706 xmlSchemaElementPtr head) 05707 { 05708 if (WXS_SUBST_GROUPS(pctxt) == NULL) 05709 return(NULL); 05710 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 05711 head->name, head->targetNamespace)); 05712 05713 } 05714 05725 static int 05726 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 05727 xmlSchemaElementPtr head, 05728 xmlSchemaElementPtr member) 05729 { 05730 xmlSchemaSubstGroupPtr substGroup = NULL; 05731 05732 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 05733 return (-1); 05734 05735 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 05736 if (substGroup == NULL) 05737 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 05738 if (substGroup == NULL) 05739 return(-1); 05740 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 05741 return(-1); 05742 return(0); 05743 } 05744 05745 /************************************************************************ 05746 * * 05747 * Utilities for parsing * 05748 * * 05749 ************************************************************************/ 05750 05768 static int 05769 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 05770 xmlSchemaPtr schema, 05771 xmlSchemaBasicItemPtr ownerItem, 05772 xmlAttrPtr attr, 05773 const xmlChar *value, 05774 const xmlChar **uri, 05775 const xmlChar **local) 05776 { 05777 const xmlChar *pref; 05778 xmlNsPtr ns; 05779 int len, ret; 05780 05781 *uri = NULL; 05782 *local = NULL; 05783 ret = xmlValidateQName(value, 1); 05784 if (ret > 0) { 05785 xmlSchemaPSimpleTypeErr(ctxt, 05786 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 05787 ownerItem, (xmlNodePtr) attr, 05788 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 05789 NULL, value, NULL, NULL, NULL); 05790 *local = value; 05791 return (ctxt->err); 05792 } else if (ret < 0) 05793 return (-1); 05794 05795 if (!strchr((char *) value, ':')) { 05796 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 05797 if (ns) 05798 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 05799 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 05800 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 05801 * parser context. */ 05802 /* 05803 * This one takes care of included schemas with no 05804 * target namespace. 05805 */ 05806 *uri = ctxt->targetNamespace; 05807 } 05808 *local = xmlDictLookup(ctxt->dict, value, -1); 05809 return (0); 05810 } 05811 /* 05812 * At this point xmlSplitQName3 has to return a local name. 05813 */ 05814 *local = xmlSplitQName3(value, &len); 05815 *local = xmlDictLookup(ctxt->dict, *local, -1); 05816 pref = xmlDictLookup(ctxt->dict, value, len); 05817 ns = xmlSearchNs(attr->doc, attr->parent, pref); 05818 if (ns == NULL) { 05819 xmlSchemaPSimpleTypeErr(ctxt, 05820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 05821 ownerItem, (xmlNodePtr) attr, 05822 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 05823 "The value '%s' of simple type 'xs:QName' has no " 05824 "corresponding namespace declaration in scope", value, NULL); 05825 return (ctxt->err); 05826 } else { 05827 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 05828 } 05829 return (0); 05830 } 05831 05849 static int 05850 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 05851 xmlSchemaPtr schema, 05852 xmlSchemaBasicItemPtr ownerItem, 05853 xmlAttrPtr attr, 05854 const xmlChar **uri, 05855 const xmlChar **local) 05856 { 05857 const xmlChar *value; 05858 05859 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 05860 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 05861 ownerItem, attr, value, uri, local)); 05862 } 05863 05880 static int 05881 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 05882 xmlSchemaPtr schema, 05883 xmlSchemaBasicItemPtr ownerItem, 05884 xmlNodePtr ownerElem, 05885 const char *name, 05886 const xmlChar **uri, 05887 const xmlChar **local) 05888 { 05889 xmlAttrPtr attr; 05890 05891 attr = xmlSchemaGetPropNode(ownerElem, name); 05892 if (attr == NULL) { 05893 *local = NULL; 05894 *uri = NULL; 05895 return (0); 05896 } 05897 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 05898 ownerItem, attr, uri, local)); 05899 } 05900 05915 static int 05916 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 05917 { 05918 int ret; 05919 const xmlChar *value; 05920 05921 if (attr == NULL) 05922 return(0); 05923 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 05924 ret = xmlValidateNCName(value, 1); 05925 if (ret == 0) { 05926 /* 05927 * NOTE: the IDness might have already be declared in the DTD 05928 */ 05929 if (attr->atype != XML_ATTRIBUTE_ID) { 05930 xmlIDPtr res; 05931 xmlChar *strip; 05932 05933 /* 05934 * TODO: Use xmlSchemaStrip here; it's not exported at this 05935 * moment. 05936 */ 05937 strip = xmlSchemaCollapseString(value); 05938 if (strip != NULL) { 05939 xmlFree((xmlChar *) value); 05940 value = strip; 05941 } 05942 res = xmlAddID(NULL, attr->doc, value, attr); 05943 if (res == NULL) { 05944 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 05945 xmlSchemaPSimpleTypeErr(ctxt, 05946 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 05947 NULL, (xmlNodePtr) attr, 05948 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 05949 NULL, NULL, "Duplicate value '%s' of simple " 05950 "type 'xs:ID'", value, NULL); 05951 } else 05952 attr->atype = XML_ATTRIBUTE_ID; 05953 } 05954 } else if (ret > 0) { 05955 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 05956 xmlSchemaPSimpleTypeErr(ctxt, 05957 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 05958 NULL, (xmlNodePtr) attr, 05959 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 05960 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 05961 "not a valid 'xs:NCName'", 05962 value, NULL); 05963 } 05964 if (value != NULL) 05965 xmlFree((xmlChar *)value); 05966 05967 return (ret); 05968 } 05969 05970 static int 05971 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 05972 xmlNodePtr ownerElem, 05973 const xmlChar *name) 05974 { 05975 xmlAttrPtr attr; 05976 05977 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 05978 if (attr == NULL) 05979 return(0); 05980 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 05981 05982 } 05983 05993 static int 05994 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 05995 int min, int max, int def, const char *expected) 05996 { 05997 const xmlChar *val, *cur; 05998 int ret = 0; 05999 xmlAttrPtr attr; 06000 06001 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 06002 if (attr == NULL) 06003 return (def); 06004 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 06005 06006 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 06007 if (max != UNBOUNDED) { 06008 xmlSchemaPSimpleTypeErr(ctxt, 06009 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 06010 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 06011 NULL, (xmlNodePtr) attr, NULL, expected, 06012 val, NULL, NULL, NULL); 06013 return (def); 06014 } else 06015 return (UNBOUNDED); /* encoding it with -1 might be another option */ 06016 } 06017 06018 cur = val; 06019 while (IS_BLANK_CH(*cur)) 06020 cur++; 06021 if (*cur == 0) { 06022 xmlSchemaPSimpleTypeErr(ctxt, 06023 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 06024 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 06025 NULL, (xmlNodePtr) attr, NULL, expected, 06026 val, NULL, NULL, NULL); 06027 return (def); 06028 } 06029 while ((*cur >= '0') && (*cur <= '9')) { 06030 ret = ret * 10 + (*cur - '0'); 06031 cur++; 06032 } 06033 while (IS_BLANK_CH(*cur)) 06034 cur++; 06035 /* 06036 * TODO: Restrict the maximal value to Integer. 06037 */ 06038 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 06039 xmlSchemaPSimpleTypeErr(ctxt, 06040 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 06041 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 06042 NULL, (xmlNodePtr) attr, NULL, expected, 06043 val, NULL, NULL, NULL); 06044 return (def); 06045 } 06046 return (ret); 06047 } 06048 06058 static int 06059 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 06060 int min, int max, int def, const char *expected) 06061 { 06062 const xmlChar *val, *cur; 06063 int ret = 0; 06064 xmlAttrPtr attr; 06065 06066 attr = xmlSchemaGetPropNode(node, "minOccurs"); 06067 if (attr == NULL) 06068 return (def); 06069 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 06070 cur = val; 06071 while (IS_BLANK_CH(*cur)) 06072 cur++; 06073 if (*cur == 0) { 06074 xmlSchemaPSimpleTypeErr(ctxt, 06075 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 06076 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 06077 NULL, (xmlNodePtr) attr, NULL, expected, 06078 val, NULL, NULL, NULL); 06079 return (def); 06080 } 06081 while ((*cur >= '0') && (*cur <= '9')) { 06082 ret = ret * 10 + (*cur - '0'); 06083 cur++; 06084 } 06085 while (IS_BLANK_CH(*cur)) 06086 cur++; 06087 /* 06088 * TODO: Restrict the maximal value to Integer. 06089 */ 06090 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 06091 xmlSchemaPSimpleTypeErr(ctxt, 06092 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 06093 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 06094 NULL, (xmlNodePtr) attr, NULL, expected, 06095 val, NULL, NULL, NULL); 06096 return (def); 06097 } 06098 return (ret); 06099 } 06100 06112 static int 06113 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 06114 xmlSchemaBasicItemPtr ownerItem, 06115 xmlNodePtr node) 06116 { 06117 xmlChar *value = NULL; 06118 int res = 0; 06119 06120 value = xmlNodeGetContent(node); 06121 /* 06122 * 3.2.2.1 Lexical representation 06123 * An instance of a datatype that is defined as �boolean� 06124 * can have the following legal literals {true, false, 1, 0}. 06125 */ 06126 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 06127 res = 1; 06128 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 06129 res = 0; 06130 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 06131 res = 1; 06132 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 06133 res = 0; 06134 else { 06135 xmlSchemaPSimpleTypeErr(ctxt, 06136 XML_SCHEMAP_INVALID_BOOLEAN, 06137 ownerItem, node, 06138 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 06139 NULL, BAD_CAST value, 06140 NULL, NULL, NULL); 06141 } 06142 if (value != NULL) 06143 xmlFree(value); 06144 return (res); 06145 } 06146 06159 static int 06160 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 06161 xmlNodePtr node, 06162 const char *name, int def) 06163 { 06164 const xmlChar *val; 06165 06166 val = xmlSchemaGetProp(ctxt, node, name); 06167 if (val == NULL) 06168 return (def); 06169 /* 06170 * 3.2.2.1 Lexical representation 06171 * An instance of a datatype that is defined as �boolean� 06172 * can have the following legal literals {true, false, 1, 0}. 06173 */ 06174 if (xmlStrEqual(val, BAD_CAST "true")) 06175 def = 1; 06176 else if (xmlStrEqual(val, BAD_CAST "false")) 06177 def = 0; 06178 else if (xmlStrEqual(val, BAD_CAST "1")) 06179 def = 1; 06180 else if (xmlStrEqual(val, BAD_CAST "0")) 06181 def = 0; 06182 else { 06183 xmlSchemaPSimpleTypeErr(ctxt, 06184 XML_SCHEMAP_INVALID_BOOLEAN, 06185 NULL, 06186 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 06187 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 06188 NULL, val, NULL, NULL, NULL); 06189 } 06190 return (def); 06191 } 06192 06193 /************************************************************************ 06194 * * 06195 * Shema extraction from an Infoset * 06196 * * 06197 ************************************************************************/ 06198 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 06199 ctxt, xmlSchemaPtr schema, 06200 xmlNodePtr node, 06201 int topLevel); 06202 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 06203 ctxt, 06204 xmlSchemaPtr schema, 06205 xmlNodePtr node, 06206 int topLevel); 06207 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 06208 ctxt, 06209 xmlSchemaPtr schema, 06210 xmlNodePtr node, 06211 xmlSchemaTypeType parentType); 06212 static xmlSchemaBasicItemPtr 06213 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 06214 xmlSchemaPtr schema, 06215 xmlNodePtr node, 06216 xmlSchemaItemListPtr uses, 06217 int parentType); 06218 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 06219 xmlSchemaPtr schema, 06220 xmlNodePtr node); 06221 static xmlSchemaWildcardPtr 06222 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 06223 xmlSchemaPtr schema, xmlNodePtr node); 06224 06242 static int 06243 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 06244 xmlSchemaBasicItemPtr ownerItem, 06245 xmlAttrPtr attr, 06246 const xmlChar *value, 06247 xmlSchemaTypePtr type) 06248 { 06249 06250 int ret = 0; 06251 06252 /* 06253 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 06254 * one is really meant to be used internally, so better not. 06255 */ 06256 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 06257 return (-1); 06258 if (type->type != XML_SCHEMA_TYPE_BASIC) { 06259 PERROR_INT("xmlSchemaPValAttrNodeValue", 06260 "the given type is not a built-in type"); 06261 return (-1); 06262 } 06263 switch (type->builtInType) { 06264 case XML_SCHEMAS_NCNAME: 06265 case XML_SCHEMAS_QNAME: 06266 case XML_SCHEMAS_ANYURI: 06267 case XML_SCHEMAS_TOKEN: 06268 case XML_SCHEMAS_LANGUAGE: 06269 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 06270 (xmlNodePtr) attr); 06271 break; 06272 default: { 06273 PERROR_INT("xmlSchemaPValAttrNodeValue", 06274 "validation using the given type is not supported while " 06275 "parsing a schema"); 06276 return (-1); 06277 } 06278 } 06279 /* 06280 * TODO: Should we use the S4S error codes instead? 06281 */ 06282 if (ret < 0) { 06283 PERROR_INT("xmlSchemaPValAttrNodeValue", 06284 "failed to validate a schema attribute value"); 06285 return (-1); 06286 } else if (ret > 0) { 06287 if (WXS_IS_LIST(type)) 06288 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 06289 else 06290 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 06291 xmlSchemaPSimpleTypeErr(pctxt, 06292 ret, ownerItem, (xmlNodePtr) attr, 06293 type, NULL, value, NULL, NULL, NULL); 06294 } 06295 return (ret); 06296 } 06297 06315 static int 06316 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 06317 xmlSchemaBasicItemPtr ownerItem, 06318 xmlAttrPtr attr, 06319 xmlSchemaTypePtr type, 06320 const xmlChar **value) 06321 { 06322 const xmlChar *val; 06323 06324 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 06325 return (-1); 06326 06327 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 06328 if (value != NULL) 06329 *value = val; 06330 06331 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 06332 val, type)); 06333 } 06334 06354 static int 06355 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 06356 xmlSchemaBasicItemPtr ownerItem, 06357 xmlNodePtr ownerElem, 06358 const char *name, 06359 xmlSchemaTypePtr type, 06360 const xmlChar **value) 06361 { 06362 xmlAttrPtr attr; 06363 06364 if ((ctxt == NULL) || (type == NULL)) { 06365 if (value != NULL) 06366 *value = NULL; 06367 return (-1); 06368 } 06369 if (type->type != XML_SCHEMA_TYPE_BASIC) { 06370 if (value != NULL) 06371 *value = NULL; 06372 xmlSchemaPErr(ctxt, ownerElem, 06373 XML_SCHEMAP_INTERNAL, 06374 "Internal error: xmlSchemaPValAttr, the given " 06375 "type '%s' is not a built-in type.\n", 06376 type->name, NULL); 06377 return (-1); 06378 } 06379 attr = xmlSchemaGetPropNode(ownerElem, name); 06380 if (attr == NULL) { 06381 if (value != NULL) 06382 *value = NULL; 06383 return (0); 06384 } 06385 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 06386 type, value)); 06387 } 06388 06389 static int 06390 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 06391 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 06392 xmlNodePtr node, 06393 xmlAttrPtr attr, 06394 const xmlChar *namespaceName) 06395 { 06396 /* TODO: Pointer comparison instead? */ 06397 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 06398 return (0); 06399 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 06400 return (0); 06401 /* 06402 * Check if the referenced namespace was <import>ed. 06403 */ 06404 if (WXS_BUCKET(pctxt)->relations != NULL) { 06405 xmlSchemaSchemaRelationPtr rel; 06406 06407 rel = WXS_BUCKET(pctxt)->relations; 06408 do { 06409 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 06410 xmlStrEqual(namespaceName, rel->importNamespace)) 06411 return (0); 06412 rel = rel->next; 06413 } while (rel != NULL); 06414 } 06415 /* 06416 * No matching <import>ed namespace found. 06417 */ 06418 { 06419 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 06420 06421 if (namespaceName == NULL) 06422 xmlSchemaCustomErr(ACTXT_CAST pctxt, 06423 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 06424 "References from this schema to components in no " 06425 "namespace are not allowed, since not indicated by an " 06426 "import statement", NULL, NULL); 06427 else 06428 xmlSchemaCustomErr(ACTXT_CAST pctxt, 06429 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 06430 "References from this schema to components in the " 06431 "namespace '%s' are not allowed, since not indicated by an " 06432 "import statement", namespaceName, NULL); 06433 } 06434 return (XML_SCHEMAP_SRC_RESOLVE); 06435 } 06436 06447 static int 06448 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 06449 xmlNodePtr *child, xmlSchemaItemListPtr *list, 06450 int parentType, int *hasRefs) 06451 { 06452 void *item; 06453 06454 while ((IS_SCHEMA((*child), "attribute")) || 06455 (IS_SCHEMA((*child), "attributeGroup"))) { 06456 if (IS_SCHEMA((*child), "attribute")) { 06457 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 06458 *list, parentType); 06459 } else { 06460 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 06461 if ((item != NULL) && (hasRefs != NULL)) 06462 *hasRefs = 1; 06463 } 06464 if (item != NULL) { 06465 if (*list == NULL) { 06466 /* TODO: Customize grow factor. */ 06467 *list = xmlSchemaItemListCreate(); 06468 if (*list == NULL) 06469 return(-1); 06470 } 06471 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 06472 return(-1); 06473 } 06474 *child = (*child)->next; 06475 } 06476 return (0); 06477 } 06478 06491 static xmlSchemaAnnotPtr 06492 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 06493 { 06494 xmlSchemaAnnotPtr ret; 06495 xmlNodePtr child = NULL; 06496 xmlAttrPtr attr; 06497 int barked = 0; 06498 06499 /* 06500 * INFO: S4S completed. 06501 */ 06502 /* 06503 * id = ID 06504 * {any attributes with non-schema namespace . . .}> 06505 * Content: (appinfo | documentation)* 06506 */ 06507 if ((ctxt == NULL) || (node == NULL)) 06508 return (NULL); 06509 if (needed) 06510 ret = xmlSchemaNewAnnot(ctxt, node); 06511 else 06512 ret = NULL; 06513 attr = node->properties; 06514 while (attr != NULL) { 06515 if (((attr->ns == NULL) && 06516 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 06517 ((attr->ns != NULL) && 06518 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 06519 06520 xmlSchemaPIllegalAttrErr(ctxt, 06521 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 06522 } 06523 attr = attr->next; 06524 } 06525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 06526 /* 06527 * And now for the children... 06528 */ 06529 child = node->children; 06530 while (child != NULL) { 06531 if (IS_SCHEMA(child, "appinfo")) { 06532 /* TODO: make available the content of "appinfo". */ 06533 /* 06534 * source = anyURI 06535 * {any attributes with non-schema namespace . . .}> 06536 * Content: ({any})* 06537 */ 06538 attr = child->properties; 06539 while (attr != NULL) { 06540 if (((attr->ns == NULL) && 06541 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 06542 ((attr->ns != NULL) && 06543 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 06544 06545 xmlSchemaPIllegalAttrErr(ctxt, 06546 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 06547 } 06548 attr = attr->next; 06549 } 06550 xmlSchemaPValAttr(ctxt, NULL, child, "source", 06551 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 06552 child = child->next; 06553 } else if (IS_SCHEMA(child, "documentation")) { 06554 /* TODO: make available the content of "documentation". */ 06555 /* 06556 * source = anyURI 06557 * {any attributes with non-schema namespace . . .}> 06558 * Content: ({any})* 06559 */ 06560 attr = child->properties; 06561 while (attr != NULL) { 06562 if (attr->ns == NULL) { 06563 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 06564 xmlSchemaPIllegalAttrErr(ctxt, 06565 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 06566 } 06567 } else { 06568 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 06569 (xmlStrEqual(attr->name, BAD_CAST "lang") && 06570 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 06571 06572 xmlSchemaPIllegalAttrErr(ctxt, 06573 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 06574 } 06575 } 06576 attr = attr->next; 06577 } 06578 /* 06579 * Attribute "xml:lang". 06580 */ 06581 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 06582 if (attr != NULL) 06583 xmlSchemaPValAttrNode(ctxt, NULL, attr, 06584 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 06585 child = child->next; 06586 } else { 06587 if (!barked) 06588 xmlSchemaPContentErr(ctxt, 06589 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 06590 NULL, node, child, NULL, "(appinfo | documentation)*"); 06591 barked = 1; 06592 child = child->next; 06593 } 06594 } 06595 06596 return (ret); 06597 } 06598 06610 static xmlSchemaFacetPtr 06611 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 06612 xmlNodePtr node) 06613 { 06614 xmlSchemaFacetPtr facet; 06615 xmlNodePtr child = NULL; 06616 const xmlChar *value; 06617 06618 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 06619 return (NULL); 06620 06621 facet = xmlSchemaNewFacet(); 06622 if (facet == NULL) { 06623 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 06624 return (NULL); 06625 } 06626 facet->node = node; 06627 value = xmlSchemaGetProp(ctxt, node, "value"); 06628 if (value == NULL) { 06629 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 06630 "Facet %s has no value\n", node->name, NULL); 06631 xmlSchemaFreeFacet(facet); 06632 return (NULL); 06633 } 06634 if (IS_SCHEMA(node, "minInclusive")) { 06635 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 06636 } else if (IS_SCHEMA(node, "minExclusive")) { 06637 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 06638 } else if (IS_SCHEMA(node, "maxInclusive")) { 06639 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 06640 } else if (IS_SCHEMA(node, "maxExclusive")) { 06641 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 06642 } else if (IS_SCHEMA(node, "totalDigits")) { 06643 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 06644 } else if (IS_SCHEMA(node, "fractionDigits")) { 06645 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 06646 } else if (IS_SCHEMA(node, "pattern")) { 06647 facet->type = XML_SCHEMA_FACET_PATTERN; 06648 } else if (IS_SCHEMA(node, "enumeration")) { 06649 facet->type = XML_SCHEMA_FACET_ENUMERATION; 06650 } else if (IS_SCHEMA(node, "whiteSpace")) { 06651 facet->type = XML_SCHEMA_FACET_WHITESPACE; 06652 } else if (IS_SCHEMA(node, "length")) { 06653 facet->type = XML_SCHEMA_FACET_LENGTH; 06654 } else if (IS_SCHEMA(node, "maxLength")) { 06655 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 06656 } else if (IS_SCHEMA(node, "minLength")) { 06657 facet->type = XML_SCHEMA_FACET_MINLENGTH; 06658 } else { 06659 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 06660 "Unknown facet type %s\n", node->name, NULL); 06661 xmlSchemaFreeFacet(facet); 06662 return (NULL); 06663 } 06664 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 06665 facet->value = value; 06666 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 06667 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 06668 const xmlChar *fixed; 06669 06670 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 06671 if (fixed != NULL) { 06672 if (xmlStrEqual(fixed, BAD_CAST "true")) 06673 facet->fixed = 1; 06674 } 06675 } 06676 child = node->children; 06677 06678 if (IS_SCHEMA(child, "annotation")) { 06679 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 06680 child = child->next; 06681 } 06682 if (child != NULL) { 06683 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 06684 "Facet %s has unexpected child content\n", 06685 node->name, NULL); 06686 } 06687 return (facet); 06688 } 06689 06703 static int 06704 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 06705 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 06706 xmlSchemaWildcardPtr wildc, 06707 xmlNodePtr node) 06708 { 06709 const xmlChar *pc, *ns, *dictnsItem; 06710 int ret = 0; 06711 xmlChar *nsItem; 06712 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 06713 xmlAttrPtr attr; 06714 06715 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 06716 if ((pc == NULL) 06717 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 06718 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 06719 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 06720 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 06721 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 06722 wildc->processContents = XML_SCHEMAS_ANY_LAX; 06723 } else { 06724 xmlSchemaPSimpleTypeErr(ctxt, 06725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 06726 NULL, node, 06727 NULL, "(strict | skip | lax)", pc, 06728 NULL, NULL, NULL); 06729 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 06730 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 06731 } 06732 /* 06733 * Build the namespace constraints. 06734 */ 06735 attr = xmlSchemaGetPropNode(node, "namespace"); 06736 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 06737 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 06738 wildc->any = 1; 06739 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 06740 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 06741 if (wildc->negNsSet == NULL) { 06742 return (-1); 06743 } 06744 wildc->negNsSet->value = ctxt->targetNamespace; 06745 } else { 06746 const xmlChar *end, *cur; 06747 06748 cur = ns; 06749 do { 06750 while (IS_BLANK_CH(*cur)) 06751 cur++; 06752 end = cur; 06753 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 06754 end++; 06755 if (end == cur) 06756 break; 06757 nsItem = xmlStrndup(cur, end - cur); 06758 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 06759 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 06760 xmlSchemaPSimpleTypeErr(ctxt, 06761 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 06762 NULL, (xmlNodePtr) attr, 06763 NULL, 06764 "((##any | ##other) | List of (xs:anyURI | " 06765 "(##targetNamespace | ##local)))", 06766 nsItem, NULL, NULL, NULL); 06767 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 06768 } else { 06769 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 06770 dictnsItem = ctxt->targetNamespace; 06771 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 06772 dictnsItem = NULL; 06773 } else { 06774 /* 06775 * Validate the item (anyURI). 06776 */ 06777 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 06778 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 06779 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 06780 } 06781 /* 06782 * Avoid dublicate namespaces. 06783 */ 06784 tmp = wildc->nsSet; 06785 while (tmp != NULL) { 06786 if (dictnsItem == tmp->value) 06787 break; 06788 tmp = tmp->next; 06789 } 06790 if (tmp == NULL) { 06791 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 06792 if (tmp == NULL) { 06793 xmlFree(nsItem); 06794 return (-1); 06795 } 06796 tmp->value = dictnsItem; 06797 tmp->next = NULL; 06798 if (wildc->nsSet == NULL) 06799 wildc->nsSet = tmp; 06800 else if (lastNs != NULL) 06801 lastNs->next = tmp; 06802 lastNs = tmp; 06803 } 06804 06805 } 06806 xmlFree(nsItem); 06807 cur = end; 06808 } while (*cur != 0); 06809 } 06810 return (ret); 06811 } 06812 06813 static int 06814 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 06815 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 06816 xmlNodePtr node, 06817 int minOccurs, 06818 int maxOccurs) { 06819 06820 if ((maxOccurs == 0) && ( minOccurs == 0)) 06821 return (0); 06822 if (maxOccurs != UNBOUNDED) { 06823 /* 06824 * TODO: Maybe we should better not create the particle, 06825 * if min/max is invalid, since it could confuse the build of the 06826 * content model. 06827 */ 06828 /* 06829 * 3.9.6 Schema Component Constraint: Particle Correct 06830 * 06831 */ 06832 if (maxOccurs < 1) { 06833 /* 06834 * 2.2 {max occurs} must be greater than or equal to 1. 06835 */ 06836 xmlSchemaPCustomAttrErr(ctxt, 06837 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 06838 NULL, NULL, 06839 xmlSchemaGetPropNode(node, "maxOccurs"), 06840 "The value must be greater than or equal to 1"); 06841 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 06842 } else if (minOccurs > maxOccurs) { 06843 /* 06844 * 2.1 {min occurs} must not be greater than {max occurs}. 06845 */ 06846 xmlSchemaPCustomAttrErr(ctxt, 06847 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 06848 NULL, NULL, 06849 xmlSchemaGetPropNode(node, "minOccurs"), 06850 "The value must not be greater than the value of 'maxOccurs'"); 06851 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 06852 } 06853 } 06854 return (0); 06855 } 06856 06870 static xmlSchemaParticlePtr 06871 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 06872 xmlNodePtr node) 06873 { 06874 xmlSchemaParticlePtr particle; 06875 xmlNodePtr child = NULL; 06876 xmlSchemaWildcardPtr wild; 06877 int min, max; 06878 xmlAttrPtr attr; 06879 xmlSchemaAnnotPtr annot = NULL; 06880 06881 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 06882 return (NULL); 06883 /* 06884 * Check for illegal attributes. 06885 */ 06886 attr = node->properties; 06887 while (attr != NULL) { 06888 if (attr->ns == NULL) { 06889 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 06890 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 06891 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 06892 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 06893 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 06894 xmlSchemaPIllegalAttrErr(ctxt, 06895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 06896 } 06897 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 06898 xmlSchemaPIllegalAttrErr(ctxt, 06899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 06900 } 06901 attr = attr->next; 06902 } 06903 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 06904 /* 06905 * minOccurs/maxOccurs. 06906 */ 06907 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 06908 "(xs:nonNegativeInteger | unbounded)"); 06909 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 06910 "xs:nonNegativeInteger"); 06911 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 06912 /* 06913 * Create & parse the wildcard. 06914 */ 06915 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 06916 if (wild == NULL) 06917 return (NULL); 06918 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 06919 /* 06920 * And now for the children... 06921 */ 06922 child = node->children; 06923 if (IS_SCHEMA(child, "annotation")) { 06924 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 06925 child = child->next; 06926 } 06927 if (child != NULL) { 06928 xmlSchemaPContentErr(ctxt, 06929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 06930 NULL, node, child, 06931 NULL, "(annotation?)"); 06932 } 06933 /* 06934 * No component if minOccurs==maxOccurs==0. 06935 */ 06936 if ((min == 0) && (max == 0)) { 06937 /* Don't free the wildcard, since it's already on the list. */ 06938 return (NULL); 06939 } 06940 /* 06941 * Create the particle. 06942 */ 06943 particle = xmlSchemaAddParticle(ctxt, node, min, max); 06944 if (particle == NULL) 06945 return (NULL); 06946 particle->annot = annot; 06947 particle->children = (xmlSchemaTreeItemPtr) wild; 06948 06949 return (particle); 06950 } 06951 06962 static xmlSchemaNotationPtr 06963 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 06964 xmlNodePtr node) 06965 { 06966 const xmlChar *name; 06967 xmlSchemaNotationPtr ret; 06968 xmlNodePtr child = NULL; 06969 06970 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 06971 return (NULL); 06972 name = xmlSchemaGetProp(ctxt, node, "name"); 06973 if (name == NULL) { 06974 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 06975 "Notation has no name\n", NULL, NULL); 06976 return (NULL); 06977 } 06978 ret = xmlSchemaAddNotation(ctxt, schema, name, 06979 ctxt->targetNamespace, node); 06980 if (ret == NULL) 06981 return (NULL); 06982 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 06983 06984 child = node->children; 06985 if (IS_SCHEMA(child, "annotation")) { 06986 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 06987 child = child->next; 06988 } 06989 if (child != NULL) { 06990 xmlSchemaPContentErr(ctxt, 06991 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 06992 NULL, node, child, 06993 NULL, "(annotation?)"); 06994 } 06995 06996 return (ret); 06997 } 06998 07010 static xmlSchemaWildcardPtr 07011 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 07012 xmlSchemaPtr schema, xmlNodePtr node) 07013 { 07014 xmlSchemaWildcardPtr ret; 07015 xmlNodePtr child = NULL; 07016 xmlAttrPtr attr; 07017 07018 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 07019 return (NULL); 07020 07021 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 07022 node); 07023 if (ret == NULL) { 07024 return (NULL); 07025 } 07026 /* 07027 * Check for illegal attributes. 07028 */ 07029 attr = node->properties; 07030 while (attr != NULL) { 07031 if (attr->ns == NULL) { 07032 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 07033 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 07034 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 07035 xmlSchemaPIllegalAttrErr(ctxt, 07036 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07037 } 07038 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 07039 xmlSchemaPIllegalAttrErr(ctxt, 07040 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07041 } 07042 attr = attr->next; 07043 } 07044 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 07045 /* 07046 * Parse the namespace list. 07047 */ 07048 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 07049 return (NULL); 07050 /* 07051 * And now for the children... 07052 */ 07053 child = node->children; 07054 if (IS_SCHEMA(child, "annotation")) { 07055 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 07056 child = child->next; 07057 } 07058 if (child != NULL) { 07059 xmlSchemaPContentErr(ctxt, 07060 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07061 NULL, node, child, 07062 NULL, "(annotation?)"); 07063 } 07064 07065 return (ret); 07066 } 07067 07068 07080 static xmlSchemaBasicItemPtr 07081 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 07082 xmlSchemaPtr schema, 07083 xmlNodePtr node, 07084 xmlSchemaItemListPtr uses, 07085 int parentType) 07086 { 07087 const xmlChar *attrValue, *name = NULL, *ns = NULL; 07088 xmlSchemaAttributeUsePtr use = NULL; 07089 xmlNodePtr child = NULL; 07090 xmlAttrPtr attr; 07091 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 07092 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 07093 int nberrors, hasForm = 0, defValueType = 0; 07094 07095 #define WXS_ATTR_DEF_VAL_DEFAULT 1 07096 #define WXS_ATTR_DEF_VAL_FIXED 2 07097 07098 /* 07099 * 3.2.3 Constraints on XML Representations of Attribute Declarations 07100 */ 07101 07102 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 07103 return (NULL); 07104 attr = xmlSchemaGetPropNode(node, "ref"); 07105 if (attr != NULL) { 07106 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 07107 NULL, attr, &tmpNs, &tmpName) != 0) { 07108 return (NULL); 07109 } 07110 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 07111 return(NULL); 07112 isRef = 1; 07113 } 07114 nberrors = pctxt->nberrors; 07115 /* 07116 * Check for illegal attributes. 07117 */ 07118 attr = node->properties; 07119 while (attr != NULL) { 07120 if (attr->ns == NULL) { 07121 if (isRef) { 07122 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 07123 xmlSchemaPValAttrNodeID(pctxt, attr); 07124 goto attr_next; 07125 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 07126 goto attr_next; 07127 } 07128 } else { 07129 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 07130 goto attr_next; 07131 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 07132 xmlSchemaPValAttrNodeID(pctxt, attr); 07133 goto attr_next; 07134 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 07135 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 07136 attr, &tmpNs, &tmpName); 07137 goto attr_next; 07138 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 07139 /* 07140 * Evaluate the target namespace 07141 */ 07142 hasForm = 1; 07143 attrValue = xmlSchemaGetNodeContent(pctxt, 07144 (xmlNodePtr) attr); 07145 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 07146 ns = pctxt->targetNamespace; 07147 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 07148 { 07149 xmlSchemaPSimpleTypeErr(pctxt, 07150 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 07151 NULL, (xmlNodePtr) attr, 07152 NULL, "(qualified | unqualified)", 07153 attrValue, NULL, NULL, NULL); 07154 } 07155 goto attr_next; 07156 } 07157 } 07158 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 07159 07160 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 07161 /* TODO: Maybe we need to normalize the value beforehand. */ 07162 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 07163 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 07164 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 07165 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 07166 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 07167 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 07168 else { 07169 xmlSchemaPSimpleTypeErr(pctxt, 07170 XML_SCHEMAP_INVALID_ATTR_USE, 07171 NULL, (xmlNodePtr) attr, 07172 NULL, "(optional | prohibited | required)", 07173 attrValue, NULL, NULL, NULL); 07174 } 07175 goto attr_next; 07176 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 07177 /* 07178 * 3.2.3 : 1 07179 * default and fixed must not both be present. 07180 */ 07181 if (defValue) { 07182 xmlSchemaPMutualExclAttrErr(pctxt, 07183 XML_SCHEMAP_SRC_ATTRIBUTE_1, 07184 NULL, attr, "default", "fixed"); 07185 } else { 07186 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 07187 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 07188 } 07189 goto attr_next; 07190 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 07191 /* 07192 * 3.2.3 : 1 07193 * default and fixed must not both be present. 07194 */ 07195 if (defValue) { 07196 xmlSchemaPMutualExclAttrErr(pctxt, 07197 XML_SCHEMAP_SRC_ATTRIBUTE_1, 07198 NULL, attr, "default", "fixed"); 07199 } else { 07200 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 07201 defValueType = WXS_ATTR_DEF_VAL_FIXED; 07202 } 07203 goto attr_next; 07204 } 07205 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 07206 goto attr_next; 07207 07208 xmlSchemaPIllegalAttrErr(pctxt, 07209 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07210 07211 attr_next: 07212 attr = attr->next; 07213 } 07214 /* 07215 * 3.2.3 : 2 07216 * If default and use are both present, use must have 07217 * the actual value optional. 07218 */ 07219 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 07220 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 07221 xmlSchemaPSimpleTypeErr(pctxt, 07222 XML_SCHEMAP_SRC_ATTRIBUTE_2, 07223 NULL, node, NULL, 07224 "(optional | prohibited | required)", NULL, 07225 "The value of the attribute 'use' must be 'optional' " 07226 "if the attribute 'default' is present", 07227 NULL, NULL); 07228 } 07229 /* 07230 * We want correct attributes. 07231 */ 07232 if (nberrors != pctxt->nberrors) 07233 return(NULL); 07234 if (! isRef) { 07235 xmlSchemaAttributePtr attrDecl; 07236 07237 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 07238 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 07239 ns = pctxt->targetNamespace; 07240 /* 07241 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 07242 * TODO: Move this to the component layer. 07243 */ 07244 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 07245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 07246 XML_SCHEMAP_NO_XSI, 07247 node, NULL, 07248 "The target namespace must not match '%s'", 07249 xmlSchemaInstanceNs, NULL); 07250 } 07251 attr = xmlSchemaGetPropNode(node, "name"); 07252 if (attr == NULL) { 07253 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 07254 NULL, node, "name", NULL); 07255 return (NULL); 07256 } 07257 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 07258 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 07259 return (NULL); 07260 } 07261 /* 07262 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 07263 * TODO: Move this to the component layer. 07264 */ 07265 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 07266 xmlSchemaPSimpleTypeErr(pctxt, 07267 XML_SCHEMAP_NO_XMLNS, 07268 NULL, (xmlNodePtr) attr, 07269 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 07270 "The value of the attribute must not match 'xmlns'", 07271 NULL, NULL); 07272 return (NULL); 07273 } 07274 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 07275 goto check_children; 07276 /* 07277 * Create the attribute use component. 07278 */ 07279 use = xmlSchemaAddAttributeUse(pctxt, node); 07280 if (use == NULL) 07281 return(NULL); 07282 use->occurs = occurs; 07283 /* 07284 * Create the attribute declaration. 07285 */ 07286 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 07287 if (attrDecl == NULL) 07288 return (NULL); 07289 if (tmpName != NULL) { 07290 attrDecl->typeName = tmpName; 07291 attrDecl->typeNs = tmpNs; 07292 } 07293 use->attrDecl = attrDecl; 07294 /* 07295 * Value constraint. 07296 */ 07297 if (defValue != NULL) { 07298 attrDecl->defValue = defValue; 07299 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 07300 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 07301 } 07302 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 07303 xmlSchemaQNameRefPtr ref; 07304 07305 /* 07306 * Create the attribute use component. 07307 */ 07308 use = xmlSchemaAddAttributeUse(pctxt, node); 07309 if (use == NULL) 07310 return(NULL); 07311 /* 07312 * We need to resolve the reference at later stage. 07313 */ 07314 WXS_ADD_PENDING(pctxt, use); 07315 use->occurs = occurs; 07316 /* 07317 * Create a QName reference to the attribute declaration. 07318 */ 07319 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 07320 tmpName, tmpNs); 07321 if (ref == NULL) 07322 return(NULL); 07323 /* 07324 * Assign the reference. This will be substituted for the 07325 * referenced attribute declaration when the QName is resolved. 07326 */ 07327 use->attrDecl = WXS_ATTR_CAST ref; 07328 /* 07329 * Value constraint. 07330 */ 07331 if (defValue != NULL) 07332 use->defValue = defValue; 07333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 07334 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 07335 } 07336 07337 check_children: 07338 /* 07339 * And now for the children... 07340 */ 07341 child = node->children; 07342 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 07343 xmlSchemaAttributeUseProhibPtr prohib; 07344 07345 if (IS_SCHEMA(child, "annotation")) { 07346 xmlSchemaParseAnnotation(pctxt, child, 0); 07347 child = child->next; 07348 } 07349 if (child != NULL) { 07350 xmlSchemaPContentErr(pctxt, 07351 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07352 NULL, node, child, NULL, 07353 "(annotation?)"); 07354 } 07355 /* 07356 * Check for pointlessness of attribute prohibitions. 07357 */ 07358 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 07359 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 07360 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 07361 node, NULL, 07362 "Skipping attribute use prohibition, since it is " 07363 "pointless inside an <attributeGroup>", 07364 NULL, NULL, NULL); 07365 return(NULL); 07366 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 07367 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 07368 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 07369 node, NULL, 07370 "Skipping attribute use prohibition, since it is " 07371 "pointless when extending a type", 07372 NULL, NULL, NULL); 07373 return(NULL); 07374 } 07375 if (! isRef) { 07376 tmpName = name; 07377 tmpNs = ns; 07378 } 07379 /* 07380 * Check for duplicate attribute prohibitions. 07381 */ 07382 if (uses) { 07383 int i; 07384 07385 for (i = 0; i < uses->nbItems; i++) { 07386 use = uses->items[i]; 07387 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 07388 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 07389 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 07390 { 07391 xmlChar *str = NULL; 07392 07393 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 07394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 07395 node, NULL, 07396 "Skipping duplicate attribute use prohibition '%s'", 07397 xmlSchemaFormatQName(&str, tmpNs, tmpName), 07398 NULL, NULL); 07399 FREE_AND_NULL(str) 07400 return(NULL); 07401 } 07402 } 07403 } 07404 /* 07405 * Create the attribute prohibition helper component. 07406 */ 07407 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 07408 if (prohib == NULL) 07409 return(NULL); 07410 prohib->node = node; 07411 prohib->name = tmpName; 07412 prohib->targetNamespace = tmpNs; 07413 if (isRef) { 07414 /* 07415 * We need at least to resolve to the attribute declaration. 07416 */ 07417 WXS_ADD_PENDING(pctxt, prohib); 07418 } 07419 return(WXS_BASIC_CAST prohib); 07420 } else { 07421 if (IS_SCHEMA(child, "annotation")) { 07422 /* 07423 * TODO: Should this go into the attr decl? 07424 */ 07425 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 07426 child = child->next; 07427 } 07428 if (isRef) { 07429 if (child != NULL) { 07430 if (IS_SCHEMA(child, "simpleType")) 07431 /* 07432 * 3.2.3 : 3.2 07433 * If ref is present, then all of <simpleType>, 07434 * form and type must be absent. 07435 */ 07436 xmlSchemaPContentErr(pctxt, 07437 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 07438 NULL, node, child, NULL, 07439 "(annotation?)"); 07440 else 07441 xmlSchemaPContentErr(pctxt, 07442 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07443 NULL, node, child, NULL, 07444 "(annotation?)"); 07445 } 07446 } else { 07447 if (IS_SCHEMA(child, "simpleType")) { 07448 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 07449 /* 07450 * 3.2.3 : 4 07451 * type and <simpleType> must not both be present. 07452 */ 07453 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 07454 NULL, node, child, 07455 "The attribute 'type' and the <simpleType> child " 07456 "are mutually exclusive", NULL); 07457 } else 07458 WXS_ATTRUSE_TYPEDEF(use) = 07459 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 07460 child = child->next; 07461 } 07462 if (child != NULL) 07463 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07464 NULL, node, child, NULL, 07465 "(annotation?, simpleType?)"); 07466 } 07467 } 07468 return (WXS_BASIC_CAST use); 07469 } 07470 07471 07472 static xmlSchemaAttributePtr 07473 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 07474 xmlSchemaPtr schema, 07475 xmlNodePtr node) 07476 { 07477 const xmlChar *attrValue; 07478 xmlSchemaAttributePtr ret; 07479 xmlNodePtr child = NULL; 07480 xmlAttrPtr attr; 07481 07482 /* 07483 * Note that the w3c spec assumes the schema to be validated with schema 07484 * for schemas beforehand. 07485 * 07486 * 3.2.3 Constraints on XML Representations of Attribute Declarations 07487 */ 07488 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 07489 return (NULL); 07490 /* 07491 * 3.2.3 : 3.1 07492 * One of ref or name must be present, but not both 07493 */ 07494 attr = xmlSchemaGetPropNode(node, "name"); 07495 if (attr == NULL) { 07496 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 07497 NULL, node, "name", NULL); 07498 return (NULL); 07499 } 07500 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 07501 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 07502 return (NULL); 07503 } 07504 /* 07505 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 07506 * TODO: Move this to the component layer. 07507 */ 07508 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 07509 xmlSchemaPSimpleTypeErr(pctxt, 07510 XML_SCHEMAP_NO_XMLNS, 07511 NULL, (xmlNodePtr) attr, 07512 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 07513 "The value of the attribute must not match 'xmlns'", 07514 NULL, NULL); 07515 return (NULL); 07516 } 07517 /* 07518 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 07519 * TODO: Move this to the component layer. 07520 * Or better leave it here and add it to the component layer 07521 * if we have a schema construction API. 07522 */ 07523 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 07524 xmlSchemaCustomErr(ACTXT_CAST pctxt, 07525 XML_SCHEMAP_NO_XSI, node, NULL, 07526 "The target namespace must not match '%s'", 07527 xmlSchemaInstanceNs, NULL); 07528 } 07529 07530 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 07531 pctxt->targetNamespace, node, 1); 07532 if (ret == NULL) 07533 return (NULL); 07534 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 07535 07536 /* 07537 * Check for illegal attributes. 07538 */ 07539 attr = node->properties; 07540 while (attr != NULL) { 07541 if (attr->ns == NULL) { 07542 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 07543 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 07544 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 07545 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 07546 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 07547 { 07548 xmlSchemaPIllegalAttrErr(pctxt, 07549 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07550 } 07551 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 07552 xmlSchemaPIllegalAttrErr(pctxt, 07553 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07554 } 07555 attr = attr->next; 07556 } 07557 xmlSchemaPValAttrQName(pctxt, schema, NULL, 07558 node, "type", &ret->typeNs, &ret->typeName); 07559 07560 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 07561 /* 07562 * Attribute "fixed". 07563 */ 07564 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 07565 if (ret->defValue != NULL) 07566 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 07567 /* 07568 * Attribute "default". 07569 */ 07570 attr = xmlSchemaGetPropNode(node, "default"); 07571 if (attr != NULL) { 07572 /* 07573 * 3.2.3 : 1 07574 * default and fixed must not both be present. 07575 */ 07576 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 07577 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 07578 WXS_BASIC_CAST ret, attr, "default", "fixed"); 07579 } else 07580 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 07581 } 07582 /* 07583 * And now for the children... 07584 */ 07585 child = node->children; 07586 if (IS_SCHEMA(child, "annotation")) { 07587 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 07588 child = child->next; 07589 } 07590 if (IS_SCHEMA(child, "simpleType")) { 07591 if (ret->typeName != NULL) { 07592 /* 07593 * 3.2.3 : 4 07594 * type and <simpleType> must not both be present. 07595 */ 07596 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 07597 NULL, node, child, 07598 "The attribute 'type' and the <simpleType> child " 07599 "are mutually exclusive", NULL); 07600 } else 07601 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 07602 child = child->next; 07603 } 07604 if (child != NULL) 07605 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07606 NULL, node, child, NULL, 07607 "(annotation?, simpleType?)"); 07608 07609 return (ret); 07610 } 07611 07625 static xmlSchemaQNameRefPtr 07626 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 07627 xmlSchemaPtr schema, 07628 xmlNodePtr node) 07629 { 07630 xmlSchemaQNameRefPtr ret; 07631 xmlNodePtr child = NULL; 07632 xmlAttrPtr attr; 07633 const xmlChar *refNs = NULL, *ref = NULL; 07634 07635 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 07636 return (NULL); 07637 07638 attr = xmlSchemaGetPropNode(node, "ref"); 07639 if (attr == NULL) { 07640 xmlSchemaPMissingAttrErr(pctxt, 07641 XML_SCHEMAP_S4S_ATTR_MISSING, 07642 NULL, node, "ref", NULL); 07643 return (NULL); 07644 } 07645 xmlSchemaPValAttrNodeQName(pctxt, schema, 07646 NULL, attr, &refNs, &ref); 07647 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 07648 return(NULL); 07649 07650 /* 07651 * Check for illegal attributes. 07652 */ 07653 attr = node->properties; 07654 while (attr != NULL) { 07655 if (attr->ns == NULL) { 07656 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 07657 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 07658 { 07659 xmlSchemaPIllegalAttrErr(pctxt, 07660 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07661 } 07662 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 07663 xmlSchemaPIllegalAttrErr(pctxt, 07664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07665 } 07666 attr = attr->next; 07667 } 07668 /* Attribute ID */ 07669 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 07670 07671 /* 07672 * And now for the children... 07673 */ 07674 child = node->children; 07675 if (IS_SCHEMA(child, "annotation")) { 07676 /* 07677 * TODO: We do not have a place to store the annotation, do we? 07678 */ 07679 xmlSchemaParseAnnotation(pctxt, child, 0); 07680 child = child->next; 07681 } 07682 if (child != NULL) { 07683 xmlSchemaPContentErr(pctxt, 07684 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07685 NULL, node, child, NULL, 07686 "(annotation?)"); 07687 } 07688 07689 /* 07690 * Handle attribute group redefinitions. 07691 */ 07692 if (pctxt->isRedefine && pctxt->redef && 07693 (pctxt->redef->item->type == 07694 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 07695 (ref == pctxt->redef->refName) && 07696 (refNs == pctxt->redef->refTargetNs)) 07697 { 07698 /* 07699 * SPEC src-redefine: 07700 * (7.1) "If it has an <attributeGroup> among its contents 07701 * the �actual value� of whose ref [attribute] is the same 07702 * as the �actual value� of its own name attribute plus 07703 * target namespace, then it must have exactly one such group." 07704 */ 07705 if (pctxt->redefCounter != 0) { 07706 xmlChar *str = NULL; 07707 07708 xmlSchemaCustomErr(ACTXT_CAST pctxt, 07709 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 07710 "The redefining attribute group definition " 07711 "'%s' must not contain more than one " 07712 "reference to the redefined definition", 07713 xmlSchemaFormatQName(&str, refNs, ref), NULL); 07714 FREE_AND_NULL(str); 07715 return(NULL); 07716 } 07717 pctxt->redefCounter++; 07718 /* 07719 * URGENT TODO: How to ensure that the reference will not be 07720 * handled by the normal component resolution mechanism? 07721 */ 07722 ret = xmlSchemaNewQNameRef(pctxt, 07723 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 07724 if (ret == NULL) 07725 return(NULL); 07726 ret->node = node; 07727 pctxt->redef->reference = WXS_BASIC_CAST ret; 07728 } else { 07729 /* 07730 * Create a QName-reference helper component. We will substitute this 07731 * component for the attribute uses of the referenced attribute group 07732 * definition. 07733 */ 07734 ret = xmlSchemaNewQNameRef(pctxt, 07735 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 07736 if (ret == NULL) 07737 return(NULL); 07738 ret->node = node; 07739 /* Add to pending items, to be able to resolve the reference. */ 07740 WXS_ADD_PENDING(pctxt, ret); 07741 } 07742 return (ret); 07743 } 07744 07756 static xmlSchemaAttributeGroupPtr 07757 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 07758 xmlSchemaPtr schema, 07759 xmlNodePtr node) 07760 { 07761 const xmlChar *name; 07762 xmlSchemaAttributeGroupPtr ret; 07763 xmlNodePtr child = NULL; 07764 xmlAttrPtr attr; 07765 int hasRefs = 0; 07766 07767 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 07768 return (NULL); 07769 07770 attr = xmlSchemaGetPropNode(node, "name"); 07771 if (attr == NULL) { 07772 xmlSchemaPMissingAttrErr(pctxt, 07773 XML_SCHEMAP_S4S_ATTR_MISSING, 07774 NULL, node, "name", NULL); 07775 return (NULL); 07776 } 07777 /* 07778 * The name is crucial, exit if invalid. 07779 */ 07780 if (xmlSchemaPValAttrNode(pctxt, 07781 NULL, attr, 07782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 07783 return (NULL); 07784 } 07785 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 07786 name, pctxt->targetNamespace, node); 07787 if (ret == NULL) 07788 return (NULL); 07789 /* 07790 * Check for illegal attributes. 07791 */ 07792 attr = node->properties; 07793 while (attr != NULL) { 07794 if (attr->ns == NULL) { 07795 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 07796 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 07797 { 07798 xmlSchemaPIllegalAttrErr(pctxt, 07799 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07800 } 07801 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 07802 xmlSchemaPIllegalAttrErr(pctxt, 07803 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 07804 } 07805 attr = attr->next; 07806 } 07807 /* Attribute ID */ 07808 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 07809 /* 07810 * And now for the children... 07811 */ 07812 child = node->children; 07813 if (IS_SCHEMA(child, "annotation")) { 07814 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 07815 child = child->next; 07816 } 07817 /* 07818 * Parse contained attribute decls/refs. 07819 */ 07820 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 07821 (xmlSchemaItemListPtr *) &(ret->attrUses), 07822 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 07823 return(NULL); 07824 if (hasRefs) 07825 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 07826 /* 07827 * Parse the attribute wildcard. 07828 */ 07829 if (IS_SCHEMA(child, "anyAttribute")) { 07830 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 07831 schema, child); 07832 child = child->next; 07833 } 07834 if (child != NULL) { 07835 xmlSchemaPContentErr(pctxt, 07836 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 07837 NULL, node, child, NULL, 07838 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 07839 } 07840 return (ret); 07841 } 07842 07851 static int 07852 xmlSchemaPValAttrFormDefault(const xmlChar *value, 07853 int *flags, 07854 int flagQualified) 07855 { 07856 if (xmlStrEqual(value, BAD_CAST "qualified")) { 07857 if ((*flags & flagQualified) == 0) 07858 *flags |= flagQualified; 07859 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 07860 return (1); 07861 07862 return (0); 07863 } 07864 07882 static int 07883 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 07884 int *flags, 07885 int flagAll, 07886 int flagExtension, 07887 int flagRestriction, 07888 int flagSubstitution, 07889 int flagList, 07890 int flagUnion) 07891 { 07892 int ret = 0; 07893 07894 /* 07895 * TODO: This does not check for dublicate entries. 07896 */ 07897 if ((flags == NULL) || (value == NULL)) 07898 return (-1); 07899 if (value[0] == 0) 07900 return (0); 07901 if (xmlStrEqual(value, BAD_CAST "#all")) { 07902 if (flagAll != -1) 07903 *flags |= flagAll; 07904 else { 07905 if (flagExtension != -1) 07906 *flags |= flagExtension; 07907 if (flagRestriction != -1) 07908 *flags |= flagRestriction; 07909 if (flagSubstitution != -1) 07910 *flags |= flagSubstitution; 07911 if (flagList != -1) 07912 *flags |= flagList; 07913 if (flagUnion != -1) 07914 *flags |= flagUnion; 07915 } 07916 } else { 07917 const xmlChar *end, *cur = value; 07918 xmlChar *item; 07919 07920 do { 07921 while (IS_BLANK_CH(*cur)) 07922 cur++; 07923 end = cur; 07924 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 07925 end++; 07926 if (end == cur) 07927 break; 07928 item = xmlStrndup(cur, end - cur); 07929 if (xmlStrEqual(item, BAD_CAST "extension")) { 07930 if (flagExtension != -1) { 07931 if ((*flags & flagExtension) == 0) 07932 *flags |= flagExtension; 07933 } else 07934 ret = 1; 07935 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 07936 if (flagRestriction != -1) { 07937 if ((*flags & flagRestriction) == 0) 07938 *flags |= flagRestriction; 07939 } else 07940 ret = 1; 07941 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 07942 if (flagSubstitution != -1) { 07943 if ((*flags & flagSubstitution) == 0) 07944 *flags |= flagSubstitution; 07945 } else 07946 ret = 1; 07947 } else if (xmlStrEqual(item, BAD_CAST "list")) { 07948 if (flagList != -1) { 07949 if ((*flags & flagList) == 0) 07950 *flags |= flagList; 07951 } else 07952 ret = 1; 07953 } else if (xmlStrEqual(item, BAD_CAST "union")) { 07954 if (flagUnion != -1) { 07955 if ((*flags & flagUnion) == 0) 07956 *flags |= flagUnion; 07957 } else 07958 ret = 1; 07959 } else 07960 ret = 1; 07961 if (item != NULL) 07962 xmlFree(item); 07963 cur = end; 07964 } while ((ret == 0) && (*cur != 0)); 07965 } 07966 07967 return (ret); 07968 } 07969 07970 static int 07971 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 07972 xmlSchemaIDCPtr idc, 07973 xmlSchemaIDCSelectPtr selector, 07974 xmlAttrPtr attr, 07975 int isField) 07976 { 07977 xmlNodePtr node; 07978 07979 /* 07980 * c-selector-xpath: 07981 * Schema Component Constraint: Selector Value OK 07982 * 07983 * TODO: 1 The {selector} must be a valid XPath expression, as defined 07984 * in [XPath]. 07985 */ 07986 if (selector == NULL) { 07987 xmlSchemaPErr(ctxt, idc->node, 07988 XML_SCHEMAP_INTERNAL, 07989 "Internal error: xmlSchemaCheckCSelectorXPath, " 07990 "the selector is not specified.\n", NULL, NULL); 07991 return (-1); 07992 } 07993 if (attr == NULL) 07994 node = idc->node; 07995 else 07996 node = (xmlNodePtr) attr; 07997 if (selector->xpath == NULL) { 07998 xmlSchemaPCustomErr(ctxt, 07999 /* TODO: Adjust error code. */ 08000 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 08001 NULL, node, 08002 "The XPath expression of the selector is not valid", NULL); 08003 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 08004 } else { 08005 const xmlChar **nsArray = NULL; 08006 xmlNsPtr *nsList = NULL; 08007 /* 08008 * Compile the XPath expression. 08009 */ 08010 /* 08011 * TODO: We need the array of in-scope namespaces for compilation. 08012 * TODO: Call xmlPatterncompile with different options for selector/ 08013 * field. 08014 */ 08015 if (attr == NULL) 08016 nsList = NULL; 08017 else 08018 nsList = xmlGetNsList(attr->doc, attr->parent); 08019 /* 08020 * Build an array of prefixes and namespaces. 08021 */ 08022 if (nsList != NULL) { 08023 int i, count = 0; 08024 08025 for (i = 0; nsList[i] != NULL; i++) 08026 count++; 08027 08028 nsArray = (const xmlChar **) xmlMalloc( 08029 (count * 2 + 1) * sizeof(const xmlChar *)); 08030 if (nsArray == NULL) { 08031 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 08032 NULL); 08033 xmlFree(nsList); 08034 return (-1); 08035 } 08036 for (i = 0; i < count; i++) { 08037 nsArray[2 * i] = nsList[i]->href; 08038 nsArray[2 * i + 1] = nsList[i]->prefix; 08039 } 08040 nsArray[count * 2] = NULL; 08041 xmlFree(nsList); 08042 } 08043 /* 08044 * TODO: Differentiate between "selector" and "field". 08045 */ 08046 if (isField) 08047 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 08048 NULL, XML_PATTERN_XSFIELD, nsArray); 08049 else 08050 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 08051 NULL, XML_PATTERN_XSSEL, nsArray); 08052 if (nsArray != NULL) 08053 xmlFree((xmlChar **) nsArray); 08054 08055 if (selector->xpathComp == NULL) { 08056 xmlSchemaPCustomErr(ctxt, 08057 /* TODO: Adjust error code? */ 08058 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 08059 NULL, node, 08060 "The XPath expression '%s' could not be " 08061 "compiled", selector->xpath); 08062 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 08063 } 08064 } 08065 return (0); 08066 } 08067 08068 #define ADD_ANNOTATION(annot) \ 08069 xmlSchemaAnnotPtr cur = item->annot; \ 08070 if (item->annot == NULL) { \ 08071 item->annot = annot; \ 08072 return (annot); \ 08073 } \ 08074 cur = item->annot; \ 08075 if (cur->next != NULL) { \ 08076 cur = cur->next; \ 08077 } \ 08078 cur->next = annot; 08079 08089 static xmlSchemaAnnotPtr 08090 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 08091 xmlSchemaAnnotPtr annot) 08092 { 08093 if ((annItem == NULL) || (annot == NULL)) 08094 return (NULL); 08095 switch (annItem->type) { 08096 case XML_SCHEMA_TYPE_ELEMENT: { 08097 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 08098 ADD_ANNOTATION(annot) 08099 } 08100 break; 08101 case XML_SCHEMA_TYPE_ATTRIBUTE: { 08102 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 08103 ADD_ANNOTATION(annot) 08104 } 08105 break; 08106 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 08107 case XML_SCHEMA_TYPE_ANY: { 08108 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 08109 ADD_ANNOTATION(annot) 08110 } 08111 break; 08112 case XML_SCHEMA_TYPE_PARTICLE: 08113 case XML_SCHEMA_TYPE_IDC_KEY: 08114 case XML_SCHEMA_TYPE_IDC_KEYREF: 08115 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 08116 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 08117 ADD_ANNOTATION(annot) 08118 } 08119 break; 08120 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 08121 xmlSchemaAttributeGroupPtr item = 08122 (xmlSchemaAttributeGroupPtr) annItem; 08123 ADD_ANNOTATION(annot) 08124 } 08125 break; 08126 case XML_SCHEMA_TYPE_NOTATION: { 08127 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 08128 ADD_ANNOTATION(annot) 08129 } 08130 break; 08131 case XML_SCHEMA_FACET_MININCLUSIVE: 08132 case XML_SCHEMA_FACET_MINEXCLUSIVE: 08133 case XML_SCHEMA_FACET_MAXINCLUSIVE: 08134 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 08135 case XML_SCHEMA_FACET_TOTALDIGITS: 08136 case XML_SCHEMA_FACET_FRACTIONDIGITS: 08137 case XML_SCHEMA_FACET_PATTERN: 08138 case XML_SCHEMA_FACET_ENUMERATION: 08139 case XML_SCHEMA_FACET_WHITESPACE: 08140 case XML_SCHEMA_FACET_LENGTH: 08141 case XML_SCHEMA_FACET_MAXLENGTH: 08142 case XML_SCHEMA_FACET_MINLENGTH: { 08143 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 08144 ADD_ANNOTATION(annot) 08145 } 08146 break; 08147 case XML_SCHEMA_TYPE_SIMPLE: 08148 case XML_SCHEMA_TYPE_COMPLEX: { 08149 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 08150 ADD_ANNOTATION(annot) 08151 } 08152 break; 08153 case XML_SCHEMA_TYPE_GROUP: { 08154 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 08155 ADD_ANNOTATION(annot) 08156 } 08157 break; 08158 case XML_SCHEMA_TYPE_SEQUENCE: 08159 case XML_SCHEMA_TYPE_CHOICE: 08160 case XML_SCHEMA_TYPE_ALL: { 08161 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 08162 ADD_ANNOTATION(annot) 08163 } 08164 break; 08165 default: 08166 xmlSchemaPCustomErr(NULL, 08167 XML_SCHEMAP_INTERNAL, 08168 NULL, NULL, 08169 "Internal error: xmlSchemaAddAnnotation, " 08170 "The item is not a annotated schema component", NULL); 08171 break; 08172 } 08173 return (annot); 08174 } 08175 08187 static xmlSchemaIDCSelectPtr 08188 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 08189 xmlSchemaIDCPtr idc, 08190 xmlNodePtr node, 08191 int isField) 08192 { 08193 xmlSchemaIDCSelectPtr item; 08194 xmlNodePtr child = NULL; 08195 xmlAttrPtr attr; 08196 08197 /* 08198 * Check for illegal attributes. 08199 */ 08200 attr = node->properties; 08201 while (attr != NULL) { 08202 if (attr->ns == NULL) { 08203 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 08204 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 08205 xmlSchemaPIllegalAttrErr(ctxt, 08206 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08207 } 08208 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 08209 xmlSchemaPIllegalAttrErr(ctxt, 08210 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08211 } 08212 attr = attr->next; 08213 } 08214 /* 08215 * Create the item. 08216 */ 08217 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 08218 if (item == NULL) { 08219 xmlSchemaPErrMemory(ctxt, 08220 "allocating a 'selector' of an identity-constraint definition", 08221 NULL); 08222 return (NULL); 08223 } 08224 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 08225 /* 08226 * Attribute "xpath" (mandatory). 08227 */ 08228 attr = xmlSchemaGetPropNode(node, "xpath"); 08229 if (attr == NULL) { 08230 xmlSchemaPMissingAttrErr(ctxt, 08231 XML_SCHEMAP_S4S_ATTR_MISSING, 08232 NULL, node, 08233 "name", NULL); 08234 } else { 08235 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 08236 /* 08237 * URGENT TODO: "field"s have an other syntax than "selector"s. 08238 */ 08239 08240 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 08241 isField) == -1) { 08242 xmlSchemaPErr(ctxt, 08243 (xmlNodePtr) attr, 08244 XML_SCHEMAP_INTERNAL, 08245 "Internal error: xmlSchemaParseIDCSelectorAndField, " 08246 "validating the XPath expression of a IDC selector.\n", 08247 NULL, NULL); 08248 } 08249 08250 } 08251 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 08252 /* 08253 * And now for the children... 08254 */ 08255 child = node->children; 08256 if (IS_SCHEMA(child, "annotation")) { 08257 /* 08258 * Add the annotation to the parent IDC. 08259 */ 08260 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 08261 xmlSchemaParseAnnotation(ctxt, child, 1)); 08262 child = child->next; 08263 } 08264 if (child != NULL) { 08265 xmlSchemaPContentErr(ctxt, 08266 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 08267 NULL, node, child, 08268 NULL, "(annotation?)"); 08269 } 08270 08271 return (item); 08272 } 08273 08284 static xmlSchemaIDCPtr 08285 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 08286 xmlSchemaPtr schema, 08287 xmlNodePtr node, 08288 xmlSchemaTypeType idcCategory, 08289 const xmlChar *targetNamespace) 08290 { 08291 xmlSchemaIDCPtr item = NULL; 08292 xmlNodePtr child = NULL; 08293 xmlAttrPtr attr; 08294 const xmlChar *name = NULL; 08295 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 08296 08297 /* 08298 * Check for illegal attributes. 08299 */ 08300 attr = node->properties; 08301 while (attr != NULL) { 08302 if (attr->ns == NULL) { 08303 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 08304 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 08305 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 08306 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 08307 xmlSchemaPIllegalAttrErr(ctxt, 08308 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08309 } 08310 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 08311 xmlSchemaPIllegalAttrErr(ctxt, 08312 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08313 } 08314 attr = attr->next; 08315 } 08316 /* 08317 * Attribute "name" (mandatory). 08318 */ 08319 attr = xmlSchemaGetPropNode(node, "name"); 08320 if (attr == NULL) { 08321 xmlSchemaPMissingAttrErr(ctxt, 08322 XML_SCHEMAP_S4S_ATTR_MISSING, 08323 NULL, node, 08324 "name", NULL); 08325 return (NULL); 08326 } else if (xmlSchemaPValAttrNode(ctxt, 08327 NULL, attr, 08328 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 08329 return (NULL); 08330 } 08331 /* Create the component. */ 08332 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 08333 idcCategory, node); 08334 if (item == NULL) 08335 return(NULL); 08336 08337 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 08338 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 08339 /* 08340 * Attribute "refer" (mandatory). 08341 */ 08342 attr = xmlSchemaGetPropNode(node, "refer"); 08343 if (attr == NULL) { 08344 xmlSchemaPMissingAttrErr(ctxt, 08345 XML_SCHEMAP_S4S_ATTR_MISSING, 08346 NULL, node, 08347 "refer", NULL); 08348 } else { 08349 /* 08350 * Create a reference item. 08351 */ 08352 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 08353 NULL, NULL); 08354 if (item->ref == NULL) 08355 return (NULL); 08356 xmlSchemaPValAttrNodeQName(ctxt, schema, 08357 NULL, attr, 08358 &(item->ref->targetNamespace), 08359 &(item->ref->name)); 08360 xmlSchemaCheckReference(ctxt, schema, node, attr, 08361 item->ref->targetNamespace); 08362 } 08363 } 08364 /* 08365 * And now for the children... 08366 */ 08367 child = node->children; 08368 if (IS_SCHEMA(child, "annotation")) { 08369 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 08370 child = child->next; 08371 } 08372 if (child == NULL) { 08373 xmlSchemaPContentErr(ctxt, 08374 XML_SCHEMAP_S4S_ELEM_MISSING, 08375 NULL, node, child, 08376 "A child element is missing", 08377 "(annotation?, (selector, field+))"); 08378 } 08379 /* 08380 * Child element <selector>. 08381 */ 08382 if (IS_SCHEMA(child, "selector")) { 08383 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 08384 item, child, 0); 08385 child = child->next; 08386 /* 08387 * Child elements <field>. 08388 */ 08389 if (IS_SCHEMA(child, "field")) { 08390 do { 08391 field = xmlSchemaParseIDCSelectorAndField(ctxt, 08392 item, child, 1); 08393 if (field != NULL) { 08394 field->index = item->nbFields; 08395 item->nbFields++; 08396 if (lastField != NULL) 08397 lastField->next = field; 08398 else 08399 item->fields = field; 08400 lastField = field; 08401 } 08402 child = child->next; 08403 } while (IS_SCHEMA(child, "field")); 08404 } else { 08405 xmlSchemaPContentErr(ctxt, 08406 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 08407 NULL, node, child, 08408 NULL, "(annotation?, (selector, field+))"); 08409 } 08410 } 08411 if (child != NULL) { 08412 xmlSchemaPContentErr(ctxt, 08413 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 08414 NULL, node, child, 08415 NULL, "(annotation?, (selector, field+))"); 08416 } 08417 08418 return (item); 08419 } 08420 08434 static xmlSchemaBasicItemPtr 08435 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 08436 xmlNodePtr node, int *isElemRef, int topLevel) 08437 { 08438 xmlSchemaElementPtr decl = NULL; 08439 xmlSchemaParticlePtr particle = NULL; 08440 xmlSchemaAnnotPtr annot = NULL; 08441 xmlNodePtr child = NULL; 08442 xmlAttrPtr attr, nameAttr; 08443 int min, max, isRef = 0; 08444 xmlChar *des = NULL; 08445 08446 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 08447 /* TODO: Complete implementation of 3.3.6 */ 08448 08449 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 08450 return (NULL); 08451 08452 if (isElemRef != NULL) 08453 *isElemRef = 0; 08454 /* 08455 * If we get a "ref" attribute on a local <element> we will assume it's 08456 * a reference - even if there's a "name" attribute; this seems to be more 08457 * robust. 08458 */ 08459 nameAttr = xmlSchemaGetPropNode(node, "name"); 08460 attr = xmlSchemaGetPropNode(node, "ref"); 08461 if ((topLevel) || (attr == NULL)) { 08462 if (nameAttr == NULL) { 08463 xmlSchemaPMissingAttrErr(ctxt, 08464 XML_SCHEMAP_S4S_ATTR_MISSING, 08465 NULL, node, "name", NULL); 08466 return (NULL); 08467 } 08468 } else 08469 isRef = 1; 08470 08471 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 08472 child = node->children; 08473 if (IS_SCHEMA(child, "annotation")) { 08474 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 08475 child = child->next; 08476 } 08477 /* 08478 * Skip particle part if a global declaration. 08479 */ 08480 if (topLevel) 08481 goto declaration_part; 08482 /* 08483 * The particle part ================================================== 08484 */ 08485 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 08486 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 08487 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 08488 particle = xmlSchemaAddParticle(ctxt, node, min, max); 08489 if (particle == NULL) 08490 goto return_null; 08491 08492 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 08493 08494 if (isRef) { 08495 const xmlChar *refNs = NULL, *ref = NULL; 08496 xmlSchemaQNameRefPtr refer = NULL; 08497 /* 08498 * The reference part ============================================= 08499 */ 08500 if (isElemRef != NULL) 08501 *isElemRef = 1; 08502 08503 xmlSchemaPValAttrNodeQName(ctxt, schema, 08504 NULL, attr, &refNs, &ref); 08505 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 08506 /* 08507 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 08508 */ 08509 if (nameAttr != NULL) { 08510 xmlSchemaPMutualExclAttrErr(ctxt, 08511 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 08512 } 08513 /* 08514 * Check for illegal attributes. 08515 */ 08516 attr = node->properties; 08517 while (attr != NULL) { 08518 if (attr->ns == NULL) { 08519 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 08520 xmlStrEqual(attr->name, BAD_CAST "name") || 08521 xmlStrEqual(attr->name, BAD_CAST "id") || 08522 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 08523 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 08524 { 08525 attr = attr->next; 08526 continue; 08527 } else { 08528 /* SPEC (3.3.3 : 2.2) */ 08529 xmlSchemaPCustomAttrErr(ctxt, 08530 XML_SCHEMAP_SRC_ELEMENT_2_2, 08531 NULL, NULL, attr, 08532 "Only the attributes 'minOccurs', 'maxOccurs' and " 08533 "'id' are allowed in addition to 'ref'"); 08534 break; 08535 } 08536 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 08537 xmlSchemaPIllegalAttrErr(ctxt, 08538 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08539 } 08540 attr = attr->next; 08541 } 08542 /* 08543 * No children except <annotation> expected. 08544 */ 08545 if (child != NULL) { 08546 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 08547 NULL, node, child, NULL, "(annotation?)"); 08548 } 08549 if ((min == 0) && (max == 0)) 08550 goto return_null; 08551 /* 08552 * Create the reference item and attach it to the particle. 08553 */ 08554 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 08555 ref, refNs); 08556 if (refer == NULL) 08557 goto return_null; 08558 particle->children = (xmlSchemaTreeItemPtr) refer; 08559 particle->annot = annot; 08560 /* 08561 * Add the particle to pending components, since the reference 08562 * need to be resolved. 08563 */ 08564 WXS_ADD_PENDING(ctxt, particle); 08565 return ((xmlSchemaBasicItemPtr) particle); 08566 } 08567 /* 08568 * The declaration part =============================================== 08569 */ 08570 declaration_part: 08571 { 08572 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 08573 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 08574 08575 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 08576 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 08577 goto return_null; 08578 /* 08579 * Evaluate the target namespace. 08580 */ 08581 if (topLevel) { 08582 ns = ctxt->targetNamespace; 08583 } else { 08584 attr = xmlSchemaGetPropNode(node, "form"); 08585 if (attr != NULL) { 08586 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 08587 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 08588 ns = ctxt->targetNamespace; 08589 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 08590 xmlSchemaPSimpleTypeErr(ctxt, 08591 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 08592 NULL, (xmlNodePtr) attr, 08593 NULL, "(qualified | unqualified)", 08594 attrValue, NULL, NULL, NULL); 08595 } 08596 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 08597 ns = ctxt->targetNamespace; 08598 } 08599 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 08600 if (decl == NULL) { 08601 goto return_null; 08602 } 08603 /* 08604 * Check for illegal attributes. 08605 */ 08606 attr = node->properties; 08607 while (attr != NULL) { 08608 if (attr->ns == NULL) { 08609 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 08610 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 08611 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 08612 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 08613 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 08614 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 08615 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 08616 { 08617 if (topLevel == 0) { 08618 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 08619 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 08620 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 08621 { 08622 xmlSchemaPIllegalAttrErr(ctxt, 08623 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08624 } 08625 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 08626 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 08627 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 08628 08629 xmlSchemaPIllegalAttrErr(ctxt, 08630 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08631 } 08632 } 08633 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 08634 08635 xmlSchemaPIllegalAttrErr(ctxt, 08636 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08637 } 08638 attr = attr->next; 08639 } 08640 /* 08641 * Extract/validate attributes. 08642 */ 08643 if (topLevel) { 08644 /* 08645 * Process top attributes of global element declarations here. 08646 */ 08647 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 08648 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 08649 xmlSchemaPValAttrQName(ctxt, schema, 08650 NULL, node, "substitutionGroup", 08651 &(decl->substGroupNs), &(decl->substGroup)); 08652 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 08653 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 08654 /* 08655 * Attribute "final". 08656 */ 08657 attr = xmlSchemaGetPropNode(node, "final"); 08658 if (attr == NULL) { 08659 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 08660 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 08661 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 08662 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 08663 } else { 08664 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 08665 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 08666 -1, 08667 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 08668 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 08669 xmlSchemaPSimpleTypeErr(ctxt, 08670 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 08671 NULL, (xmlNodePtr) attr, 08672 NULL, "(#all | List of (extension | restriction))", 08673 attrValue, NULL, NULL, NULL); 08674 } 08675 } 08676 } 08677 /* 08678 * Attribute "block". 08679 */ 08680 attr = xmlSchemaGetPropNode(node, "block"); 08681 if (attr == NULL) { 08682 /* 08683 * Apply default "block" values. 08684 */ 08685 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 08686 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 08687 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 08688 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 08689 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 08690 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 08691 } else { 08692 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 08693 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 08694 -1, 08695 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 08696 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 08697 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 08698 xmlSchemaPSimpleTypeErr(ctxt, 08699 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 08700 NULL, (xmlNodePtr) attr, 08701 NULL, "(#all | List of (extension | " 08702 "restriction | substitution))", attrValue, 08703 NULL, NULL, NULL); 08704 } 08705 } 08706 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 08707 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 08708 08709 attr = xmlSchemaGetPropNode(node, "type"); 08710 if (attr != NULL) { 08711 xmlSchemaPValAttrNodeQName(ctxt, schema, 08712 NULL, attr, 08713 &(decl->namedTypeNs), &(decl->namedType)); 08714 xmlSchemaCheckReference(ctxt, schema, node, 08715 attr, decl->namedTypeNs); 08716 } 08717 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 08718 attr = xmlSchemaGetPropNode(node, "fixed"); 08719 if (attr != NULL) { 08720 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 08721 if (decl->value != NULL) { 08722 /* 08723 * 3.3.3 : 1 08724 * default and fixed must not both be present. 08725 */ 08726 xmlSchemaPMutualExclAttrErr(ctxt, 08727 XML_SCHEMAP_SRC_ELEMENT_1, 08728 NULL, attr, "default", "fixed"); 08729 } else { 08730 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 08731 decl->value = fixed; 08732 } 08733 } 08734 /* 08735 * And now for the children... 08736 */ 08737 if (IS_SCHEMA(child, "complexType")) { 08738 /* 08739 * 3.3.3 : 3 08740 * "type" and either <simpleType> or <complexType> are mutually 08741 * exclusive 08742 */ 08743 if (decl->namedType != NULL) { 08744 xmlSchemaPContentErr(ctxt, 08745 XML_SCHEMAP_SRC_ELEMENT_3, 08746 NULL, node, child, 08747 "The attribute 'type' and the <complexType> child are " 08748 "mutually exclusive", NULL); 08749 } else 08750 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 08751 child = child->next; 08752 } else if (IS_SCHEMA(child, "simpleType")) { 08753 /* 08754 * 3.3.3 : 3 08755 * "type" and either <simpleType> or <complexType> are 08756 * mutually exclusive 08757 */ 08758 if (decl->namedType != NULL) { 08759 xmlSchemaPContentErr(ctxt, 08760 XML_SCHEMAP_SRC_ELEMENT_3, 08761 NULL, node, child, 08762 "The attribute 'type' and the <simpleType> child are " 08763 "mutually exclusive", NULL); 08764 } else 08765 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 08766 child = child->next; 08767 } 08768 while ((IS_SCHEMA(child, "unique")) || 08769 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 08770 if (IS_SCHEMA(child, "unique")) { 08771 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 08772 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 08773 } else if (IS_SCHEMA(child, "key")) { 08774 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 08775 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 08776 } else if (IS_SCHEMA(child, "keyref")) { 08777 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 08778 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 08779 } 08780 if (lastIDC != NULL) 08781 lastIDC->next = curIDC; 08782 else 08783 decl->idcs = (void *) curIDC; 08784 lastIDC = curIDC; 08785 child = child->next; 08786 } 08787 if (child != NULL) { 08788 xmlSchemaPContentErr(ctxt, 08789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 08790 NULL, node, child, 08791 NULL, "(annotation?, ((simpleType | complexType)?, " 08792 "(unique | key | keyref)*))"); 08793 } 08794 decl->annot = annot; 08795 } 08796 /* 08797 * NOTE: Element Declaration Representation OK 4. will be checked at a 08798 * different layer. 08799 */ 08800 FREE_AND_NULL(des) 08801 if (topLevel) 08802 return ((xmlSchemaBasicItemPtr) decl); 08803 else { 08804 particle->children = (xmlSchemaTreeItemPtr) decl; 08805 return ((xmlSchemaBasicItemPtr) particle); 08806 } 08807 08808 return_null: 08809 FREE_AND_NULL(des); 08810 if (annot != NULL) { 08811 if (particle != NULL) 08812 particle->annot = NULL; 08813 if (decl != NULL) 08814 decl->annot = NULL; 08815 xmlSchemaFreeAnnot(annot); 08816 } 08817 return (NULL); 08818 } 08819 08832 static int 08833 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 08834 xmlNodePtr node) 08835 { 08836 xmlSchemaTypePtr type; 08837 xmlNodePtr child = NULL; 08838 xmlAttrPtr attr; 08839 const xmlChar *cur = NULL; 08840 08841 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 08842 return (-1); 08843 /* Not a component, don't create it. */ 08844 type = ctxt->ctxtType; 08845 /* 08846 * Mark the simple type as being of variety "union". 08847 */ 08848 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 08849 /* 08850 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 08851 * then the �simple ur-type definition�." 08852 */ 08853 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 08854 /* 08855 * Check for illegal attributes. 08856 */ 08857 attr = node->properties; 08858 while (attr != NULL) { 08859 if (attr->ns == NULL) { 08860 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 08861 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 08862 xmlSchemaPIllegalAttrErr(ctxt, 08863 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08864 } 08865 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 08866 xmlSchemaPIllegalAttrErr(ctxt, 08867 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 08868 } 08869 attr = attr->next; 08870 } 08871 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 08872 /* 08873 * Attribute "memberTypes". This is a list of QNames. 08874 * TODO: Check the value to contain anything. 08875 */ 08876 attr = xmlSchemaGetPropNode(node, "memberTypes"); 08877 if (attr != NULL) { 08878 const xmlChar *end; 08879 xmlChar *tmp; 08880 const xmlChar *localName, *nsName; 08881 xmlSchemaTypeLinkPtr link, lastLink = NULL; 08882 xmlSchemaQNameRefPtr ref; 08883 08884 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 08885 type->base = cur; 08886 do { 08887 while (IS_BLANK_CH(*cur)) 08888 cur++; 08889 end = cur; 08890 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 08891 end++; 08892 if (end == cur) 08893 break; 08894 tmp = xmlStrndup(cur, end - cur); 08895 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 08896 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 08897 /* 08898 * Create the member type link. 08899 */ 08900 link = (xmlSchemaTypeLinkPtr) 08901 xmlMalloc(sizeof(xmlSchemaTypeLink)); 08902 if (link == NULL) { 08903 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 08904 "allocating a type link", NULL); 08905 return (-1); 08906 } 08907 link->type = NULL; 08908 link->next = NULL; 08909 if (lastLink == NULL) 08910 type->memberTypes = link; 08911 else 08912 lastLink->next = link; 08913 lastLink = link; 08914 /* 08915 * Create a reference item. 08916 */ 08917 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 08918 localName, nsName); 08919 if (ref == NULL) { 08920 FREE_AND_NULL(tmp) 08921 return (-1); 08922 } 08923 /* 08924 * Assign the reference to the link, it will be resolved 08925 * later during fixup of the union simple type. 08926 */ 08927 link->type = (xmlSchemaTypePtr) ref; 08928 } 08929 FREE_AND_NULL(tmp) 08930 cur = end; 08931 } while (*cur != 0); 08932 08933 } 08934 /* 08935 * And now for the children... 08936 */ 08937 child = node->children; 08938 if (IS_SCHEMA(child, "annotation")) { 08939 /* 08940 * Add the annotation to the simple type ancestor. 08941 */ 08942 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 08943 xmlSchemaParseAnnotation(ctxt, child, 1)); 08944 child = child->next; 08945 } 08946 if (IS_SCHEMA(child, "simpleType")) { 08947 xmlSchemaTypePtr subtype, last = NULL; 08948 08949 /* 08950 * Anchor the member types in the "subtypes" field of the 08951 * simple type. 08952 */ 08953 while (IS_SCHEMA(child, "simpleType")) { 08954 subtype = (xmlSchemaTypePtr) 08955 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 08956 if (subtype != NULL) { 08957 if (last == NULL) { 08958 type->subtypes = subtype; 08959 last = subtype; 08960 } else { 08961 last->next = subtype; 08962 last = subtype; 08963 } 08964 last->next = NULL; 08965 } 08966 child = child->next; 08967 } 08968 } 08969 if (child != NULL) { 08970 xmlSchemaPContentErr(ctxt, 08971 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 08972 NULL, node, child, NULL, "(annotation?, simpleType*)"); 08973 } 08974 if ((attr == NULL) && (type->subtypes == NULL)) { 08975 /* 08976 * src-union-memberTypes-or-simpleTypes 08977 * Either the memberTypes [attribute] of the <union> element must 08978 * be non-empty or there must be at least one simpleType [child]. 08979 */ 08980 xmlSchemaPCustomErr(ctxt, 08981 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 08982 NULL, node, 08983 "Either the attribute 'memberTypes' or " 08984 "at least one <simpleType> child must be present", NULL); 08985 } 08986 return (0); 08987 } 08988 09001 static xmlSchemaTypePtr 09002 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 09003 xmlNodePtr node) 09004 { 09005 xmlSchemaTypePtr type; 09006 xmlNodePtr child = NULL; 09007 xmlAttrPtr attr; 09008 09009 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 09010 return (NULL); 09011 /* Not a component, don't create it. */ 09012 type = ctxt->ctxtType; 09013 /* 09014 * Mark the type as being of variety "list". 09015 */ 09016 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 09017 /* 09018 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 09019 * then the �simple ur-type definition�." 09020 */ 09021 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 09022 /* 09023 * Check for illegal attributes. 09024 */ 09025 attr = node->properties; 09026 while (attr != NULL) { 09027 if (attr->ns == NULL) { 09028 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 09029 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 09030 xmlSchemaPIllegalAttrErr(ctxt, 09031 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09032 } 09033 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 09034 xmlSchemaPIllegalAttrErr(ctxt, 09035 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09036 } 09037 attr = attr->next; 09038 } 09039 09040 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 09041 09042 /* 09043 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 09044 * fields for holding the reference to the itemType. 09045 * 09046 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 09047 * the "ref" fields. 09048 */ 09049 xmlSchemaPValAttrQName(ctxt, schema, NULL, 09050 node, "itemType", &(type->baseNs), &(type->base)); 09051 /* 09052 * And now for the children... 09053 */ 09054 child = node->children; 09055 if (IS_SCHEMA(child, "annotation")) { 09056 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 09057 xmlSchemaParseAnnotation(ctxt, child, 1)); 09058 child = child->next; 09059 } 09060 if (IS_SCHEMA(child, "simpleType")) { 09061 /* 09062 * src-list-itemType-or-simpleType 09063 * Either the itemType [attribute] or the <simpleType> [child] of 09064 * the <list> element must be present, but not both. 09065 */ 09066 if (type->base != NULL) { 09067 xmlSchemaPCustomErr(ctxt, 09068 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 09069 NULL, node, 09070 "The attribute 'itemType' and the <simpleType> child " 09071 "are mutually exclusive", NULL); 09072 } else { 09073 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 09074 } 09075 child = child->next; 09076 } else if (type->base == NULL) { 09077 xmlSchemaPCustomErr(ctxt, 09078 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 09079 NULL, node, 09080 "Either the attribute 'itemType' or the <simpleType> child " 09081 "must be present", NULL); 09082 } 09083 if (child != NULL) { 09084 xmlSchemaPContentErr(ctxt, 09085 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 09086 NULL, node, child, NULL, "(annotation?, simpleType?)"); 09087 } 09088 if ((type->base == NULL) && 09089 (type->subtypes == NULL) && 09090 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 09091 xmlSchemaPCustomErr(ctxt, 09092 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 09093 NULL, node, 09094 "Either the attribute 'itemType' or the <simpleType> child " 09095 "must be present", NULL); 09096 } 09097 return (NULL); 09098 } 09099 09112 static xmlSchemaTypePtr 09113 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 09114 xmlNodePtr node, int topLevel) 09115 { 09116 xmlSchemaTypePtr type, oldCtxtType; 09117 xmlNodePtr child = NULL; 09118 const xmlChar *attrValue = NULL; 09119 xmlAttrPtr attr; 09120 int hasRestriction = 0; 09121 09122 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 09123 return (NULL); 09124 09125 if (topLevel) { 09126 attr = xmlSchemaGetPropNode(node, "name"); 09127 if (attr == NULL) { 09128 xmlSchemaPMissingAttrErr(ctxt, 09129 XML_SCHEMAP_S4S_ATTR_MISSING, 09130 NULL, node, 09131 "name", NULL); 09132 return (NULL); 09133 } else { 09134 if (xmlSchemaPValAttrNode(ctxt, 09135 NULL, attr, 09136 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 09137 return (NULL); 09138 /* 09139 * Skip built-in types. 09140 */ 09141 if (ctxt->isS4S) { 09142 xmlSchemaTypePtr biType; 09143 09144 if (ctxt->isRedefine) { 09145 /* 09146 * REDEFINE: Disallow redefinition of built-in-types. 09147 * TODO: It seems that the spec does not say anything 09148 * about this case. 09149 */ 09150 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 09151 NULL, node, 09152 "Redefinition of built-in simple types is not " 09153 "supported", NULL); 09154 return(NULL); 09155 } 09156 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 09157 if (biType != NULL) 09158 return (biType); 09159 } 09160 } 09161 } 09162 /* 09163 * TargetNamespace: 09164 * SPEC "The �actual value� of the targetNamespace [attribute] 09165 * of the <schema> ancestor element information item if present, 09166 * otherwise �absent�. 09167 */ 09168 if (topLevel == 0) { 09169 #ifdef ENABLE_NAMED_LOCALS 09170 char buf[40]; 09171 #endif 09172 /* 09173 * Parse as local simple type definition. 09174 */ 09175 #ifdef ENABLE_NAMED_LOCALS 09176 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 09177 type = xmlSchemaAddType(ctxt, schema, 09178 XML_SCHEMA_TYPE_SIMPLE, 09179 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 09180 ctxt->targetNamespace, node, 0); 09181 #else 09182 type = xmlSchemaAddType(ctxt, schema, 09183 XML_SCHEMA_TYPE_SIMPLE, 09184 NULL, ctxt->targetNamespace, node, 0); 09185 #endif 09186 if (type == NULL) 09187 return (NULL); 09188 type->type = XML_SCHEMA_TYPE_SIMPLE; 09189 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 09190 /* 09191 * Check for illegal attributes. 09192 */ 09193 attr = node->properties; 09194 while (attr != NULL) { 09195 if (attr->ns == NULL) { 09196 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 09197 xmlSchemaPIllegalAttrErr(ctxt, 09198 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09199 } 09200 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 09201 xmlSchemaPIllegalAttrErr(ctxt, 09202 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09203 } 09204 attr = attr->next; 09205 } 09206 } else { 09207 /* 09208 * Parse as global simple type definition. 09209 * 09210 * Note that attrValue is the value of the attribute "name" here. 09211 */ 09212 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 09213 attrValue, ctxt->targetNamespace, node, 1); 09214 if (type == NULL) 09215 return (NULL); 09216 type->type = XML_SCHEMA_TYPE_SIMPLE; 09217 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 09218 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 09219 /* 09220 * Check for illegal attributes. 09221 */ 09222 attr = node->properties; 09223 while (attr != NULL) { 09224 if (attr->ns == NULL) { 09225 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 09226 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 09227 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 09228 xmlSchemaPIllegalAttrErr(ctxt, 09229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09230 } 09231 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 09232 xmlSchemaPIllegalAttrErr(ctxt, 09233 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09234 } 09235 attr = attr->next; 09236 } 09237 /* 09238 * Attribute "final". 09239 */ 09240 attr = xmlSchemaGetPropNode(node, "final"); 09241 if (attr == NULL) { 09242 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 09243 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 09244 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 09245 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 09246 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 09247 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 09248 } else { 09249 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 09250 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 09251 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 09252 XML_SCHEMAS_TYPE_FINAL_LIST, 09253 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 09254 09255 xmlSchemaPSimpleTypeErr(ctxt, 09256 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 09257 WXS_BASIC_CAST type, (xmlNodePtr) attr, 09258 NULL, "(#all | List of (list | union | restriction)", 09259 attrValue, NULL, NULL, NULL); 09260 } 09261 } 09262 } 09263 type->targetNamespace = ctxt->targetNamespace; 09264 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 09265 /* 09266 * And now for the children... 09267 */ 09268 oldCtxtType = ctxt->ctxtType; 09269 09270 ctxt->ctxtType = type; 09271 09272 child = node->children; 09273 if (IS_SCHEMA(child, "annotation")) { 09274 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 09275 child = child->next; 09276 } 09277 if (child == NULL) { 09278 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 09279 NULL, node, child, NULL, 09280 "(annotation?, (restriction | list | union))"); 09281 } else if (IS_SCHEMA(child, "restriction")) { 09282 xmlSchemaParseRestriction(ctxt, schema, child, 09283 XML_SCHEMA_TYPE_SIMPLE); 09284 hasRestriction = 1; 09285 child = child->next; 09286 } else if (IS_SCHEMA(child, "list")) { 09287 xmlSchemaParseList(ctxt, schema, child); 09288 child = child->next; 09289 } else if (IS_SCHEMA(child, "union")) { 09290 xmlSchemaParseUnion(ctxt, schema, child); 09291 child = child->next; 09292 } 09293 if (child != NULL) { 09294 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 09295 NULL, node, child, NULL, 09296 "(annotation?, (restriction | list | union))"); 09297 } 09298 /* 09299 * REDEFINE: SPEC src-redefine (5) 09300 * "Within the [children], each <simpleType> must have a 09301 * <restriction> among its [children] ... the �actual value� of whose 09302 * base [attribute] must be the same as the �actual value� of its own 09303 * name attribute plus target namespace;" 09304 */ 09305 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 09306 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 09307 NULL, node, "This is a redefinition, thus the " 09308 "<simpleType> must have a <restriction> child", NULL); 09309 } 09310 09311 ctxt->ctxtType = oldCtxtType; 09312 return (type); 09313 } 09314 09326 static xmlSchemaTreeItemPtr 09327 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 09328 xmlSchemaPtr schema, 09329 xmlNodePtr node) 09330 { 09331 xmlSchemaParticlePtr item; 09332 xmlNodePtr child = NULL; 09333 xmlAttrPtr attr; 09334 const xmlChar *ref = NULL, *refNs = NULL; 09335 int min, max; 09336 09337 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 09338 return (NULL); 09339 09340 attr = xmlSchemaGetPropNode(node, "ref"); 09341 if (attr == NULL) { 09342 xmlSchemaPMissingAttrErr(ctxt, 09343 XML_SCHEMAP_S4S_ATTR_MISSING, 09344 NULL, node, "ref", NULL); 09345 return (NULL); 09346 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 09347 attr, &refNs, &ref) != 0) { 09348 return (NULL); 09349 } 09350 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 09351 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 09352 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 09353 "(xs:nonNegativeInteger | unbounded)"); 09354 /* 09355 * Check for illegal attributes. 09356 */ 09357 attr = node->properties; 09358 while (attr != NULL) { 09359 if (attr->ns == NULL) { 09360 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 09361 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 09362 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 09363 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 09364 xmlSchemaPIllegalAttrErr(ctxt, 09365 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09366 } 09367 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 09368 xmlSchemaPIllegalAttrErr(ctxt, 09369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09370 } 09371 attr = attr->next; 09372 } 09373 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 09374 item = xmlSchemaAddParticle(ctxt, node, min, max); 09375 if (item == NULL) 09376 return (NULL); 09377 /* 09378 * Create a qname-reference and set as the term; it will be substituted 09379 * for the model group after the reference has been resolved. 09380 */ 09381 item->children = (xmlSchemaTreeItemPtr) 09382 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 09383 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 09384 /* 09385 * And now for the children... 09386 */ 09387 child = node->children; 09388 /* TODO: Is annotation even allowed for a model group reference? */ 09389 if (IS_SCHEMA(child, "annotation")) { 09390 /* 09391 * TODO: What to do exactly with the annotation? 09392 */ 09393 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 09394 child = child->next; 09395 } 09396 if (child != NULL) { 09397 xmlSchemaPContentErr(ctxt, 09398 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 09399 NULL, node, child, NULL, 09400 "(annotation?)"); 09401 } 09402 /* 09403 * Corresponds to no component at all if minOccurs==maxOccurs==0. 09404 */ 09405 if ((min == 0) && (max == 0)) 09406 return (NULL); 09407 09408 return ((xmlSchemaTreeItemPtr) item); 09409 } 09410 09428 static xmlSchemaModelGroupDefPtr 09429 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 09430 xmlSchemaPtr schema, 09431 xmlNodePtr node) 09432 { 09433 xmlSchemaModelGroupDefPtr item; 09434 xmlNodePtr child = NULL; 09435 xmlAttrPtr attr; 09436 const xmlChar *name; 09437 09438 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 09439 return (NULL); 09440 09441 attr = xmlSchemaGetPropNode(node, "name"); 09442 if (attr == NULL) { 09443 xmlSchemaPMissingAttrErr(ctxt, 09444 XML_SCHEMAP_S4S_ATTR_MISSING, 09445 NULL, node, 09446 "name", NULL); 09447 return (NULL); 09448 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 09449 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 09450 return (NULL); 09451 } 09452 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 09453 ctxt->targetNamespace, node); 09454 if (item == NULL) 09455 return (NULL); 09456 /* 09457 * Check for illegal attributes. 09458 */ 09459 attr = node->properties; 09460 while (attr != NULL) { 09461 if (attr->ns == NULL) { 09462 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 09463 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 09464 xmlSchemaPIllegalAttrErr(ctxt, 09465 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09466 } 09467 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 09468 xmlSchemaPIllegalAttrErr(ctxt, 09469 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 09470 } 09471 attr = attr->next; 09472 } 09473 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 09474 /* 09475 * And now for the children... 09476 */ 09477 child = node->children; 09478 if (IS_SCHEMA(child, "annotation")) { 09479 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 09480 child = child->next; 09481 } 09482 if (IS_SCHEMA(child, "all")) { 09483 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 09484 XML_SCHEMA_TYPE_ALL, 0); 09485 child = child->next; 09486 } else if (IS_SCHEMA(child, "choice")) { 09487 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 09488 XML_SCHEMA_TYPE_CHOICE, 0); 09489 child = child->next; 09490 } else if (IS_SCHEMA(child, "sequence")) { 09491 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 09492 XML_SCHEMA_TYPE_SEQUENCE, 0); 09493 child = child->next; 09494 } 09495 09496 09497 09498 if (child != NULL) { 09499 xmlSchemaPContentErr(ctxt, 09500 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 09501 NULL, node, child, NULL, 09502 "(annotation?, (all | choice | sequence)?)"); 09503 } 09504 return (item); 09505 } 09506 09514 static void 09515 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 09516 { 09517 xmlNodePtr delete, cur; 09518 09519 if ((ctxt == NULL) || (root == NULL)) return; 09520 09521 /* 09522 * Remove all the blank text nodes 09523 */ 09524 delete = NULL; 09525 cur = root; 09526 while (cur != NULL) { 09527 if (delete != NULL) { 09528 xmlUnlinkNode(delete); 09529 xmlFreeNode(delete); 09530 delete = NULL; 09531 } 09532 if (cur->type == XML_TEXT_NODE) { 09533 if (IS_BLANK_NODE(cur)) { 09534 if (xmlNodeGetSpacePreserve(cur) != 1) { 09535 delete = cur; 09536 } 09537 } 09538 } else if ((cur->type != XML_ELEMENT_NODE) && 09539 (cur->type != XML_CDATA_SECTION_NODE)) { 09540 delete = cur; 09541 goto skip_children; 09542 } 09543 09544 /* 09545 * Skip to next node 09546 */ 09547 if (cur->children != NULL) { 09548 if ((cur->children->type != XML_ENTITY_DECL) && 09549 (cur->children->type != XML_ENTITY_REF_NODE) && 09550 (cur->children->type != XML_ENTITY_NODE)) { 09551 cur = cur->children; 09552 continue; 09553 } 09554 } 09555 skip_children: 09556 if (cur->next != NULL) { 09557 cur = cur->next; 09558 continue; 09559 } 09560 09561 do { 09562 cur = cur->parent; 09563 if (cur == NULL) 09564 break; 09565 if (cur == root) { 09566 cur = NULL; 09567 break; 09568 } 09569 if (cur->next != NULL) { 09570 cur = cur->next; 09571 break; 09572 } 09573 } while (cur != NULL); 09574 } 09575 if (delete != NULL) { 09576 xmlUnlinkNode(delete); 09577 xmlFreeNode(delete); 09578 delete = NULL; 09579 } 09580 } 09581 09582 09583 static void 09584 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 09585 { 09586 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 09587 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 09588 09589 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 09590 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 09591 09592 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 09593 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 09594 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 09595 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 09596 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 09597 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 09598 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 09599 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 09600 09601 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 09602 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 09603 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 09604 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 09605 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 09606 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 09607 } 09608 09609 static int 09610 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 09611 xmlSchemaPtr schema, 09612 xmlNodePtr node) 09613 { 09614 xmlAttrPtr attr; 09615 const xmlChar *val; 09616 int res = 0, oldErrs = ctxt->nberrors; 09617 09618 /* 09619 * Those flags should be moved to the parser context flags, 09620 * since they are not visible at the component level. I.e. 09621 * they are used if processing schema *documents* only. 09622 */ 09623 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 09624 HFAILURE; 09625 09626 /* 09627 * Since the version is of type xs:token, we won't bother to 09628 * check it. 09629 */ 09630 /* REMOVED: 09631 attr = xmlSchemaGetPropNode(node, "version"); 09632 if (attr != NULL) { 09633 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 09634 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 09635 HFAILURE; 09636 } 09637 */ 09638 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 09639 if (attr != NULL) { 09640 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 09641 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 09642 HFAILURE; 09643 if (res != 0) { 09644 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 09645 goto exit; 09646 } 09647 } 09648 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 09649 if (attr != NULL) { 09650 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 09651 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 09652 XML_SCHEMAS_QUALIF_ELEM); 09653 HFAILURE; 09654 if (res != 0) { 09655 xmlSchemaPSimpleTypeErr(ctxt, 09656 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 09657 NULL, (xmlNodePtr) attr, NULL, 09658 "(qualified | unqualified)", val, NULL, NULL, NULL); 09659 } 09660 } 09661 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 09662 if (attr != NULL) { 09663 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 09664 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 09665 XML_SCHEMAS_QUALIF_ATTR); 09666 HFAILURE; 09667 if (res != 0) { 09668 xmlSchemaPSimpleTypeErr(ctxt, 09669 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 09670 NULL, (xmlNodePtr) attr, NULL, 09671 "(qualified | unqualified)", val, NULL, NULL, NULL); 09672 } 09673 } 09674 attr = xmlSchemaGetPropNode(node, "finalDefault"); 09675 if (attr != NULL) { 09676 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 09677 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 09678 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 09679 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 09680 -1, 09681 XML_SCHEMAS_FINAL_DEFAULT_LIST, 09682 XML_SCHEMAS_FINAL_DEFAULT_UNION); 09683 HFAILURE; 09684 if (res != 0) { 09685 xmlSchemaPSimpleTypeErr(ctxt, 09686 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 09687 NULL, (xmlNodePtr) attr, NULL, 09688 "(#all | List of (extension | restriction | list | union))", 09689 val, NULL, NULL, NULL); 09690 } 09691 } 09692 attr = xmlSchemaGetPropNode(node, "blockDefault"); 09693 if (attr != NULL) { 09694 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 09695 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 09696 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 09697 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 09698 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 09699 HFAILURE; 09700 if (res != 0) { 09701 xmlSchemaPSimpleTypeErr(ctxt, 09702 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 09703 NULL, (xmlNodePtr) attr, NULL, 09704 "(#all | List of (extension | restriction | substitution))", 09705 val, NULL, NULL, NULL); 09706 } 09707 } 09708 09709 exit: 09710 if (oldErrs != ctxt->nberrors) 09711 res = ctxt->err; 09712 return(res); 09713 exit_failure: 09714 return(-1); 09715 } 09716 09726 static int 09727 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 09728 xmlSchemaPtr schema, xmlNodePtr nodes) 09729 { 09730 xmlNodePtr child; 09731 xmlSchemaAnnotPtr annot; 09732 int res = 0, oldErrs, tmpOldErrs; 09733 09734 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 09735 return(-1); 09736 09737 oldErrs = ctxt->nberrors; 09738 child = nodes; 09739 while ((IS_SCHEMA(child, "include")) || 09740 (IS_SCHEMA(child, "import")) || 09741 (IS_SCHEMA(child, "redefine")) || 09742 (IS_SCHEMA(child, "annotation"))) { 09743 if (IS_SCHEMA(child, "annotation")) { 09744 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 09745 if (schema->annot == NULL) 09746 schema->annot = annot; 09747 else 09748 xmlSchemaFreeAnnot(annot); 09749 } else if (IS_SCHEMA(child, "import")) { 09750 tmpOldErrs = ctxt->nberrors; 09751 res = xmlSchemaParseImport(ctxt, schema, child); 09752 HFAILURE; 09753 HSTOP(ctxt); 09754 if (tmpOldErrs != ctxt->nberrors) 09755 goto exit; 09756 } else if (IS_SCHEMA(child, "include")) { 09757 tmpOldErrs = ctxt->nberrors; 09758 res = xmlSchemaParseInclude(ctxt, schema, child); 09759 HFAILURE; 09760 HSTOP(ctxt); 09761 if (tmpOldErrs != ctxt->nberrors) 09762 goto exit; 09763 } else if (IS_SCHEMA(child, "redefine")) { 09764 tmpOldErrs = ctxt->nberrors; 09765 res = xmlSchemaParseRedefine(ctxt, schema, child); 09766 HFAILURE; 09767 HSTOP(ctxt); 09768 if (tmpOldErrs != ctxt->nberrors) 09769 goto exit; 09770 } 09771 child = child->next; 09772 } 09773 /* 09774 * URGENT TODO: Change the functions to return int results. 09775 * We need especially to catch internal errors. 09776 */ 09777 while (child != NULL) { 09778 if (IS_SCHEMA(child, "complexType")) { 09779 xmlSchemaParseComplexType(ctxt, schema, child, 1); 09780 child = child->next; 09781 } else if (IS_SCHEMA(child, "simpleType")) { 09782 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 09783 child = child->next; 09784 } else if (IS_SCHEMA(child, "element")) { 09785 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 09786 child = child->next; 09787 } else if (IS_SCHEMA(child, "attribute")) { 09788 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 09789 child = child->next; 09790 } else if (IS_SCHEMA(child, "attributeGroup")) { 09791 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 09792 child = child->next; 09793 } else if (IS_SCHEMA(child, "group")) { 09794 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 09795 child = child->next; 09796 } else if (IS_SCHEMA(child, "notation")) { 09797 xmlSchemaParseNotation(ctxt, schema, child); 09798 child = child->next; 09799 } else { 09800 xmlSchemaPContentErr(ctxt, 09801 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 09802 NULL, child->parent, child, 09803 NULL, "((include | import | redefine | annotation)*, " 09804 "(((simpleType | complexType | group | attributeGroup) " 09805 "| element | attribute | notation), annotation*)*)"); 09806 child = child->next; 09807 } 09808 while (IS_SCHEMA(child, "annotation")) { 09809 /* 09810 * TODO: We should add all annotations. 09811 */ 09812 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 09813 if (schema->annot == NULL) 09814 schema->annot = annot; 09815 else 09816 xmlSchemaFreeAnnot(annot); 09817 child = child->next; 09818 } 09819 } 09820 exit: 09821 ctxt->ctxtType = NULL; 09822 if (oldErrs != ctxt->nberrors) 09823 res = ctxt->err; 09824 return(res); 09825 exit_failure: 09826 return(-1); 09827 } 09828 09829 static xmlSchemaSchemaRelationPtr 09830 xmlSchemaSchemaRelationCreate(void) 09831 { 09832 xmlSchemaSchemaRelationPtr ret; 09833 09834 ret = (xmlSchemaSchemaRelationPtr) 09835 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 09836 if (ret == NULL) { 09837 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 09838 return(NULL); 09839 } 09840 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 09841 return(ret); 09842 } 09843 09844 #if 0 09845 static void 09846 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 09847 { 09848 xmlFree(rel); 09849 } 09850 #endif 09851 09852 static void 09853 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 09854 { 09855 xmlSchemaRedefPtr prev; 09856 09857 while (redef != NULL) { 09858 prev = redef; 09859 redef = redef->next; 09860 xmlFree(prev); 09861 } 09862 } 09863 09864 static void 09865 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 09866 { 09867 /* 09868 * After the construction context has been freed, there will be 09869 * no schema graph available any more. Only the schema buckets 09870 * will stay alive, which are put into the "schemasImports" and 09871 * "includes" slots of the xmlSchema. 09872 */ 09873 if (con->buckets != NULL) 09874 xmlSchemaItemListFree(con->buckets); 09875 if (con->pending != NULL) 09876 xmlSchemaItemListFree(con->pending); 09877 if (con->substGroups != NULL) 09878 xmlHashFree(con->substGroups, 09879 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 09880 if (con->redefs != NULL) 09881 xmlSchemaRedefListFree(con->redefs); 09882 if (con->dict != NULL) 09883 xmlDictFree(con->dict); 09884 xmlFree(con); 09885 } 09886 09887 static xmlSchemaConstructionCtxtPtr 09888 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 09889 { 09890 xmlSchemaConstructionCtxtPtr ret; 09891 09892 ret = (xmlSchemaConstructionCtxtPtr) 09893 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 09894 if (ret == NULL) { 09895 xmlSchemaPErrMemory(NULL, 09896 "allocating schema construction context", NULL); 09897 return (NULL); 09898 } 09899 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 09900 09901 ret->buckets = xmlSchemaItemListCreate(); 09902 if (ret->buckets == NULL) { 09903 xmlSchemaPErrMemory(NULL, 09904 "allocating list of schema buckets", NULL); 09905 xmlFree(ret); 09906 return (NULL); 09907 } 09908 ret->pending = xmlSchemaItemListCreate(); 09909 if (ret->pending == NULL) { 09910 xmlSchemaPErrMemory(NULL, 09911 "allocating list of pending global components", NULL); 09912 xmlSchemaConstructionCtxtFree(ret); 09913 return (NULL); 09914 } 09915 ret->dict = dict; 09916 xmlDictReference(dict); 09917 return(ret); 09918 } 09919 09920 static xmlSchemaParserCtxtPtr 09921 xmlSchemaParserCtxtCreate(void) 09922 { 09923 xmlSchemaParserCtxtPtr ret; 09924 09925 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 09926 if (ret == NULL) { 09927 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 09928 NULL); 09929 return (NULL); 09930 } 09931 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 09932 ret->type = XML_SCHEMA_CTXT_PARSER; 09933 ret->attrProhibs = xmlSchemaItemListCreate(); 09934 if (ret->attrProhibs == NULL) { 09935 xmlFree(ret); 09936 return(NULL); 09937 } 09938 return(ret); 09939 } 09940 09951 static xmlSchemaParserCtxtPtr 09952 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 09953 { 09954 xmlSchemaParserCtxtPtr ret; 09955 09956 ret = xmlSchemaParserCtxtCreate(); 09957 if (ret == NULL) 09958 return (NULL); 09959 ret->dict = dict; 09960 xmlDictReference(dict); 09961 if (URL != NULL) 09962 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 09963 return (ret); 09964 } 09965 09966 static int 09967 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 09968 { 09969 if (vctxt->pctxt == NULL) { 09970 if (vctxt->schema != NULL) 09971 vctxt->pctxt = 09972 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 09973 else 09974 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 09975 if (vctxt->pctxt == NULL) { 09976 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 09977 "failed to create a temp. parser context"); 09978 return (-1); 09979 } 09980 /* TODO: Pass user data. */ 09981 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 09982 vctxt->warning, vctxt->errCtxt); 09983 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 09984 vctxt->errCtxt); 09985 } 09986 return (0); 09987 } 09988 09999 static xmlSchemaBucketPtr 10000 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10001 const xmlChar *schemaLocation) 10002 { 10003 xmlSchemaBucketPtr cur; 10004 xmlSchemaItemListPtr list; 10005 10006 list = pctxt->constructor->buckets; 10007 if (list->nbItems == 0) 10008 return(NULL); 10009 else { 10010 int i; 10011 for (i = 0; i < list->nbItems; i++) { 10012 cur = (xmlSchemaBucketPtr) list->items[i]; 10013 /* Pointer comparison! */ 10014 if (cur->schemaLocation == schemaLocation) 10015 return(cur); 10016 } 10017 } 10018 return(NULL); 10019 } 10020 10021 static xmlSchemaBucketPtr 10022 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10023 const xmlChar *schemaLocation, 10024 const xmlChar *targetNamespace) 10025 { 10026 xmlSchemaBucketPtr cur; 10027 xmlSchemaItemListPtr list; 10028 10029 list = pctxt->constructor->buckets; 10030 if (list->nbItems == 0) 10031 return(NULL); 10032 else { 10033 int i; 10034 for (i = 0; i < list->nbItems; i++) { 10035 cur = (xmlSchemaBucketPtr) list->items[i]; 10036 /* Pointer comparison! */ 10037 if ((cur->origTargetNamespace == NULL) && 10038 (cur->schemaLocation == schemaLocation) && 10039 (cur->targetNamespace == targetNamespace)) 10040 return(cur); 10041 } 10042 } 10043 return(NULL); 10044 } 10045 10046 10047 #define IS_BAD_SCHEMA_DOC(b) \ 10048 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10049 10050 static xmlSchemaBucketPtr 10051 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10052 const xmlChar *targetNamespace, 10053 int imported) 10054 { 10055 xmlSchemaBucketPtr cur; 10056 xmlSchemaItemListPtr list; 10057 10058 list = pctxt->constructor->buckets; 10059 if (list->nbItems == 0) 10060 return(NULL); 10061 else { 10062 int i; 10063 for (i = 0; i < list->nbItems; i++) { 10064 cur = (xmlSchemaBucketPtr) list->items[i]; 10065 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10066 (cur->origTargetNamespace == targetNamespace) && 10067 ((imported && cur->imported) || 10068 ((!imported) && (!cur->imported)))) 10069 return(cur); 10070 } 10071 } 10072 return(NULL); 10073 } 10074 10075 static int 10076 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10077 xmlSchemaPtr schema, 10078 xmlSchemaBucketPtr bucket) 10079 { 10080 int oldFlags; 10081 xmlDocPtr oldDoc; 10082 xmlNodePtr node; 10083 int ret, oldErrs; 10084 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10085 10086 /* 10087 * Save old values; reset the *main* schema. 10088 * URGENT TODO: This is not good; move the per-document information 10089 * to the parser. Get rid of passing the main schema to the 10090 * parsing functions. 10091 */ 10092 oldFlags = schema->flags; 10093 oldDoc = schema->doc; 10094 if (schema->flags != 0) 10095 xmlSchemaClearSchemaDefaults(schema); 10096 schema->doc = bucket->doc; 10097 pctxt->schema = schema; 10098 /* 10099 * Keep the current target namespace on the parser *not* on the 10100 * main schema. 10101 */ 10102 pctxt->targetNamespace = bucket->targetNamespace; 10103 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10104 10105 if ((bucket->targetNamespace != NULL) && 10106 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10107 /* 10108 * We are parsing the schema for schemas! 10109 */ 10110 pctxt->isS4S = 1; 10111 } 10112 /* Mark it as parsed, even if parsing fails. */ 10113 bucket->parsed++; 10114 /* Compile the schema doc. */ 10115 node = xmlDocGetRootElement(bucket->doc); 10116 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10117 if (ret != 0) 10118 goto exit; 10119 /* An empty schema; just get out. */ 10120 if (node->children == NULL) 10121 goto exit; 10122 oldErrs = pctxt->nberrors; 10123 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10124 if (ret != 0) 10125 goto exit; 10126 /* 10127 * TODO: Not nice, but I'm not 100% sure we will get always an error 10128 * as a result of the obove functions; so better rely on pctxt->err 10129 * as well. 10130 */ 10131 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10132 ret = pctxt->err; 10133 goto exit; 10134 } 10135 10136 exit: 10137 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10138 /* Restore schema values. */ 10139 schema->doc = oldDoc; 10140 schema->flags = oldFlags; 10141 return(ret); 10142 } 10143 10144 static int 10145 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10146 xmlSchemaPtr schema, 10147 xmlSchemaBucketPtr bucket) 10148 { 10149 xmlSchemaParserCtxtPtr newpctxt; 10150 int res = 0; 10151 10152 if (bucket == NULL) 10153 return(0); 10154 if (bucket->parsed) { 10155 PERROR_INT("xmlSchemaParseNewDoc", 10156 "reparsing a schema doc"); 10157 return(-1); 10158 } 10159 if (bucket->doc == NULL) { 10160 PERROR_INT("xmlSchemaParseNewDoc", 10161 "parsing a schema doc, but there's no doc"); 10162 return(-1); 10163 } 10164 if (pctxt->constructor == NULL) { 10165 PERROR_INT("xmlSchemaParseNewDoc", 10166 "no constructor"); 10167 return(-1); 10168 } 10169 /* Create and init the temporary parser context. */ 10170 newpctxt = xmlSchemaNewParserCtxtUseDict( 10171 (const char *) bucket->schemaLocation, pctxt->dict); 10172 if (newpctxt == NULL) 10173 return(-1); 10174 newpctxt->constructor = pctxt->constructor; 10175 /* 10176 * TODO: Can we avoid that the parser knows about the main schema? 10177 * It would be better if he knows about the current schema bucket 10178 * only. 10179 */ 10180 newpctxt->schema = schema; 10181 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10182 pctxt->errCtxt); 10183 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10184 pctxt->errCtxt); 10185 newpctxt->counter = pctxt->counter; 10186 10187 10188 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10189 10190 /* Channel back errors and cleanup the temporary parser context. */ 10191 if (res != 0) 10192 pctxt->err = res; 10193 pctxt->nberrors += newpctxt->nberrors; 10194 pctxt->counter = newpctxt->counter; 10195 newpctxt->constructor = NULL; 10196 /* Free the parser context. */ 10197 xmlSchemaFreeParserCtxt(newpctxt); 10198 return(res); 10199 } 10200 10201 static void 10202 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10203 xmlSchemaSchemaRelationPtr rel) 10204 { 10205 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10206 10207 if (cur == NULL) { 10208 bucket->relations = rel; 10209 return; 10210 } 10211 while (cur->next != NULL) 10212 cur = cur->next; 10213 cur->next = rel; 10214 } 10215 10216 10217 static const xmlChar * 10218 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10219 xmlNodePtr ctxtNode) 10220 { 10221 /* 10222 * Build an absolue location URI. 10223 */ 10224 if (location != NULL) { 10225 if (ctxtNode == NULL) 10226 return(location); 10227 else { 10228 xmlChar *base, *URI; 10229 const xmlChar *ret = NULL; 10230 10231 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10232 if (base == NULL) { 10233 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10234 } else { 10235 URI = xmlBuildURI(location, base); 10236 xmlFree(base); 10237 } 10238 if (URI != NULL) { 10239 ret = xmlDictLookup(dict, URI, -1); 10240 xmlFree(URI); 10241 return(ret); 10242 } 10243 } 10244 } 10245 return(NULL); 10246 } 10247 10248 10249 10262 static int 10263 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10264 int type, /* import or include or redefine */ 10265 const xmlChar *schemaLocation, 10266 xmlDocPtr schemaDoc, 10267 const char *schemaBuffer, 10268 int schemaBufferLen, 10269 xmlNodePtr invokingNode, 10270 const xmlChar *sourceTargetNamespace, 10271 const xmlChar *importNamespace, 10272 xmlSchemaBucketPtr *bucket) 10273 { 10274 const xmlChar *targetNamespace = NULL; 10275 xmlSchemaSchemaRelationPtr relation = NULL; 10276 xmlDocPtr doc = NULL; 10277 int res = 0, err = 0, located = 0, preserveDoc = 0; 10278 xmlSchemaBucketPtr bkt = NULL; 10279 10280 if (bucket != NULL) 10281 *bucket = NULL; 10282 10283 switch (type) { 10284 case XML_SCHEMA_SCHEMA_IMPORT: 10285 case XML_SCHEMA_SCHEMA_MAIN: 10286 err = XML_SCHEMAP_SRC_IMPORT; 10287 break; 10288 case XML_SCHEMA_SCHEMA_INCLUDE: 10289 err = XML_SCHEMAP_SRC_INCLUDE; 10290 break; 10291 case XML_SCHEMA_SCHEMA_REDEFINE: 10292 err = XML_SCHEMAP_SRC_REDEFINE; 10293 break; 10294 } 10295 10296 10297 /* Special handling for the main schema: 10298 * skip the location and relation logic and just parse the doc. 10299 * We need just a bucket to be returned in this case. 10300 */ 10301 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10302 goto doc_load; 10303 10304 /* Note that we expect the location to be an absulute URI. */ 10305 if (schemaLocation != NULL) { 10306 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10307 if ((bkt != NULL) && 10308 (pctxt->constructor->bucket == bkt)) { 10309 /* Report self-imports/inclusions/redefinitions. */ 10310 10311 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10312 invokingNode, NULL, 10313 "The schema must not import/include/redefine itself", 10314 NULL, NULL); 10315 goto exit; 10316 } 10317 } 10318 /* 10319 * Create a relation for the graph of schemas. 10320 */ 10321 relation = xmlSchemaSchemaRelationCreate(); 10322 if (relation == NULL) 10323 return(-1); 10324 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10325 relation); 10326 relation->type = type; 10327 10328 /* 10329 * Save the namespace import information. 10330 */ 10331 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10332 relation->importNamespace = importNamespace; 10333 if (schemaLocation == NULL) { 10334 /* 10335 * No location; this is just an import of the namespace. 10336 * Note that we don't assign a bucket to the relation 10337 * in this case. 10338 */ 10339 goto exit; 10340 } 10341 targetNamespace = importNamespace; 10342 } 10343 10344 /* Did we already fetch the doc? */ 10345 if (bkt != NULL) { 10346 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10347 /* 10348 * We included/redefined and then try to import a schema, 10349 * but the new location provided for import was different. 10350 */ 10351 if (schemaLocation == NULL) 10352 schemaLocation = BAD_CAST "in_memory_buffer"; 10353 if (!xmlStrEqual(schemaLocation, 10354 bkt->schemaLocation)) { 10355 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10356 invokingNode, NULL, 10357 "The schema document '%s' cannot be imported, since " 10358 "it was already included or redefined", 10359 schemaLocation, NULL); 10360 goto exit; 10361 } 10362 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10363 /* 10364 * We imported and then try to include/redefine a schema, 10365 * but the new location provided for the include/redefine 10366 * was different. 10367 */ 10368 if (schemaLocation == NULL) 10369 schemaLocation = BAD_CAST "in_memory_buffer"; 10370 if (!xmlStrEqual(schemaLocation, 10371 bkt->schemaLocation)) { 10372 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10373 invokingNode, NULL, 10374 "The schema document '%s' cannot be included or " 10375 "redefined, since it was already imported", 10376 schemaLocation, NULL); 10377 goto exit; 10378 } 10379 } 10380 } 10381 10382 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10383 /* 10384 * Given that the schemaLocation [attribute] is only a hint, it is open 10385 * to applications to ignore all but the first <import> for a given 10386 * namespace, regardless of the �actual value� of schemaLocation, but 10387 * such a strategy risks missing useful information when new 10388 * schemaLocations are offered. 10389 * 10390 * We will use the first <import> that comes with a location. 10391 * Further <import>s *with* a location, will result in an error. 10392 * TODO: Better would be to just report a warning here, but 10393 * we'll try it this way until someone complains. 10394 * 10395 * Schema Document Location Strategy: 10396 * 3 Based on the namespace name, identify an existing schema document, 10397 * either as a resource which is an XML document or a <schema> element 10398 * information item, in some local schema repository; 10399 * 5 Attempt to resolve the namespace name to locate such a resource. 10400 * 10401 * NOTE: (3) and (5) are not supported. 10402 */ 10403 if (bkt != NULL) { 10404 relation->bucket = bkt; 10405 goto exit; 10406 } 10407 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10408 importNamespace, 1); 10409 10410 if (bkt != NULL) { 10411 relation->bucket = bkt; 10412 if (bkt->schemaLocation == NULL) { 10413 /* First given location of the schema; load the doc. */ 10414 bkt->schemaLocation = schemaLocation; 10415 } else { 10416 if (!xmlStrEqual(schemaLocation, 10417 bkt->schemaLocation)) { 10418 /* 10419 * Additional location given; just skip it. 10420 * URGENT TODO: We should report a warning here. 10421 * res = XML_SCHEMAP_SRC_IMPORT; 10422 */ 10423 if (schemaLocation == NULL) 10424 schemaLocation = BAD_CAST "in_memory_buffer"; 10425 10426 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10427 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10428 invokingNode, NULL, 10429 "Skipping import of schema located at '%s' for the " 10430 "namespace '%s', since this namespace was already " 10431 "imported with the schema located at '%s'", 10432 schemaLocation, importNamespace, bkt->schemaLocation); 10433 } 10434 goto exit; 10435 } 10436 } 10437 /* 10438 * No bucket + first location: load the doc and create a 10439 * bucket. 10440 */ 10441 } else { 10442 /* <include> and <redefine> */ 10443 if (bkt != NULL) { 10444 10445 if ((bkt->origTargetNamespace == NULL) && 10446 (bkt->targetNamespace != sourceTargetNamespace)) { 10447 xmlSchemaBucketPtr chamel; 10448 10449 /* 10450 * Chameleon include/redefine: skip loading only if it was 10451 * aleady build for the targetNamespace of the including 10452 * schema. 10453 */ 10454 /* 10455 * URGENT TODO: If the schema is a chameleon-include then copy 10456 * the components into the including schema and modify the 10457 * targetNamespace of those components, do nothing otherwise. 10458 * NOTE: This is currently worked-around by compiling the 10459 * chameleon for every destinct including targetNamespace; thus 10460 * not performant at the moment. 10461 * TODO: Check when the namespace in wildcards for chameleons 10462 * needs to be converted: before we built wildcard intersections 10463 * or after. 10464 * Answer: after! 10465 */ 10466 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10467 schemaLocation, sourceTargetNamespace); 10468 if (chamel != NULL) { 10469 /* A fitting chameleon was already parsed; NOP. */ 10470 relation->bucket = chamel; 10471 goto exit; 10472 } 10473 /* 10474 * We need to parse the chameleon again for a different 10475 * targetNamespace. 10476 * CHAMELEON TODO: Optimize this by only parsing the 10477 * chameleon once, and then copying the components to 10478 * the new targetNamespace. 10479 */ 10480 bkt = NULL; 10481 } else { 10482 relation->bucket = bkt; 10483 goto exit; 10484 } 10485 } 10486 } 10487 if ((bkt != NULL) && (bkt->doc != NULL)) { 10488 PERROR_INT("xmlSchemaAddSchemaDoc", 10489 "trying to load a schema doc, but a doc is already " 10490 "assigned to the schema bucket"); 10491 goto exit_failure; 10492 } 10493 10494 doc_load: 10495 /* 10496 * Load the document. 10497 */ 10498 if (schemaDoc != NULL) { 10499 doc = schemaDoc; 10500 /* Don' free this one, since it was provided by the caller. */ 10501 preserveDoc = 1; 10502 /* TODO: Does the context or the doc hold the location? */ 10503 if (schemaDoc->URL != NULL) 10504 schemaLocation = xmlDictLookup(pctxt->dict, 10505 schemaDoc->URL, -1); 10506 else 10507 schemaLocation = BAD_CAST "in_memory_buffer"; 10508 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10509 xmlParserCtxtPtr parserCtxt; 10510 10511 parserCtxt = xmlNewParserCtxt(); 10512 if (parserCtxt == NULL) { 10513 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10514 "allocating a parser context", NULL); 10515 goto exit_failure; 10516 } 10517 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10518 /* 10519 * TODO: Do we have to burden the schema parser dict with all 10520 * the content of the schema doc? 10521 */ 10522 xmlDictFree(parserCtxt->dict); 10523 parserCtxt->dict = pctxt->dict; 10524 xmlDictReference(parserCtxt->dict); 10525 } 10526 if (schemaLocation != NULL) { 10527 /* Parse from file. */ 10528 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10529 NULL, SCHEMAS_PARSE_OPTIONS); 10530 } else if (schemaBuffer != NULL) { 10531 /* Parse from memory buffer. */ 10532 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10533 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10534 schemaLocation = BAD_CAST "in_memory_buffer"; 10535 if (doc != NULL) 10536 doc->URL = xmlStrdup(schemaLocation); 10537 } 10538 /* 10539 * For <import>: 10540 * 2.1 The referent is (a fragment of) a resource which is an 10541 * XML document (see clause 1.1), which in turn corresponds to 10542 * a <schema> element information item in a well-formed information 10543 * set, which in turn corresponds to a valid schema. 10544 * TODO: (2.1) fragments of XML documents are not supported. 10545 * 10546 * 2.2 The referent is a <schema> element information item in 10547 * a well-formed information set, which in turn corresponds 10548 * to a valid schema. 10549 * TODO: (2.2) is not supported. 10550 */ 10551 if (doc == NULL) { 10552 xmlErrorPtr lerr; 10553 lerr = xmlGetLastError(); 10554 /* 10555 * Check if this a parser error, or if the document could 10556 * just not be located. 10557 * TODO: Try to find specific error codes to react only on 10558 * localisation failures. 10559 */ 10560 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10561 /* 10562 * We assume a parser error here. 10563 */ 10564 located = 1; 10565 /* TODO: Error code ?? */ 10566 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10567 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10568 invokingNode, NULL, 10569 "Failed to parse the XML resource '%s'", 10570 schemaLocation, NULL); 10571 } 10572 } 10573 xmlFreeParserCtxt(parserCtxt); 10574 if ((doc == NULL) && located) 10575 goto exit_error; 10576 } else { 10577 xmlSchemaPErr(pctxt, NULL, 10578 XML_SCHEMAP_NOTHING_TO_PARSE, 10579 "No information for parsing was provided with the " 10580 "given schema parser context.\n", 10581 NULL, NULL); 10582 goto exit_failure; 10583 } 10584 /* 10585 * Preprocess the document. 10586 */ 10587 if (doc != NULL) { 10588 xmlNodePtr docElem = NULL; 10589 10590 located = 1; 10591 docElem = xmlDocGetRootElement(doc); 10592 if (docElem == NULL) { 10593 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10594 invokingNode, NULL, 10595 "The document '%s' has no document element", 10596 schemaLocation, NULL); 10597 goto exit_error; 10598 } 10599 /* 10600 * Remove all the blank text nodes. 10601 */ 10602 xmlSchemaCleanupDoc(pctxt, docElem); 10603 /* 10604 * Check the schema's top level element. 10605 */ 10606 if (!IS_SCHEMA(docElem, "schema")) { 10607 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10608 invokingNode, NULL, 10609 "The XML document '%s' is not a schema document", 10610 schemaLocation, NULL); 10611 goto exit_error; 10612 } 10613 /* 10614 * Note that we don't apply a type check for the 10615 * targetNamespace value here. 10616 */ 10617 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10618 "targetNamespace"); 10619 } 10620 10621 /* after_doc_loading: */ 10622 if ((bkt == NULL) && located) { 10623 /* Only create a bucket if the schema was located. */ 10624 bkt = xmlSchemaBucketCreate(pctxt, type, 10625 targetNamespace); 10626 if (bkt == NULL) 10627 goto exit_failure; 10628 } 10629 if (bkt != NULL) { 10630 bkt->schemaLocation = schemaLocation; 10631 bkt->located = located; 10632 if (doc != NULL) { 10633 bkt->doc = doc; 10634 bkt->targetNamespace = targetNamespace; 10635 bkt->origTargetNamespace = targetNamespace; 10636 if (preserveDoc) 10637 bkt->preserveDoc = 1; 10638 } 10639 if (WXS_IS_BUCKET_IMPMAIN(type)) 10640 bkt->imported++; 10641 /* 10642 * Add it to the graph of schemas. 10643 */ 10644 if (relation != NULL) 10645 relation->bucket = bkt; 10646 } 10647 10648 exit: 10649 /* 10650 * Return the bucket explicitely; this is needed for the 10651 * main schema. 10652 */ 10653 if (bucket != NULL) 10654 *bucket = bkt; 10655 return (0); 10656 10657 exit_error: 10658 if ((doc != NULL) && (! preserveDoc)) { 10659 xmlFreeDoc(doc); 10660 if (bkt != NULL) 10661 bkt->doc = NULL; 10662 } 10663 return(pctxt->err); 10664 10665 exit_failure: 10666 if ((doc != NULL) && (! preserveDoc)) { 10667 xmlFreeDoc(doc); 10668 if (bkt != NULL) 10669 bkt->doc = NULL; 10670 } 10671 return (-1); 10672 } 10673 10686 static int 10687 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10688 xmlNodePtr node) 10689 { 10690 xmlNodePtr child; 10691 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10692 const xmlChar *thisTargetNamespace; 10693 xmlAttrPtr attr; 10694 int ret = 0; 10695 xmlSchemaBucketPtr bucket = NULL; 10696 10697 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10698 return (-1); 10699 10700 /* 10701 * Check for illegal attributes. 10702 */ 10703 attr = node->properties; 10704 while (attr != NULL) { 10705 if (attr->ns == NULL) { 10706 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10707 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10708 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10709 xmlSchemaPIllegalAttrErr(pctxt, 10710 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10711 } 10712 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10713 xmlSchemaPIllegalAttrErr(pctxt, 10714 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10715 } 10716 attr = attr->next; 10717 } 10718 /* 10719 * Extract and validate attributes. 10720 */ 10721 if (xmlSchemaPValAttr(pctxt, NULL, node, 10722 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10723 &namespaceName) != 0) { 10724 xmlSchemaPSimpleTypeErr(pctxt, 10725 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10726 NULL, node, 10727 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10728 NULL, namespaceName, NULL, NULL, NULL); 10729 return (pctxt->err); 10730 } 10731 10732 if (xmlSchemaPValAttr(pctxt, NULL, node, 10733 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10734 &schemaLocation) != 0) { 10735 xmlSchemaPSimpleTypeErr(pctxt, 10736 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10737 NULL, node, 10738 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10739 NULL, namespaceName, NULL, NULL, NULL); 10740 return (pctxt->err); 10741 } 10742 /* 10743 * And now for the children... 10744 */ 10745 child = node->children; 10746 if (IS_SCHEMA(child, "annotation")) { 10747 /* 10748 * the annotation here is simply discarded ... 10749 * TODO: really? 10750 */ 10751 child = child->next; 10752 } 10753 if (child != NULL) { 10754 xmlSchemaPContentErr(pctxt, 10755 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10756 NULL, node, child, NULL, 10757 "(annotation?)"); 10758 } 10759 /* 10760 * Apply additional constraints. 10761 * 10762 * Note that it is important to use the original @targetNamespace 10763 * (or none at all), to rule out imports of schemas _with_ a 10764 * @targetNamespace if the importing schema is a chameleon schema 10765 * (with no @targetNamespace). 10766 */ 10767 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10768 if (namespaceName != NULL) { 10769 /* 10770 * 1.1 If the namespace [attribute] is present, then its �actual value� 10771 * must not match the �actual value� of the enclosing <schema>'s 10772 * targetNamespace [attribute]. 10773 */ 10774 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10775 xmlSchemaPCustomErr(pctxt, 10776 XML_SCHEMAP_SRC_IMPORT_1_1, 10777 NULL, node, 10778 "The value of the attribute 'namespace' must not match " 10779 "the target namespace '%s' of the importing schema", 10780 thisTargetNamespace); 10781 return (pctxt->err); 10782 } 10783 } else { 10784 /* 10785 * 1.2 If the namespace [attribute] is not present, then the enclosing 10786 * <schema> must have a targetNamespace [attribute]. 10787 */ 10788 if (thisTargetNamespace == NULL) { 10789 xmlSchemaPCustomErr(pctxt, 10790 XML_SCHEMAP_SRC_IMPORT_1_2, 10791 NULL, node, 10792 "The attribute 'namespace' must be existent if " 10793 "the importing schema has no target namespace", 10794 NULL); 10795 return (pctxt->err); 10796 } 10797 } 10798 /* 10799 * Locate and acquire the schema document. 10800 */ 10801 if (schemaLocation != NULL) 10802 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10803 schemaLocation, node); 10804 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10805 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10806 namespaceName, &bucket); 10807 10808 if (ret != 0) 10809 return(ret); 10810 10811 /* 10812 * For <import>: "It is *not* an error for the application 10813 * schema reference strategy to fail." 10814 * So just don't parse if no schema document was found. 10815 * Note that we will get no bucket if the schema could not be 10816 * located or if there was no schemaLocation. 10817 */ 10818 if ((bucket == NULL) && (schemaLocation != NULL)) { 10819 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10820 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10821 node, NULL, 10822 "Failed to locate a schema at location '%s'. " 10823 "Skipping the import", schemaLocation, NULL, NULL); 10824 } 10825 10826 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10827 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10828 } 10829 10830 return (ret); 10831 } 10832 10833 static int 10834 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10835 xmlSchemaPtr schema, 10836 xmlNodePtr node, 10837 xmlChar **schemaLocation, 10838 int type) 10839 { 10840 xmlAttrPtr attr; 10841 10842 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10843 (schemaLocation == NULL)) 10844 return (-1); 10845 10846 *schemaLocation = NULL; 10847 /* 10848 * Check for illegal attributes. 10849 * Applies for both <include> and <redefine>. 10850 */ 10851 attr = node->properties; 10852 while (attr != NULL) { 10853 if (attr->ns == NULL) { 10854 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10855 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10856 xmlSchemaPIllegalAttrErr(pctxt, 10857 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10858 } 10859 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10860 xmlSchemaPIllegalAttrErr(pctxt, 10861 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10862 } 10863 attr = attr->next; 10864 } 10865 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10866 /* 10867 * Preliminary step, extract the URI-Reference and make an URI 10868 * from the base. 10869 */ 10870 /* 10871 * Attribute "schemaLocation" is mandatory. 10872 */ 10873 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10874 if (attr != NULL) { 10875 xmlChar *base = NULL; 10876 xmlChar *uri = NULL; 10877 10878 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10879 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10880 (const xmlChar **) schemaLocation) != 0) 10881 goto exit_error; 10882 base = xmlNodeGetBase(node->doc, node); 10883 if (base == NULL) { 10884 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10885 } else { 10886 uri = xmlBuildURI(*schemaLocation, base); 10887 xmlFree(base); 10888 } 10889 if (uri == NULL) { 10890 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10891 "could not build an URI from the schemaLocation") 10892 goto exit_failure; 10893 } 10894 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10895 xmlFree(uri); 10896 } else { 10897 xmlSchemaPMissingAttrErr(pctxt, 10898 XML_SCHEMAP_S4S_ATTR_MISSING, 10899 NULL, node, "schemaLocation", NULL); 10900 goto exit_error; 10901 } 10902 /* 10903 * Report self-inclusion and self-redefinition. 10904 */ 10905 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10906 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10907 xmlSchemaPCustomErr(pctxt, 10908 XML_SCHEMAP_SRC_REDEFINE, 10909 NULL, node, 10910 "The schema document '%s' cannot redefine itself.", 10911 *schemaLocation); 10912 } else { 10913 xmlSchemaPCustomErr(pctxt, 10914 XML_SCHEMAP_SRC_INCLUDE, 10915 NULL, node, 10916 "The schema document '%s' cannot include itself.", 10917 *schemaLocation); 10918 } 10919 goto exit_error; 10920 } 10921 10922 return(0); 10923 exit_error: 10924 return(pctxt->err); 10925 exit_failure: 10926 return(-1); 10927 } 10928 10929 static int 10930 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10931 xmlSchemaPtr schema, 10932 xmlNodePtr node, 10933 int type) 10934 { 10935 xmlNodePtr child = NULL; 10936 const xmlChar *schemaLocation = NULL; 10937 int res = 0; /* hasRedefinitions = 0 */ 10938 int isChameleon = 0, wasChameleon = 0; 10939 xmlSchemaBucketPtr bucket = NULL; 10940 10941 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10942 return (-1); 10943 10944 /* 10945 * Parse attributes. Note that the returned schemaLocation will 10946 * be already converted to an absolute URI. 10947 */ 10948 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10949 node, (xmlChar **) (&schemaLocation), type); 10950 if (res != 0) 10951 return(res); 10952 /* 10953 * Load and add the schema document. 10954 */ 10955 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10956 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10957 if (res != 0) 10958 return(res); 10959 /* 10960 * If we get no schema bucket back, then this means that the schema 10961 * document could not be located or was broken XML or was not 10962 * a schema document. 10963 */ 10964 if ((bucket == NULL) || (bucket->doc == NULL)) { 10965 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 10966 /* 10967 * WARNING for <include>: 10968 * We will raise an error if the schema cannot be located 10969 * for inclusions, since the that was the feedback from the 10970 * schema people. I.e. the following spec piece will *not* be 10971 * satisfied: 10972 * SPEC src-include: "It is not an error for the �actual value� of the 10973 * schemaLocation [attribute] to fail to resolve it all, in which 10974 * case no corresponding inclusion is performed. 10975 * So do we need a warning report here?" 10976 */ 10977 res = XML_SCHEMAP_SRC_INCLUDE; 10978 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10979 node, NULL, 10980 "Failed to load the document '%s' for inclusion", 10981 schemaLocation, NULL); 10982 } else { 10983 /* 10984 * NOTE: This was changed to raise an error even if no redefinitions 10985 * are specified. 10986 * 10987 * SPEC src-redefine (1) 10988 * "If there are any element information items among the [children] 10989 * other than <annotation> then the �actual value� of the 10990 * schemaLocation [attribute] must successfully resolve." 10991 * TODO: Ask the WG if a the location has always to resolve 10992 * here as well! 10993 */ 10994 res = XML_SCHEMAP_SRC_REDEFINE; 10995 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10996 node, NULL, 10997 "Failed to load the document '%s' for redefinition", 10998 schemaLocation, NULL); 10999 } 11000 } else { 11001 /* 11002 * Check targetNamespace sanity before parsing the new schema. 11003 * TODO: Note that we won't check further content if the 11004 * targetNamespace was bad. 11005 */ 11006 if (bucket->origTargetNamespace != NULL) { 11007 /* 11008 * SPEC src-include (2.1) 11009 * "SII has a targetNamespace [attribute], and its �actual 11010 * value� is identical to the �actual value� of the targetNamespace 11011 * [attribute] of SII� (which must have such an [attribute])." 11012 */ 11013 if (pctxt->targetNamespace == NULL) { 11014 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11015 XML_SCHEMAP_SRC_INCLUDE, 11016 node, NULL, 11017 "The target namespace of the included/redefined schema " 11018 "'%s' has to be absent, since the including/redefining " 11019 "schema has no target namespace", 11020 schemaLocation, NULL); 11021 goto exit_error; 11022 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11023 pctxt->targetNamespace)) { 11024 /* TODO: Change error function. */ 11025 xmlSchemaPCustomErrExt(pctxt, 11026 XML_SCHEMAP_SRC_INCLUDE, 11027 NULL, node, 11028 "The target namespace '%s' of the included/redefined " 11029 "schema '%s' differs from '%s' of the " 11030 "including/redefining schema", 11031 bucket->origTargetNamespace, schemaLocation, 11032 pctxt->targetNamespace); 11033 goto exit_error; 11034 } 11035 } else if (pctxt->targetNamespace != NULL) { 11036 /* 11037 * Chameleons: the original target namespace will 11038 * differ from the resulting namespace. 11039 */ 11040 isChameleon = 1; 11041 if (bucket->parsed && 11042 bucket->origTargetNamespace != NULL) { 11043 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11044 XML_SCHEMAP_SRC_INCLUDE, 11045 node, NULL, 11046 "The target namespace of the included/redefined schema " 11047 "'%s' has to be absent or the same as the " 11048 "including/redefining schema's target namespace", 11049 schemaLocation, NULL); 11050 goto exit_error; 11051 } 11052 bucket->targetNamespace = pctxt->targetNamespace; 11053 } 11054 } 11055 /* 11056 * Parse the schema. 11057 */ 11058 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11059 if (isChameleon) { 11060 /* TODO: Get rid of this flag on the schema itself. */ 11061 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11062 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11063 } else 11064 wasChameleon = 1; 11065 } 11066 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11067 /* Restore chameleon flag. */ 11068 if (isChameleon && (!wasChameleon)) 11069 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11070 } 11071 /* 11072 * And now for the children... 11073 */ 11074 child = node->children; 11075 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11076 /* 11077 * Parse (simpleType | complexType | group | attributeGroup))* 11078 */ 11079 pctxt->redefined = bucket; 11080 /* 11081 * How to proceed if the redefined schema was not located? 11082 */ 11083 pctxt->isRedefine = 1; 11084 while (IS_SCHEMA(child, "annotation") || 11085 IS_SCHEMA(child, "simpleType") || 11086 IS_SCHEMA(child, "complexType") || 11087 IS_SCHEMA(child, "group") || 11088 IS_SCHEMA(child, "attributeGroup")) { 11089 if (IS_SCHEMA(child, "annotation")) { 11090 /* 11091 * TODO: discard or not? 11092 */ 11093 } else if (IS_SCHEMA(child, "simpleType")) { 11094 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11095 } else if (IS_SCHEMA(child, "complexType")) { 11096 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11097 /* hasRedefinitions = 1; */ 11098 } else if (IS_SCHEMA(child, "group")) { 11099 /* hasRedefinitions = 1; */ 11100 xmlSchemaParseModelGroupDefinition(pctxt, 11101 schema, child); 11102 } else if (IS_SCHEMA(child, "attributeGroup")) { 11103 /* hasRedefinitions = 1; */ 11104 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11105 child); 11106 } 11107 child = child->next; 11108 } 11109 pctxt->redefined = NULL; 11110 pctxt->isRedefine = 0; 11111 } else { 11112 if (IS_SCHEMA(child, "annotation")) { 11113 /* 11114 * TODO: discard or not? 11115 */ 11116 child = child->next; 11117 } 11118 } 11119 if (child != NULL) { 11120 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11121 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11122 xmlSchemaPContentErr(pctxt, res, 11123 NULL, node, child, NULL, 11124 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11125 } else { 11126 xmlSchemaPContentErr(pctxt, res, 11127 NULL, node, child, NULL, 11128 "(annotation?)"); 11129 } 11130 } 11131 return(res); 11132 11133 exit_error: 11134 return(pctxt->err); 11135 } 11136 11137 static int 11138 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11139 xmlNodePtr node) 11140 { 11141 int res; 11142 #ifndef ENABLE_REDEFINE 11143 TODO 11144 return(0); 11145 #endif 11146 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11147 XML_SCHEMA_SCHEMA_REDEFINE); 11148 if (res != 0) 11149 return(res); 11150 return(0); 11151 } 11152 11153 static int 11154 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11155 xmlNodePtr node) 11156 { 11157 int res; 11158 11159 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11160 XML_SCHEMA_SCHEMA_INCLUDE); 11161 if (res != 0) 11162 return(res); 11163 return(0); 11164 } 11165 11191 static xmlSchemaTreeItemPtr 11192 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11193 xmlNodePtr node, xmlSchemaTypeType type, 11194 int withParticle) 11195 { 11196 xmlSchemaModelGroupPtr item; 11197 xmlSchemaParticlePtr particle = NULL; 11198 xmlNodePtr child = NULL; 11199 xmlAttrPtr attr; 11200 int min = 1, max = 1, isElemRef, hasRefs = 0; 11201 11202 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11203 return (NULL); 11204 /* 11205 * Create a model group with the given compositor. 11206 */ 11207 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11208 if (item == NULL) 11209 return (NULL); 11210 11211 if (withParticle) { 11212 if (type == XML_SCHEMA_TYPE_ALL) { 11213 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11214 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11215 } else { 11216 /* choice + sequence */ 11217 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11218 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11219 "(xs:nonNegativeInteger | unbounded)"); 11220 } 11221 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11222 /* 11223 * Create a particle 11224 */ 11225 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11226 if (particle == NULL) 11227 return (NULL); 11228 particle->children = (xmlSchemaTreeItemPtr) item; 11229 /* 11230 * Check for illegal attributes. 11231 */ 11232 attr = node->properties; 11233 while (attr != NULL) { 11234 if (attr->ns == NULL) { 11235 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11236 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11237 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11238 xmlSchemaPIllegalAttrErr(ctxt, 11239 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11240 } 11241 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11242 xmlSchemaPIllegalAttrErr(ctxt, 11243 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11244 } 11245 attr = attr->next; 11246 } 11247 } else { 11248 /* 11249 * Check for illegal attributes. 11250 */ 11251 attr = node->properties; 11252 while (attr != NULL) { 11253 if (attr->ns == NULL) { 11254 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11255 xmlSchemaPIllegalAttrErr(ctxt, 11256 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11257 } 11258 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11259 xmlSchemaPIllegalAttrErr(ctxt, 11260 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11261 } 11262 attr = attr->next; 11263 } 11264 } 11265 11266 /* 11267 * Extract and validate attributes. 11268 */ 11269 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11270 /* 11271 * And now for the children... 11272 */ 11273 child = node->children; 11274 if (IS_SCHEMA(child, "annotation")) { 11275 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11276 child = child->next; 11277 } 11278 if (type == XML_SCHEMA_TYPE_ALL) { 11279 xmlSchemaParticlePtr part, last = NULL; 11280 11281 while (IS_SCHEMA(child, "element")) { 11282 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11283 schema, child, &isElemRef, 0); 11284 /* 11285 * SPEC cos-all-limited (2) 11286 * "The {max occurs} of all the particles in the {particles} 11287 * of the ('all') group must be 0 or 1. 11288 */ 11289 if (part != NULL) { 11290 if (isElemRef) 11291 hasRefs++; 11292 if (part->minOccurs > 1) { 11293 xmlSchemaPCustomErr(ctxt, 11294 XML_SCHEMAP_COS_ALL_LIMITED, 11295 NULL, child, 11296 "Invalid value for minOccurs (must be 0 or 1)", 11297 NULL); 11298 /* Reset to 1. */ 11299 part->minOccurs = 1; 11300 } 11301 if (part->maxOccurs > 1) { 11302 xmlSchemaPCustomErr(ctxt, 11303 XML_SCHEMAP_COS_ALL_LIMITED, 11304 NULL, child, 11305 "Invalid value for maxOccurs (must be 0 or 1)", 11306 NULL); 11307 /* Reset to 1. */ 11308 part->maxOccurs = 1; 11309 } 11310 if (last == NULL) 11311 item->children = (xmlSchemaTreeItemPtr) part; 11312 else 11313 last->next = (xmlSchemaTreeItemPtr) part; 11314 last = part; 11315 } 11316 child = child->next; 11317 } 11318 if (child != NULL) { 11319 xmlSchemaPContentErr(ctxt, 11320 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11321 NULL, node, child, NULL, 11322 "(annotation?, (annotation?, element*)"); 11323 } 11324 } else { 11325 /* choice + sequence */ 11326 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11327 11328 while ((IS_SCHEMA(child, "element")) || 11329 (IS_SCHEMA(child, "group")) || 11330 (IS_SCHEMA(child, "any")) || 11331 (IS_SCHEMA(child, "choice")) || 11332 (IS_SCHEMA(child, "sequence"))) { 11333 11334 if (IS_SCHEMA(child, "element")) { 11335 part = (xmlSchemaTreeItemPtr) 11336 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11337 if (part && isElemRef) 11338 hasRefs++; 11339 } else if (IS_SCHEMA(child, "group")) { 11340 part = 11341 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11342 if (part != NULL) 11343 hasRefs++; 11344 /* 11345 * Handle redefinitions. 11346 */ 11347 if (ctxt->isRedefine && ctxt->redef && 11348 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11349 part && part->children) 11350 { 11351 if ((xmlSchemaGetQNameRefName(part->children) == 11352 ctxt->redef->refName) && 11353 (xmlSchemaGetQNameRefTargetNs(part->children) == 11354 ctxt->redef->refTargetNs)) 11355 { 11356 /* 11357 * SPEC src-redefine: 11358 * (6.1) "If it has a <group> among its contents at 11359 * some level the �actual value� of whose ref 11360 * [attribute] is the same as the �actual value� of 11361 * its own name attribute plus target namespace, then 11362 * all of the following must be true:" 11363 * (6.1.1) "It must have exactly one such group." 11364 */ 11365 if (ctxt->redefCounter != 0) { 11366 xmlChar *str = NULL; 11367 11368 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11369 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11370 "The redefining model group definition " 11371 "'%s' must not contain more than one " 11372 "reference to the redefined definition", 11373 xmlSchemaFormatQName(&str, 11374 ctxt->redef->refTargetNs, 11375 ctxt->redef->refName), 11376 NULL); 11377 FREE_AND_NULL(str) 11378 part = NULL; 11379 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11380 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11381 { 11382 xmlChar *str = NULL; 11383 /* 11384 * SPEC src-redefine: 11385 * (6.1.2) "The �actual value� of both that 11386 * group's minOccurs and maxOccurs [attribute] 11387 * must be 1 (or �absent�). 11388 */ 11389 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11390 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11391 "The redefining model group definition " 11392 "'%s' must not contain a reference to the " 11393 "redefined definition with a " 11394 "maxOccurs/minOccurs other than 1", 11395 xmlSchemaFormatQName(&str, 11396 ctxt->redef->refTargetNs, 11397 ctxt->redef->refName), 11398 NULL); 11399 FREE_AND_NULL(str) 11400 part = NULL; 11401 } 11402 ctxt->redef->reference = WXS_BASIC_CAST part; 11403 ctxt->redefCounter++; 11404 } 11405 } 11406 } else if (IS_SCHEMA(child, "any")) { 11407 part = (xmlSchemaTreeItemPtr) 11408 xmlSchemaParseAny(ctxt, schema, child); 11409 } else if (IS_SCHEMA(child, "choice")) { 11410 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11411 XML_SCHEMA_TYPE_CHOICE, 1); 11412 } else if (IS_SCHEMA(child, "sequence")) { 11413 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11414 XML_SCHEMA_TYPE_SEQUENCE, 1); 11415 } 11416 if (part != NULL) { 11417 if (last == NULL) 11418 item->children = part; 11419 else 11420 last->next = part; 11421 last = part; 11422 } 11423 child = child->next; 11424 } 11425 if (child != NULL) { 11426 xmlSchemaPContentErr(ctxt, 11427 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11428 NULL, node, child, NULL, 11429 "(annotation?, (element | group | choice | sequence | any)*)"); 11430 } 11431 } 11432 if ((max == 0) && (min == 0)) 11433 return (NULL); 11434 if (hasRefs) { 11435 /* 11436 * We need to resolve references. 11437 */ 11438 WXS_ADD_PENDING(ctxt, item); 11439 } 11440 if (withParticle) 11441 return ((xmlSchemaTreeItemPtr) particle); 11442 else 11443 return ((xmlSchemaTreeItemPtr) item); 11444 } 11445 11457 static xmlSchemaTypePtr 11458 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11459 xmlNodePtr node, xmlSchemaTypeType parentType) 11460 { 11461 xmlSchemaTypePtr type; 11462 xmlNodePtr child = NULL; 11463 xmlAttrPtr attr; 11464 11465 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11466 return (NULL); 11467 /* Not a component, don't create it. */ 11468 type = ctxt->ctxtType; 11469 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11470 11471 /* 11472 * Check for illegal attributes. 11473 */ 11474 attr = node->properties; 11475 while (attr != NULL) { 11476 if (attr->ns == NULL) { 11477 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11478 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11479 xmlSchemaPIllegalAttrErr(ctxt, 11480 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11481 } 11482 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11483 xmlSchemaPIllegalAttrErr(ctxt, 11484 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11485 } 11486 attr = attr->next; 11487 } 11488 /* 11489 * Extract and validate attributes. 11490 */ 11491 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11492 /* 11493 * Attribute 11494 */ 11495 /* 11496 * Extract the base type. The "base" attribute is mandatory if inside 11497 * a complex type or if redefining. 11498 * 11499 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11500 * among its [children]), the simple type definition which is 11501 * the {content type} of the type definition �resolved� to by 11502 * the �actual value� of the base [attribute]" 11503 */ 11504 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11505 &(type->baseNs), &(type->base)) == 0) 11506 { 11507 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11508 xmlSchemaPMissingAttrErr(ctxt, 11509 XML_SCHEMAP_S4S_ATTR_MISSING, 11510 NULL, node, "base", NULL); 11511 } else if ((ctxt->isRedefine) && 11512 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11513 { 11514 if (type->base == NULL) { 11515 xmlSchemaPMissingAttrErr(ctxt, 11516 XML_SCHEMAP_S4S_ATTR_MISSING, 11517 NULL, node, "base", NULL); 11518 } else if ((! xmlStrEqual(type->base, type->name)) || 11519 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11520 { 11521 xmlChar *str1 = NULL, *str2 = NULL; 11522 /* 11523 * REDEFINE: SPEC src-redefine (5) 11524 * "Within the [children], each <simpleType> must have a 11525 * <restriction> among its [children] ... the �actual value� of 11526 * whose base [attribute] must be the same as the �actual value� 11527 * of its own name attribute plus target namespace;" 11528 */ 11529 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11530 NULL, node, "This is a redefinition, but the QName " 11531 "value '%s' of the 'base' attribute does not match the " 11532 "type's designation '%s'", 11533 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11534 xmlSchemaFormatQName(&str2, type->targetNamespace, 11535 type->name), NULL); 11536 FREE_AND_NULL(str1); 11537 FREE_AND_NULL(str2); 11538 /* Avoid confusion and erase the values. */ 11539 type->base = NULL; 11540 type->baseNs = NULL; 11541 } 11542 } 11543 } 11544 /* 11545 * And now for the children... 11546 */ 11547 child = node->children; 11548 if (IS_SCHEMA(child, "annotation")) { 11549 /* 11550 * Add the annotation to the simple type ancestor. 11551 */ 11552 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11553 xmlSchemaParseAnnotation(ctxt, child, 1)); 11554 child = child->next; 11555 } 11556 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11557 /* 11558 * Corresponds to <simpleType><restriction><simpleType>. 11559 */ 11560 if (IS_SCHEMA(child, "simpleType")) { 11561 if (type->base != NULL) { 11562 /* 11563 * src-restriction-base-or-simpleType 11564 * Either the base [attribute] or the simpleType [child] of the 11565 * <restriction> element must be present, but not both. 11566 */ 11567 xmlSchemaPContentErr(ctxt, 11568 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11569 NULL, node, child, 11570 "The attribute 'base' and the <simpleType> child are " 11571 "mutually exclusive", NULL); 11572 } else { 11573 type->baseType = (xmlSchemaTypePtr) 11574 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11575 } 11576 child = child->next; 11577 } else if (type->base == NULL) { 11578 xmlSchemaPContentErr(ctxt, 11579 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11580 NULL, node, child, 11581 "Either the attribute 'base' or a <simpleType> child " 11582 "must be present", NULL); 11583 } 11584 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11585 /* 11586 * Corresponds to <complexType><complexContent><restriction>... 11587 * followed by: 11588 * 11589 * Model groups <all>, <choice> and <sequence>. 11590 */ 11591 if (IS_SCHEMA(child, "all")) { 11592 type->subtypes = (xmlSchemaTypePtr) 11593 xmlSchemaParseModelGroup(ctxt, schema, child, 11594 XML_SCHEMA_TYPE_ALL, 1); 11595 child = child->next; 11596 } else if (IS_SCHEMA(child, "choice")) { 11597 type->subtypes = (xmlSchemaTypePtr) 11598 xmlSchemaParseModelGroup(ctxt, 11599 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11600 child = child->next; 11601 } else if (IS_SCHEMA(child, "sequence")) { 11602 type->subtypes = (xmlSchemaTypePtr) 11603 xmlSchemaParseModelGroup(ctxt, schema, child, 11604 XML_SCHEMA_TYPE_SEQUENCE, 1); 11605 child = child->next; 11606 /* 11607 * Model group reference <group>. 11608 */ 11609 } else if (IS_SCHEMA(child, "group")) { 11610 type->subtypes = (xmlSchemaTypePtr) 11611 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11612 /* 11613 * Note that the reference will be resolved in 11614 * xmlSchemaResolveTypeReferences(); 11615 */ 11616 child = child->next; 11617 } 11618 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11619 /* 11620 * Corresponds to <complexType><simpleContent><restriction>... 11621 * 11622 * "1.1 the simple type definition corresponding to the <simpleType> 11623 * among the [children] of <restriction> if there is one;" 11624 */ 11625 if (IS_SCHEMA(child, "simpleType")) { 11626 /* 11627 * We will store the to-be-restricted simple type in 11628 * type->contentTypeDef *temporarily*. 11629 */ 11630 type->contentTypeDef = (xmlSchemaTypePtr) 11631 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11632 if ( type->contentTypeDef == NULL) 11633 return (NULL); 11634 child = child->next; 11635 } 11636 } 11637 11638 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11639 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11640 xmlSchemaFacetPtr facet, lastfacet = NULL; 11641 /* 11642 * Corresponds to <complexType><simpleContent><restriction>... 11643 * <simpleType><restriction>... 11644 */ 11645 11646 /* 11647 * Add the facets to the simple type ancestor. 11648 */ 11649 /* 11650 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11651 * Simple Type Definition Schema Representation Constraint: 11652 * *Single Facet Value* 11653 */ 11654 while ((IS_SCHEMA(child, "minInclusive")) || 11655 (IS_SCHEMA(child, "minExclusive")) || 11656 (IS_SCHEMA(child, "maxInclusive")) || 11657 (IS_SCHEMA(child, "maxExclusive")) || 11658 (IS_SCHEMA(child, "totalDigits")) || 11659 (IS_SCHEMA(child, "fractionDigits")) || 11660 (IS_SCHEMA(child, "pattern")) || 11661 (IS_SCHEMA(child, "enumeration")) || 11662 (IS_SCHEMA(child, "whiteSpace")) || 11663 (IS_SCHEMA(child, "length")) || 11664 (IS_SCHEMA(child, "maxLength")) || 11665 (IS_SCHEMA(child, "minLength"))) { 11666 facet = xmlSchemaParseFacet(ctxt, schema, child); 11667 if (facet != NULL) { 11668 if (lastfacet == NULL) 11669 type->facets = facet; 11670 else 11671 lastfacet->next = facet; 11672 lastfacet = facet; 11673 lastfacet->next = NULL; 11674 } 11675 child = child->next; 11676 } 11677 /* 11678 * Create links for derivation and validation. 11679 */ 11680 if (type->facets != NULL) { 11681 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11682 11683 facet = type->facets; 11684 do { 11685 facetLink = (xmlSchemaFacetLinkPtr) 11686 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11687 if (facetLink == NULL) { 11688 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11689 xmlFree(facetLink); 11690 return (NULL); 11691 } 11692 facetLink->facet = facet; 11693 facetLink->next = NULL; 11694 if (lastFacetLink == NULL) 11695 type->facetSet = facetLink; 11696 else 11697 lastFacetLink->next = facetLink; 11698 lastFacetLink = facetLink; 11699 facet = facet->next; 11700 } while (facet != NULL); 11701 } 11702 } 11703 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11704 /* 11705 * Attribute uses/declarations. 11706 */ 11707 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11708 (xmlSchemaItemListPtr *) &(type->attrUses), 11709 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11710 return(NULL); 11711 /* 11712 * Attribute wildcard. 11713 */ 11714 if (IS_SCHEMA(child, "anyAttribute")) { 11715 type->attributeWildcard = 11716 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11717 child = child->next; 11718 } 11719 } 11720 if (child != NULL) { 11721 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11722 xmlSchemaPContentErr(ctxt, 11723 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11724 NULL, node, child, NULL, 11725 "annotation?, (group | all | choice | sequence)?, " 11726 "((attribute | attributeGroup)*, anyAttribute?))"); 11727 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11728 xmlSchemaPContentErr(ctxt, 11729 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11730 NULL, node, child, NULL, 11731 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11732 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11733 "length | minLength | maxLength | enumeration | whiteSpace | " 11734 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11735 } else { 11736 /* Simple type */ 11737 xmlSchemaPContentErr(ctxt, 11738 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11739 NULL, node, child, NULL, 11740 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11741 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11742 "length | minLength | maxLength | enumeration | whiteSpace | " 11743 "pattern)*))"); 11744 } 11745 } 11746 return (NULL); 11747 } 11748 11761 static xmlSchemaTypePtr 11762 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11763 xmlNodePtr node, xmlSchemaTypeType parentType) 11764 { 11765 xmlSchemaTypePtr type; 11766 xmlNodePtr child = NULL; 11767 xmlAttrPtr attr; 11768 11769 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11770 return (NULL); 11771 /* Not a component, don't create it. */ 11772 type = ctxt->ctxtType; 11773 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11774 11775 /* 11776 * Check for illegal attributes. 11777 */ 11778 attr = node->properties; 11779 while (attr != NULL) { 11780 if (attr->ns == NULL) { 11781 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11782 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11783 xmlSchemaPIllegalAttrErr(ctxt, 11784 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11785 } 11786 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11787 xmlSchemaPIllegalAttrErr(ctxt, 11788 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11789 } 11790 attr = attr->next; 11791 } 11792 11793 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11794 11795 /* 11796 * Attribute "base" - mandatory. 11797 */ 11798 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11799 "base", &(type->baseNs), &(type->base)) == 0) && 11800 (type->base == NULL)) { 11801 xmlSchemaPMissingAttrErr(ctxt, 11802 XML_SCHEMAP_S4S_ATTR_MISSING, 11803 NULL, node, "base", NULL); 11804 } 11805 /* 11806 * And now for the children... 11807 */ 11808 child = node->children; 11809 if (IS_SCHEMA(child, "annotation")) { 11810 /* 11811 * Add the annotation to the type ancestor. 11812 */ 11813 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11814 xmlSchemaParseAnnotation(ctxt, child, 1)); 11815 child = child->next; 11816 } 11817 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11818 /* 11819 * Corresponds to <complexType><complexContent><extension>... and: 11820 * 11821 * Model groups <all>, <choice>, <sequence> and <group>. 11822 */ 11823 if (IS_SCHEMA(child, "all")) { 11824 type->subtypes = (xmlSchemaTypePtr) 11825 xmlSchemaParseModelGroup(ctxt, schema, 11826 child, XML_SCHEMA_TYPE_ALL, 1); 11827 child = child->next; 11828 } else if (IS_SCHEMA(child, "choice")) { 11829 type->subtypes = (xmlSchemaTypePtr) 11830 xmlSchemaParseModelGroup(ctxt, schema, 11831 child, XML_SCHEMA_TYPE_CHOICE, 1); 11832 child = child->next; 11833 } else if (IS_SCHEMA(child, "sequence")) { 11834 type->subtypes = (xmlSchemaTypePtr) 11835 xmlSchemaParseModelGroup(ctxt, schema, 11836 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11837 child = child->next; 11838 } else if (IS_SCHEMA(child, "group")) { 11839 type->subtypes = (xmlSchemaTypePtr) 11840 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11841 /* 11842 * Note that the reference will be resolved in 11843 * xmlSchemaResolveTypeReferences(); 11844 */ 11845 child = child->next; 11846 } 11847 } 11848 if (child != NULL) { 11849 /* 11850 * Attribute uses/declarations. 11851 */ 11852 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11853 (xmlSchemaItemListPtr *) &(type->attrUses), 11854 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11855 return(NULL); 11856 /* 11857 * Attribute wildcard. 11858 */ 11859 if (IS_SCHEMA(child, "anyAttribute")) { 11860 ctxt->ctxtType->attributeWildcard = 11861 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11862 child = child->next; 11863 } 11864 } 11865 if (child != NULL) { 11866 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11867 /* Complex content extension. */ 11868 xmlSchemaPContentErr(ctxt, 11869 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11870 NULL, node, child, NULL, 11871 "(annotation?, ((group | all | choice | sequence)?, " 11872 "((attribute | attributeGroup)*, anyAttribute?)))"); 11873 } else { 11874 /* Simple content extension. */ 11875 xmlSchemaPContentErr(ctxt, 11876 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11877 NULL, node, child, NULL, 11878 "(annotation?, ((attribute | attributeGroup)*, " 11879 "anyAttribute?))"); 11880 } 11881 } 11882 return (NULL); 11883 } 11884 11896 static int 11897 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11898 xmlSchemaPtr schema, xmlNodePtr node, 11899 int *hasRestrictionOrExtension) 11900 { 11901 xmlSchemaTypePtr type; 11902 xmlNodePtr child = NULL; 11903 xmlAttrPtr attr; 11904 11905 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11906 (hasRestrictionOrExtension == NULL)) 11907 return (-1); 11908 *hasRestrictionOrExtension = 0; 11909 /* Not a component, don't create it. */ 11910 type = ctxt->ctxtType; 11911 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11912 /* 11913 * Check for illegal attributes. 11914 */ 11915 attr = node->properties; 11916 while (attr != NULL) { 11917 if (attr->ns == NULL) { 11918 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11919 xmlSchemaPIllegalAttrErr(ctxt, 11920 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11921 } 11922 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11923 xmlSchemaPIllegalAttrErr(ctxt, 11924 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11925 } 11926 attr = attr->next; 11927 } 11928 11929 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11930 11931 /* 11932 * And now for the children... 11933 */ 11934 child = node->children; 11935 if (IS_SCHEMA(child, "annotation")) { 11936 /* 11937 * Add the annotation to the complex type ancestor. 11938 */ 11939 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11940 xmlSchemaParseAnnotation(ctxt, child, 1)); 11941 child = child->next; 11942 } 11943 if (child == NULL) { 11944 xmlSchemaPContentErr(ctxt, 11945 XML_SCHEMAP_S4S_ELEM_MISSING, 11946 NULL, node, NULL, NULL, 11947 "(annotation?, (restriction | extension))"); 11948 } 11949 if (child == NULL) { 11950 xmlSchemaPContentErr(ctxt, 11951 XML_SCHEMAP_S4S_ELEM_MISSING, 11952 NULL, node, NULL, NULL, 11953 "(annotation?, (restriction | extension))"); 11954 } 11955 if (IS_SCHEMA(child, "restriction")) { 11956 xmlSchemaParseRestriction(ctxt, schema, child, 11957 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11958 (*hasRestrictionOrExtension) = 1; 11959 child = child->next; 11960 } else if (IS_SCHEMA(child, "extension")) { 11961 xmlSchemaParseExtension(ctxt, schema, child, 11962 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11963 (*hasRestrictionOrExtension) = 1; 11964 child = child->next; 11965 } 11966 if (child != NULL) { 11967 xmlSchemaPContentErr(ctxt, 11968 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11969 NULL, node, child, NULL, 11970 "(annotation?, (restriction | extension))"); 11971 } 11972 return (0); 11973 } 11974 11986 static int 11987 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 11988 xmlSchemaPtr schema, xmlNodePtr node, 11989 int *hasRestrictionOrExtension) 11990 { 11991 xmlSchemaTypePtr type; 11992 xmlNodePtr child = NULL; 11993 xmlAttrPtr attr; 11994 11995 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11996 (hasRestrictionOrExtension == NULL)) 11997 return (-1); 11998 *hasRestrictionOrExtension = 0; 11999 /* Not a component, don't create it. */ 12000 type = ctxt->ctxtType; 12001 /* 12002 * Check for illegal attributes. 12003 */ 12004 attr = node->properties; 12005 while (attr != NULL) { 12006 if (attr->ns == NULL) { 12007 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12008 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12009 { 12010 xmlSchemaPIllegalAttrErr(ctxt, 12011 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12012 } 12013 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12014 xmlSchemaPIllegalAttrErr(ctxt, 12015 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12016 } 12017 attr = attr->next; 12018 } 12019 12020 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12021 12022 /* 12023 * Set the 'mixed' on the complex type ancestor. 12024 */ 12025 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12026 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12027 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12028 } 12029 child = node->children; 12030 if (IS_SCHEMA(child, "annotation")) { 12031 /* 12032 * Add the annotation to the complex type ancestor. 12033 */ 12034 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12035 xmlSchemaParseAnnotation(ctxt, child, 1)); 12036 child = child->next; 12037 } 12038 if (child == NULL) { 12039 xmlSchemaPContentErr(ctxt, 12040 XML_SCHEMAP_S4S_ELEM_MISSING, 12041 NULL, node, NULL, 12042 NULL, "(annotation?, (restriction | extension))"); 12043 } 12044 if (child == NULL) { 12045 xmlSchemaPContentErr(ctxt, 12046 XML_SCHEMAP_S4S_ELEM_MISSING, 12047 NULL, node, NULL, 12048 NULL, "(annotation?, (restriction | extension))"); 12049 } 12050 if (IS_SCHEMA(child, "restriction")) { 12051 xmlSchemaParseRestriction(ctxt, schema, child, 12052 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12053 (*hasRestrictionOrExtension) = 1; 12054 child = child->next; 12055 } else if (IS_SCHEMA(child, "extension")) { 12056 xmlSchemaParseExtension(ctxt, schema, child, 12057 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12058 (*hasRestrictionOrExtension) = 1; 12059 child = child->next; 12060 } 12061 if (child != NULL) { 12062 xmlSchemaPContentErr(ctxt, 12063 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12064 NULL, node, child, 12065 NULL, "(annotation?, (restriction | extension))"); 12066 } 12067 return (0); 12068 } 12069 12081 static xmlSchemaTypePtr 12082 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12083 xmlNodePtr node, int topLevel) 12084 { 12085 xmlSchemaTypePtr type, ctxtType; 12086 xmlNodePtr child = NULL; 12087 const xmlChar *name = NULL; 12088 xmlAttrPtr attr; 12089 const xmlChar *attrValue; 12090 #ifdef ENABLE_NAMED_LOCALS 12091 char buf[40]; 12092 #endif 12093 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12094 12095 12096 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12097 return (NULL); 12098 12099 ctxtType = ctxt->ctxtType; 12100 12101 if (topLevel) { 12102 attr = xmlSchemaGetPropNode(node, "name"); 12103 if (attr == NULL) { 12104 xmlSchemaPMissingAttrErr(ctxt, 12105 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12106 return (NULL); 12107 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12108 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12109 return (NULL); 12110 } 12111 } 12112 12113 if (topLevel == 0) { 12114 /* 12115 * Parse as local complex type definition. 12116 */ 12117 #ifdef ENABLE_NAMED_LOCALS 12118 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12119 type = xmlSchemaAddType(ctxt, schema, 12120 XML_SCHEMA_TYPE_COMPLEX, 12121 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12122 ctxt->targetNamespace, node, 0); 12123 #else 12124 type = xmlSchemaAddType(ctxt, schema, 12125 XML_SCHEMA_TYPE_COMPLEX, 12126 NULL, ctxt->targetNamespace, node, 0); 12127 #endif 12128 if (type == NULL) 12129 return (NULL); 12130 name = type->name; 12131 type->node = node; 12132 type->type = XML_SCHEMA_TYPE_COMPLEX; 12133 /* 12134 * TODO: We need the target namespace. 12135 */ 12136 } else { 12137 /* 12138 * Parse as global complex type definition. 12139 */ 12140 type = xmlSchemaAddType(ctxt, schema, 12141 XML_SCHEMA_TYPE_COMPLEX, 12142 name, ctxt->targetNamespace, node, 1); 12143 if (type == NULL) 12144 return (NULL); 12145 type->node = node; 12146 type->type = XML_SCHEMA_TYPE_COMPLEX; 12147 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12148 } 12149 type->targetNamespace = ctxt->targetNamespace; 12150 /* 12151 * Handle attributes. 12152 */ 12153 attr = node->properties; 12154 while (attr != NULL) { 12155 if (attr->ns == NULL) { 12156 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12157 /* 12158 * Attribute "id". 12159 */ 12160 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12161 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12162 /* 12163 * Attribute "mixed". 12164 */ 12165 if (xmlSchemaPGetBoolNodeValue(ctxt, 12166 NULL, (xmlNodePtr) attr)) 12167 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12168 } else if (topLevel) { 12169 /* 12170 * Attributes of global complex type definitions. 12171 */ 12172 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12173 /* Pass. */ 12174 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12175 /* 12176 * Attribute "abstract". 12177 */ 12178 if (xmlSchemaPGetBoolNodeValue(ctxt, 12179 NULL, (xmlNodePtr) attr)) 12180 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12181 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12182 /* 12183 * Attribute "final". 12184 */ 12185 attrValue = xmlSchemaGetNodeContent(ctxt, 12186 (xmlNodePtr) attr); 12187 if (xmlSchemaPValAttrBlockFinal(attrValue, 12188 &(type->flags), 12189 -1, 12190 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12191 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12192 -1, -1, -1) != 0) 12193 { 12194 xmlSchemaPSimpleTypeErr(ctxt, 12195 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12196 NULL, (xmlNodePtr) attr, NULL, 12197 "(#all | List of (extension | restriction))", 12198 attrValue, NULL, NULL, NULL); 12199 } else 12200 final = 1; 12201 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12202 /* 12203 * Attribute "block". 12204 */ 12205 attrValue = xmlSchemaGetNodeContent(ctxt, 12206 (xmlNodePtr) attr); 12207 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12208 -1, 12209 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12210 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12211 -1, -1, -1) != 0) { 12212 xmlSchemaPSimpleTypeErr(ctxt, 12213 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12214 NULL, (xmlNodePtr) attr, NULL, 12215 "(#all | List of (extension | restriction)) ", 12216 attrValue, NULL, NULL, NULL); 12217 } else 12218 block = 1; 12219 } else { 12220 xmlSchemaPIllegalAttrErr(ctxt, 12221 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12222 } 12223 } else { 12224 xmlSchemaPIllegalAttrErr(ctxt, 12225 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12226 } 12227 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12228 xmlSchemaPIllegalAttrErr(ctxt, 12229 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12230 } 12231 attr = attr->next; 12232 } 12233 if (! block) { 12234 /* 12235 * Apply default "block" values. 12236 */ 12237 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12238 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12239 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12240 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12241 } 12242 if (! final) { 12243 /* 12244 * Apply default "block" values. 12245 */ 12246 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12247 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12248 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12249 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12250 } 12251 /* 12252 * And now for the children... 12253 */ 12254 child = node->children; 12255 if (IS_SCHEMA(child, "annotation")) { 12256 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12257 child = child->next; 12258 } 12259 ctxt->ctxtType = type; 12260 if (IS_SCHEMA(child, "simpleContent")) { 12261 /* 12262 * <complexType><simpleContent>... 12263 * 3.4.3 : 2.2 12264 * Specifying mixed='true' when the <simpleContent> 12265 * alternative is chosen has no effect 12266 */ 12267 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12268 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12269 xmlSchemaParseSimpleContent(ctxt, schema, child, 12270 &hasRestrictionOrExtension); 12271 child = child->next; 12272 } else if (IS_SCHEMA(child, "complexContent")) { 12273 /* 12274 * <complexType><complexContent>... 12275 */ 12276 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12277 xmlSchemaParseComplexContent(ctxt, schema, child, 12278 &hasRestrictionOrExtension); 12279 child = child->next; 12280 } else { 12281 /* 12282 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12283 * 12284 * SPEC 12285 * "...the third alternative (neither <simpleContent> nor 12286 * <complexContent>) is chosen. This case is understood as shorthand 12287 * for complex content restricting the �ur-type definition�, and the 12288 * details of the mappings should be modified as necessary. 12289 */ 12290 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12291 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12292 /* 12293 * Parse model groups. 12294 */ 12295 if (IS_SCHEMA(child, "all")) { 12296 type->subtypes = (xmlSchemaTypePtr) 12297 xmlSchemaParseModelGroup(ctxt, schema, child, 12298 XML_SCHEMA_TYPE_ALL, 1); 12299 child = child->next; 12300 } else if (IS_SCHEMA(child, "choice")) { 12301 type->subtypes = (xmlSchemaTypePtr) 12302 xmlSchemaParseModelGroup(ctxt, schema, child, 12303 XML_SCHEMA_TYPE_CHOICE, 1); 12304 child = child->next; 12305 } else if (IS_SCHEMA(child, "sequence")) { 12306 type->subtypes = (xmlSchemaTypePtr) 12307 xmlSchemaParseModelGroup(ctxt, schema, child, 12308 XML_SCHEMA_TYPE_SEQUENCE, 1); 12309 child = child->next; 12310 } else if (IS_SCHEMA(child, "group")) { 12311 type->subtypes = (xmlSchemaTypePtr) 12312 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12313 /* 12314 * Note that the reference will be resolved in 12315 * xmlSchemaResolveTypeReferences(); 12316 */ 12317 child = child->next; 12318 } 12319 /* 12320 * Parse attribute decls/refs. 12321 */ 12322 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12323 (xmlSchemaItemListPtr *) &(type->attrUses), 12324 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12325 return(NULL); 12326 /* 12327 * Parse attribute wildcard. 12328 */ 12329 if (IS_SCHEMA(child, "anyAttribute")) { 12330 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12331 child = child->next; 12332 } 12333 } 12334 if (child != NULL) { 12335 xmlSchemaPContentErr(ctxt, 12336 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12337 NULL, node, child, 12338 NULL, "(annotation?, (simpleContent | complexContent | " 12339 "((group | all | choice | sequence)?, ((attribute | " 12340 "attributeGroup)*, anyAttribute?))))"); 12341 } 12342 /* 12343 * REDEFINE: SPEC src-redefine (5) 12344 */ 12345 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12346 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12347 NULL, node, "This is a redefinition, thus the " 12348 "<complexType> must have a <restriction> or <extension> " 12349 "grand-child", NULL); 12350 } 12351 ctxt->ctxtType = ctxtType; 12352 return (type); 12353 } 12354 12355 /************************************************************************ 12356 * * 12357 * Validating using Schemas * 12358 * * 12359 ************************************************************************/ 12360 12361 /************************************************************************ 12362 * * 12363 * Reading/Writing Schemas * 12364 * * 12365 ************************************************************************/ 12366 12367 #if 0 /* Will be enabled if it is clear what options are needed. */ 12368 12378 static int 12379 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12380 int options) 12381 12382 { 12383 int i; 12384 12385 if (ctxt == NULL) 12386 return (-1); 12387 /* 12388 * WARNING: Change the start value if adding to the 12389 * xmlSchemaParseOption. 12390 */ 12391 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12392 if (options & 1<<i) { 12393 return (-1); 12394 } 12395 } 12396 ctxt->options = options; 12397 return (0); 12398 } 12399 12406 static int 12407 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12408 12409 { 12410 if (ctxt == NULL) 12411 return (-1); 12412 else 12413 return (ctxt->options); 12414 } 12415 #endif 12416 12426 xmlSchemaParserCtxtPtr 12427 xmlSchemaNewParserCtxt(const char *URL) 12428 { 12429 xmlSchemaParserCtxtPtr ret; 12430 12431 if (URL == NULL) 12432 return (NULL); 12433 12434 ret = xmlSchemaParserCtxtCreate(); 12435 if (ret == NULL) 12436 return(NULL); 12437 ret->dict = xmlDictCreate(); 12438 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12439 return (ret); 12440 } 12441 12452 xmlSchemaParserCtxtPtr 12453 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12454 { 12455 xmlSchemaParserCtxtPtr ret; 12456 12457 if ((buffer == NULL) || (size <= 0)) 12458 return (NULL); 12459 ret = xmlSchemaParserCtxtCreate(); 12460 if (ret == NULL) 12461 return(NULL); 12462 ret->buffer = buffer; 12463 ret->size = size; 12464 ret->dict = xmlDictCreate(); 12465 return (ret); 12466 } 12467 12477 xmlSchemaParserCtxtPtr 12478 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12479 { 12480 xmlSchemaParserCtxtPtr ret; 12481 12482 if (doc == NULL) 12483 return (NULL); 12484 ret = xmlSchemaParserCtxtCreate(); 12485 if (ret == NULL) 12486 return(NULL); 12487 ret->doc = doc; 12488 ret->dict = xmlDictCreate(); 12489 /* The application has responsibility for the document */ 12490 ret->preserve = 1; 12491 12492 return (ret); 12493 } 12494 12501 void 12502 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12503 { 12504 if (ctxt == NULL) 12505 return; 12506 if (ctxt->doc != NULL && !ctxt->preserve) 12507 xmlFreeDoc(ctxt->doc); 12508 if (ctxt->vctxt != NULL) { 12509 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12510 } 12511 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12512 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12513 ctxt->constructor = NULL; 12514 ctxt->ownsConstructor = 0; 12515 } 12516 if (ctxt->attrProhibs != NULL) 12517 xmlSchemaItemListFree(ctxt->attrProhibs); 12518 xmlDictFree(ctxt->dict); 12519 xmlFree(ctxt); 12520 } 12521 12522 /************************************************************************ 12523 * * 12524 * Building the content models * 12525 * * 12526 ************************************************************************/ 12527 12533 static int 12534 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12535 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12536 { 12537 xmlAutomataStatePtr start, tmp; 12538 xmlSchemaElementPtr elemDecl, member; 12539 xmlSchemaSubstGroupPtr substGroup; 12540 int i; 12541 int ret = 0; 12542 12543 elemDecl = (xmlSchemaElementPtr) particle->children; 12544 /* 12545 * Wrap the substitution group with a CHOICE. 12546 */ 12547 start = pctxt->state; 12548 if (end == NULL) 12549 end = xmlAutomataNewState(pctxt->am); 12550 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12551 if (substGroup == NULL) { 12552 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12553 XML_SCHEMAP_INTERNAL, 12554 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12555 "declaration is marked having a subst. group but none " 12556 "available.\n", elemDecl->name, NULL); 12557 return(0); 12558 } 12559 if (counter >= 0) { 12560 /* 12561 * NOTE that we put the declaration in, even if it's abstract. 12562 * However, an error will be raised during *validation* if an element 12563 * information item shall be validated against an abstract element 12564 * declaration. 12565 */ 12566 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12567 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12568 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12569 /* 12570 * Add subst. group members. 12571 */ 12572 for (i = 0; i < substGroup->members->nbItems; i++) { 12573 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12574 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12575 member->name, member->targetNamespace, member); 12576 } 12577 } else if (particle->maxOccurs == 1) { 12578 /* 12579 * NOTE that we put the declaration in, even if it's abstract, 12580 */ 12581 xmlAutomataNewEpsilon(pctxt->am, 12582 xmlAutomataNewTransition2(pctxt->am, 12583 start, NULL, 12584 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12585 /* 12586 * Add subst. group members. 12587 */ 12588 for (i = 0; i < substGroup->members->nbItems; i++) { 12589 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12590 /* 12591 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12592 * was incorrectly used instead of xmlAutomataNewTransition2() 12593 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12594 * section in xmlSchemaBuildAContentModel() ). 12595 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12596 * intended for the above "counter" section originally. I.e., 12597 * check xs:all with subst-groups. 12598 * 12599 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12600 * member->name, member->targetNamespace, 12601 * 1, 1, member); 12602 */ 12603 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12604 member->name, member->targetNamespace, member); 12605 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12606 } 12607 } else { 12608 xmlAutomataStatePtr hop; 12609 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12610 UNBOUNDED : particle->maxOccurs - 1; 12611 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12612 12613 counter = 12614 xmlAutomataNewCounter(pctxt->am, minOccurs, 12615 maxOccurs); 12616 hop = xmlAutomataNewState(pctxt->am); 12617 12618 xmlAutomataNewEpsilon(pctxt->am, 12619 xmlAutomataNewTransition2(pctxt->am, 12620 start, NULL, 12621 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12622 hop); 12623 /* 12624 * Add subst. group members. 12625 */ 12626 for (i = 0; i < substGroup->members->nbItems; i++) { 12627 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12628 xmlAutomataNewEpsilon(pctxt->am, 12629 xmlAutomataNewTransition2(pctxt->am, 12630 start, NULL, 12631 member->name, member->targetNamespace, member), 12632 hop); 12633 } 12634 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12635 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12636 } 12637 if (particle->minOccurs == 0) { 12638 xmlAutomataNewEpsilon(pctxt->am, start, end); 12639 ret = 1; 12640 } 12641 pctxt->state = end; 12642 return(ret); 12643 } 12644 12650 static int 12651 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12652 xmlSchemaParticlePtr particle) 12653 { 12654 int ret = 0; 12655 12656 if (((xmlSchemaElementPtr) particle->children)->flags & 12657 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12658 /* 12659 * Substitution groups. 12660 */ 12661 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12662 } else { 12663 xmlSchemaElementPtr elemDecl; 12664 xmlAutomataStatePtr start; 12665 12666 elemDecl = (xmlSchemaElementPtr) particle->children; 12667 12668 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12669 return(0); 12670 if (particle->maxOccurs == 1) { 12671 start = ctxt->state; 12672 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12673 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12674 } else if ((particle->maxOccurs >= UNBOUNDED) && 12675 (particle->minOccurs < 2)) { 12676 /* Special case. */ 12677 start = ctxt->state; 12678 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12679 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12680 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12681 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12682 } else { 12683 int counter; 12684 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12685 UNBOUNDED : particle->maxOccurs - 1; 12686 int minOccurs = particle->minOccurs < 1 ? 12687 0 : particle->minOccurs - 1; 12688 12689 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12690 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12691 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12692 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12693 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12694 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12695 NULL, counter); 12696 } 12697 if (particle->minOccurs == 0) { 12698 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12699 ret = 1; 12700 } 12701 } 12702 return(ret); 12703 } 12704 12715 static int 12716 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12717 xmlSchemaParticlePtr particle) 12718 { 12719 int ret = 0, tmp2; 12720 12721 if (particle == NULL) { 12722 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12723 return(1); 12724 } 12725 if (particle->children == NULL) { 12726 /* 12727 * Just return in this case. A missing "term" of the particle 12728 * might arise due to an invalid "term" component. 12729 */ 12730 return(1); 12731 } 12732 12733 switch (particle->children->type) { 12734 case XML_SCHEMA_TYPE_ANY: { 12735 xmlAutomataStatePtr start, end; 12736 xmlSchemaWildcardPtr wild; 12737 xmlSchemaWildcardNsPtr ns; 12738 12739 wild = (xmlSchemaWildcardPtr) particle->children; 12740 12741 start = pctxt->state; 12742 end = xmlAutomataNewState(pctxt->am); 12743 12744 if (particle->maxOccurs == 1) { 12745 if (wild->any == 1) { 12746 /* 12747 * We need to add both transitions: 12748 * 12749 * 1. the {"*", "*"} for elements in a namespace. 12750 */ 12751 pctxt->state = 12752 xmlAutomataNewTransition2(pctxt->am, 12753 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12754 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12755 /* 12756 * 2. the {"*"} for elements in no namespace. 12757 */ 12758 pctxt->state = 12759 xmlAutomataNewTransition2(pctxt->am, 12760 start, NULL, BAD_CAST "*", NULL, wild); 12761 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12762 12763 } else if (wild->nsSet != NULL) { 12764 ns = wild->nsSet; 12765 do { 12766 pctxt->state = start; 12767 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12768 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12769 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12770 ns = ns->next; 12771 } while (ns != NULL); 12772 12773 } else if (wild->negNsSet != NULL) { 12774 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12775 start, end, BAD_CAST "*", wild->negNsSet->value, 12776 wild); 12777 } 12778 } else { 12779 int counter; 12780 xmlAutomataStatePtr hop; 12781 int maxOccurs = 12782 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12783 particle->maxOccurs - 1; 12784 int minOccurs = 12785 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12786 12787 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12788 hop = xmlAutomataNewState(pctxt->am); 12789 if (wild->any == 1) { 12790 pctxt->state = 12791 xmlAutomataNewTransition2(pctxt->am, 12792 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12793 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12794 pctxt->state = 12795 xmlAutomataNewTransition2(pctxt->am, 12796 start, NULL, BAD_CAST "*", NULL, wild); 12797 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12798 } else if (wild->nsSet != NULL) { 12799 ns = wild->nsSet; 12800 do { 12801 pctxt->state = 12802 xmlAutomataNewTransition2(pctxt->am, 12803 start, NULL, BAD_CAST "*", ns->value, wild); 12804 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12805 ns = ns->next; 12806 } while (ns != NULL); 12807 12808 } else if (wild->negNsSet != NULL) { 12809 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12810 start, hop, BAD_CAST "*", wild->negNsSet->value, 12811 wild); 12812 } 12813 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12814 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12815 } 12816 if (particle->minOccurs == 0) { 12817 xmlAutomataNewEpsilon(pctxt->am, start, end); 12818 ret = 1; 12819 } 12820 pctxt->state = end; 12821 break; 12822 } 12823 case XML_SCHEMA_TYPE_ELEMENT: 12824 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12825 break; 12826 case XML_SCHEMA_TYPE_SEQUENCE:{ 12827 xmlSchemaTreeItemPtr sub; 12828 12829 ret = 1; 12830 /* 12831 * If max and min occurances are default (1) then 12832 * simply iterate over the particles of the <sequence>. 12833 */ 12834 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12835 sub = particle->children->children; 12836 12837 while (sub != NULL) { 12838 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12839 (xmlSchemaParticlePtr) sub); 12840 if (tmp2 != 1) ret = 0; 12841 sub = sub->next; 12842 } 12843 } else { 12844 xmlAutomataStatePtr oldstate = pctxt->state; 12845 12846 if (particle->maxOccurs >= UNBOUNDED) { 12847 if (particle->minOccurs > 1) { 12848 xmlAutomataStatePtr tmp; 12849 int counter; 12850 12851 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12852 oldstate, NULL); 12853 oldstate = pctxt->state; 12854 12855 counter = xmlAutomataNewCounter(pctxt->am, 12856 particle->minOccurs - 1, UNBOUNDED); 12857 12858 sub = particle->children->children; 12859 while (sub != NULL) { 12860 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12861 (xmlSchemaParticlePtr) sub); 12862 if (tmp2 != 1) ret = 0; 12863 sub = sub->next; 12864 } 12865 tmp = pctxt->state; 12866 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12867 oldstate, counter); 12868 pctxt->state = 12869 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12870 NULL, counter); 12871 if (ret == 1) 12872 xmlAutomataNewEpsilon(pctxt->am, 12873 oldstate, pctxt->state); 12874 12875 } else { 12876 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12877 oldstate, NULL); 12878 oldstate = pctxt->state; 12879 12880 sub = particle->children->children; 12881 while (sub != NULL) { 12882 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12883 (xmlSchemaParticlePtr) sub); 12884 if (tmp2 != 1) ret = 0; 12885 sub = sub->next; 12886 } 12887 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12888 oldstate); 12889 /* 12890 * epsilon needed to block previous trans from 12891 * being allowed to enter back from another 12892 * construct 12893 */ 12894 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12895 pctxt->state, NULL); 12896 if (particle->minOccurs == 0) { 12897 xmlAutomataNewEpsilon(pctxt->am, 12898 oldstate, pctxt->state); 12899 ret = 1; 12900 } 12901 } 12902 } else if ((particle->maxOccurs > 1) 12903 || (particle->minOccurs > 1)) { 12904 xmlAutomataStatePtr tmp; 12905 int counter; 12906 12907 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12908 oldstate, NULL); 12909 oldstate = pctxt->state; 12910 12911 counter = xmlAutomataNewCounter(pctxt->am, 12912 particle->minOccurs - 1, 12913 particle->maxOccurs - 1); 12914 12915 sub = particle->children->children; 12916 while (sub != NULL) { 12917 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12918 (xmlSchemaParticlePtr) sub); 12919 if (tmp2 != 1) ret = 0; 12920 sub = sub->next; 12921 } 12922 tmp = pctxt->state; 12923 xmlAutomataNewCountedTrans(pctxt->am, 12924 tmp, oldstate, counter); 12925 pctxt->state = 12926 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12927 counter); 12928 if ((particle->minOccurs == 0) || (ret == 1)) { 12929 xmlAutomataNewEpsilon(pctxt->am, 12930 oldstate, pctxt->state); 12931 ret = 1; 12932 } 12933 } else { 12934 sub = particle->children->children; 12935 while (sub != NULL) { 12936 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12937 (xmlSchemaParticlePtr) sub); 12938 if (tmp2 != 1) ret = 0; 12939 sub = sub->next; 12940 } 12941 if (particle->minOccurs == 0) { 12942 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12943 pctxt->state); 12944 ret = 1; 12945 } 12946 } 12947 } 12948 break; 12949 } 12950 case XML_SCHEMA_TYPE_CHOICE:{ 12951 xmlSchemaTreeItemPtr sub; 12952 xmlAutomataStatePtr start, end; 12953 12954 ret = 0; 12955 start = pctxt->state; 12956 end = xmlAutomataNewState(pctxt->am); 12957 12958 /* 12959 * iterate over the subtypes and remerge the end with an 12960 * epsilon transition 12961 */ 12962 if (particle->maxOccurs == 1) { 12963 sub = particle->children->children; 12964 while (sub != NULL) { 12965 pctxt->state = start; 12966 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12967 (xmlSchemaParticlePtr) sub); 12968 if (tmp2 == 1) ret = 1; 12969 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12970 sub = sub->next; 12971 } 12972 } else { 12973 int counter; 12974 xmlAutomataStatePtr hop, base; 12975 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12976 UNBOUNDED : particle->maxOccurs - 1; 12977 int minOccurs = 12978 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12979 12980 /* 12981 * use a counter to keep track of the number of transtions 12982 * which went through the choice. 12983 */ 12984 counter = 12985 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12986 hop = xmlAutomataNewState(pctxt->am); 12987 base = xmlAutomataNewState(pctxt->am); 12988 12989 sub = particle->children->children; 12990 while (sub != NULL) { 12991 pctxt->state = base; 12992 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12993 (xmlSchemaParticlePtr) sub); 12994 if (tmp2 == 1) ret = 1; 12995 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12996 sub = sub->next; 12997 } 12998 xmlAutomataNewEpsilon(pctxt->am, start, base); 12999 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13000 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13001 if (ret == 1) 13002 xmlAutomataNewEpsilon(pctxt->am, base, end); 13003 } 13004 if (particle->minOccurs == 0) { 13005 xmlAutomataNewEpsilon(pctxt->am, start, end); 13006 ret = 1; 13007 } 13008 pctxt->state = end; 13009 break; 13010 } 13011 case XML_SCHEMA_TYPE_ALL:{ 13012 xmlAutomataStatePtr start, tmp; 13013 xmlSchemaParticlePtr sub; 13014 xmlSchemaElementPtr elemDecl; 13015 13016 ret = 1; 13017 13018 sub = (xmlSchemaParticlePtr) particle->children->children; 13019 if (sub == NULL) 13020 break; 13021 13022 ret = 0; 13023 13024 start = pctxt->state; 13025 tmp = xmlAutomataNewState(pctxt->am); 13026 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13027 pctxt->state = tmp; 13028 while (sub != NULL) { 13029 pctxt->state = tmp; 13030 13031 elemDecl = (xmlSchemaElementPtr) sub->children; 13032 if (elemDecl == NULL) { 13033 PERROR_INT("xmlSchemaBuildAContentModel", 13034 "<element> particle has no term"); 13035 return(ret); 13036 }; 13037 /* 13038 * NOTE: The {max occurs} of all the particles in the 13039 * {particles} of the group must be 0 or 1; this is 13040 * already ensured during the parse of the content of 13041 * <all>. 13042 */ 13043 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13044 int counter; 13045 13046 /* 13047 * This is an abstract group, we need to share 13048 * the same counter for all the element transitions 13049 * derived from the group 13050 */ 13051 counter = xmlAutomataNewCounter(pctxt->am, 13052 sub->minOccurs, sub->maxOccurs); 13053 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13054 sub, counter, pctxt->state); 13055 } else { 13056 if ((sub->minOccurs == 1) && 13057 (sub->maxOccurs == 1)) { 13058 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13059 pctxt->state, 13060 elemDecl->name, 13061 elemDecl->targetNamespace, 13062 1, 1, elemDecl); 13063 } else if ((sub->minOccurs == 0) && 13064 (sub->maxOccurs == 1)) { 13065 13066 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13067 pctxt->state, 13068 elemDecl->name, 13069 elemDecl->targetNamespace, 13070 0, 13071 1, 13072 elemDecl); 13073 } 13074 } 13075 sub = (xmlSchemaParticlePtr) sub->next; 13076 } 13077 pctxt->state = 13078 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13079 if (particle->minOccurs == 0) { 13080 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13081 ret = 1; 13082 } 13083 break; 13084 } 13085 case XML_SCHEMA_TYPE_GROUP: 13086 /* 13087 * If we hit a model group definition, then this means that 13088 * it was empty, thus was not substituted for the containing 13089 * model group. Just do nothing in this case. 13090 * TODO: But the group should be substituted and not occur at 13091 * all in the content model at this point. Fix this. 13092 */ 13093 ret = 1; 13094 break; 13095 default: 13096 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13097 "xmlSchemaBuildAContentModel", 13098 "found unexpected term of type '%s' in content model", 13099 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13100 return(ret); 13101 } 13102 return(ret); 13103 } 13104 13113 static void 13114 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13115 xmlSchemaParserCtxtPtr ctxt) 13116 { 13117 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13118 (type->contModel != NULL) || 13119 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13120 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13121 return; 13122 13123 #ifdef DEBUG_CONTENT 13124 xmlGenericError(xmlGenericErrorContext, 13125 "Building content model for %s\n", name); 13126 #endif 13127 ctxt->am = NULL; 13128 ctxt->am = xmlNewAutomata(); 13129 if (ctxt->am == NULL) { 13130 xmlGenericError(xmlGenericErrorContext, 13131 "Cannot create automata for complex type %s\n", type->name); 13132 return; 13133 } 13134 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13135 /* 13136 * Build the automaton. 13137 */ 13138 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13139 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13140 type->contModel = xmlAutomataCompile(ctxt->am); 13141 if (type->contModel == NULL) { 13142 xmlSchemaPCustomErr(ctxt, 13143 XML_SCHEMAP_INTERNAL, 13144 WXS_BASIC_CAST type, type->node, 13145 "Failed to compile the content model", NULL); 13146 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13147 xmlSchemaPCustomErr(ctxt, 13148 XML_SCHEMAP_NOT_DETERMINISTIC, 13149 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13150 WXS_BASIC_CAST type, type->node, 13151 "The content model is not determinist", NULL); 13152 } else { 13153 #ifdef DEBUG_CONTENT_REGEXP 13154 xmlGenericError(xmlGenericErrorContext, 13155 "Content model of %s:\n", type->name); 13156 xmlRegexpPrint(stderr, type->contModel); 13157 #endif 13158 } 13159 ctxt->state = NULL; 13160 xmlFreeAutomata(ctxt->am); 13161 ctxt->am = NULL; 13162 } 13163 13173 static void 13174 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13175 xmlSchemaParserCtxtPtr ctxt) 13176 { 13177 if ((ctxt == NULL) || (elemDecl == NULL) || 13178 ((elemDecl != NULL) && 13179 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13180 return; 13181 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13182 13183 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13184 xmlSchemaTypePtr type; 13185 13186 /* (type definition) ... otherwise the type definition �resolved� 13187 * to by the �actual value� of the type [attribute] ... 13188 */ 13189 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13190 elemDecl->namedTypeNs); 13191 if (type == NULL) { 13192 xmlSchemaPResCompAttrErr(ctxt, 13193 XML_SCHEMAP_SRC_RESOLVE, 13194 WXS_BASIC_CAST elemDecl, elemDecl->node, 13195 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13196 XML_SCHEMA_TYPE_BASIC, "type definition"); 13197 } else 13198 elemDecl->subtypes = type; 13199 } 13200 if (elemDecl->substGroup != NULL) { 13201 xmlSchemaElementPtr substHead; 13202 13203 /* 13204 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13205 * substitutionGroup? 13206 */ 13207 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13208 elemDecl->substGroupNs); 13209 if (substHead == NULL) { 13210 xmlSchemaPResCompAttrErr(ctxt, 13211 XML_SCHEMAP_SRC_RESOLVE, 13212 WXS_BASIC_CAST elemDecl, NULL, 13213 "substitutionGroup", elemDecl->substGroup, 13214 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13215 } else { 13216 xmlSchemaResolveElementReferences(substHead, ctxt); 13217 /* 13218 * Set the "substitution group affiliation". 13219 * NOTE that now we use the "refDecl" field for this. 13220 */ 13221 WXS_SUBST_HEAD(elemDecl) = substHead; 13222 /* 13223 * The type definitions is set to: 13224 * SPEC "...the {type definition} of the element 13225 * declaration �resolved� to by the �actual value� 13226 * of the substitutionGroup [attribute], if present" 13227 */ 13228 if (elemDecl->subtypes == NULL) 13229 elemDecl->subtypes = substHead->subtypes; 13230 } 13231 } 13232 /* 13233 * SPEC "The definition of anyType serves as the default type definition 13234 * for element declarations whose XML representation does not specify one." 13235 */ 13236 if ((elemDecl->subtypes == NULL) && 13237 (elemDecl->namedType == NULL) && 13238 (elemDecl->substGroup == NULL)) 13239 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13240 } 13241 13253 static int 13254 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13255 xmlSchemaTypePtr type) 13256 { 13257 13258 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13259 xmlSchemaTypePtr memberType; 13260 13261 /* 13262 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13263 * define the explicit members as the type definitions �resolved� 13264 * to by the items in the �actual value� of the memberTypes [attribute], 13265 * if any, followed by the type definitions corresponding to the 13266 * <simpleType>s among the [children] of <union>, if any." 13267 */ 13268 /* 13269 * Resolve references. 13270 */ 13271 link = type->memberTypes; 13272 lastLink = NULL; 13273 while (link != NULL) { 13274 const xmlChar *name, *nsName; 13275 13276 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13277 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13278 13279 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13280 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13281 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13282 WXS_BASIC_CAST type, type->node, "memberTypes", 13283 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13284 /* 13285 * Remove the member type link. 13286 */ 13287 if (lastLink == NULL) 13288 type->memberTypes = link->next; 13289 else 13290 lastLink->next = link->next; 13291 newLink = link; 13292 link = link->next; 13293 xmlFree(newLink); 13294 } else { 13295 link->type = memberType; 13296 lastLink = link; 13297 link = link->next; 13298 } 13299 } 13300 /* 13301 * Add local simple types, 13302 */ 13303 memberType = type->subtypes; 13304 while (memberType != NULL) { 13305 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13306 if (link == NULL) { 13307 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13308 return (-1); 13309 } 13310 link->type = memberType; 13311 link->next = NULL; 13312 if (lastLink == NULL) 13313 type->memberTypes = link; 13314 else 13315 lastLink->next = link; 13316 lastLink = link; 13317 memberType = memberType->next; 13318 } 13319 return (0); 13320 } 13321 13332 static int 13333 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13334 { 13335 if (type == NULL) 13336 return (0); 13337 if (WXS_IS_COMPLEX(type)) 13338 return (0); 13339 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13340 if (type->builtInType == valType) 13341 return(1); 13342 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13343 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13344 return (0); 13345 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13346 } 13347 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13348 } 13349 13350 #if 0 13351 13361 static int 13362 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13363 { 13364 if (type == NULL) 13365 return (0); 13366 if (WXS_IS_COMPLEX(type)) 13367 return (0); 13368 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13369 if (type->builtInType == valType) 13370 return(1); 13371 return (0); 13372 } else 13373 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13374 13375 return (0); 13376 } 13377 13378 static xmlSchemaTypePtr 13379 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13380 { 13381 if (type == NULL) 13382 return (NULL); 13383 if (WXS_IS_COMPLEX(type)) 13384 return (NULL); 13385 if (type->type == XML_SCHEMA_TYPE_BASIC) 13386 return(type); 13387 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13388 } 13389 #endif 13390 13398 static xmlSchemaTypePtr 13399 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13400 { 13401 13402 while (type != NULL) { 13403 /* 13404 * Note that anySimpleType is actually not a primitive type 13405 * but we need that here. 13406 */ 13407 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13408 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13409 return (type); 13410 type = type->baseType; 13411 } 13412 13413 return (NULL); 13414 } 13415 13416 #if 0 13417 13424 static xmlSchemaTypePtr 13425 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13426 { 13427 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13428 return (0); 13429 while (type != NULL) { 13430 if (type->type == XML_SCHEMA_TYPE_BASIC) 13431 return (type); 13432 type = type->baseType; 13433 } 13434 13435 return (NULL); 13436 } 13437 #endif 13438 13449 static int 13450 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13451 xmlSchemaWildcardPtr dest, 13452 xmlSchemaWildcardPtr source) 13453 { 13454 xmlSchemaWildcardNsPtr cur, tmp, last; 13455 13456 if ((source == NULL) || (dest == NULL)) 13457 return(-1); 13458 dest->any = source->any; 13459 cur = source->nsSet; 13460 last = NULL; 13461 while (cur != NULL) { 13462 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13463 if (tmp == NULL) 13464 return(-1); 13465 tmp->value = cur->value; 13466 if (last == NULL) 13467 dest->nsSet = tmp; 13468 else 13469 last->next = tmp; 13470 last = tmp; 13471 cur = cur->next; 13472 } 13473 if (dest->negNsSet != NULL) 13474 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13475 if (source->negNsSet != NULL) { 13476 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13477 if (dest->negNsSet == NULL) 13478 return(-1); 13479 dest->negNsSet->value = source->negNsSet->value; 13480 } else 13481 dest->negNsSet = NULL; 13482 return(0); 13483 } 13484 13496 static int 13497 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13498 xmlSchemaWildcardPtr completeWild, 13499 xmlSchemaWildcardPtr curWild) 13500 { 13501 xmlSchemaWildcardNsPtr cur, curB, tmp; 13502 13503 /* 13504 * 1 If O1 and O2 are the same value, then that value must be the 13505 * value. 13506 */ 13507 if ((completeWild->any == curWild->any) && 13508 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13509 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13510 13511 if ((completeWild->negNsSet == NULL) || 13512 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13513 13514 if (completeWild->nsSet != NULL) { 13515 int found = 0; 13516 13517 /* 13518 * Check equality of sets. 13519 */ 13520 cur = completeWild->nsSet; 13521 while (cur != NULL) { 13522 found = 0; 13523 curB = curWild->nsSet; 13524 while (curB != NULL) { 13525 if (cur->value == curB->value) { 13526 found = 1; 13527 break; 13528 } 13529 curB = curB->next; 13530 } 13531 if (!found) 13532 break; 13533 cur = cur->next; 13534 } 13535 if (found) 13536 return(0); 13537 } else 13538 return(0); 13539 } 13540 } 13541 /* 13542 * 2 If either O1 or O2 is any, then any must be the value 13543 */ 13544 if (completeWild->any != curWild->any) { 13545 if (completeWild->any == 0) { 13546 completeWild->any = 1; 13547 if (completeWild->nsSet != NULL) { 13548 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13549 completeWild->nsSet = NULL; 13550 } 13551 if (completeWild->negNsSet != NULL) { 13552 xmlFree(completeWild->negNsSet); 13553 completeWild->negNsSet = NULL; 13554 } 13555 } 13556 return (0); 13557 } 13558 /* 13559 * 3 If both O1 and O2 are sets of (namespace names or �absent�), 13560 * then the union of those sets must be the value. 13561 */ 13562 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13563 int found; 13564 xmlSchemaWildcardNsPtr start; 13565 13566 cur = curWild->nsSet; 13567 start = completeWild->nsSet; 13568 while (cur != NULL) { 13569 found = 0; 13570 curB = start; 13571 while (curB != NULL) { 13572 if (cur->value == curB->value) { 13573 found = 1; 13574 break; 13575 } 13576 curB = curB->next; 13577 } 13578 if (!found) { 13579 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13580 if (tmp == NULL) 13581 return (-1); 13582 tmp->value = cur->value; 13583 tmp->next = completeWild->nsSet; 13584 completeWild->nsSet = tmp; 13585 } 13586 cur = cur->next; 13587 } 13588 13589 return(0); 13590 } 13591 /* 13592 * 4 If the two are negations of different values (namespace names 13593 * or �absent�), then a pair of not and �absent� must be the value. 13594 */ 13595 if ((completeWild->negNsSet != NULL) && 13596 (curWild->negNsSet != NULL) && 13597 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13598 completeWild->negNsSet->value = NULL; 13599 13600 return(0); 13601 } 13602 /* 13603 * 5. 13604 */ 13605 if (((completeWild->negNsSet != NULL) && 13606 (completeWild->negNsSet->value != NULL) && 13607 (curWild->nsSet != NULL)) || 13608 ((curWild->negNsSet != NULL) && 13609 (curWild->negNsSet->value != NULL) && 13610 (completeWild->nsSet != NULL))) { 13611 13612 int nsFound, absentFound = 0; 13613 13614 if (completeWild->nsSet != NULL) { 13615 cur = completeWild->nsSet; 13616 curB = curWild->negNsSet; 13617 } else { 13618 cur = curWild->nsSet; 13619 curB = completeWild->negNsSet; 13620 } 13621 nsFound = 0; 13622 while (cur != NULL) { 13623 if (cur->value == NULL) 13624 absentFound = 1; 13625 else if (cur->value == curB->value) 13626 nsFound = 1; 13627 if (nsFound && absentFound) 13628 break; 13629 cur = cur->next; 13630 } 13631 13632 if (nsFound && absentFound) { 13633 /* 13634 * 5.1 If the set S includes both the negated namespace 13635 * name and �absent�, then any must be the value. 13636 */ 13637 completeWild->any = 1; 13638 if (completeWild->nsSet != NULL) { 13639 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13640 completeWild->nsSet = NULL; 13641 } 13642 if (completeWild->negNsSet != NULL) { 13643 xmlFree(completeWild->negNsSet); 13644 completeWild->negNsSet = NULL; 13645 } 13646 } else if (nsFound && (!absentFound)) { 13647 /* 13648 * 5.2 If the set S includes the negated namespace name 13649 * but not �absent�, then a pair of not and �absent� must 13650 * be the value. 13651 */ 13652 if (completeWild->nsSet != NULL) { 13653 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13654 completeWild->nsSet = NULL; 13655 } 13656 if (completeWild->negNsSet == NULL) { 13657 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13658 if (completeWild->negNsSet == NULL) 13659 return (-1); 13660 } 13661 completeWild->negNsSet->value = NULL; 13662 } else if ((!nsFound) && absentFound) { 13663 /* 13664 * 5.3 If the set S includes �absent� but not the negated 13665 * namespace name, then the union is not expressible. 13666 */ 13667 xmlSchemaPErr(ctxt, completeWild->node, 13668 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13669 "The union of the wilcard is not expressible.\n", 13670 NULL, NULL); 13671 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13672 } else if ((!nsFound) && (!absentFound)) { 13673 /* 13674 * 5.4 If the set S does not include either the negated namespace 13675 * name or �absent�, then whichever of O1 or O2 is a pair of not 13676 * and a namespace name must be the value. 13677 */ 13678 if (completeWild->negNsSet == NULL) { 13679 if (completeWild->nsSet != NULL) { 13680 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13681 completeWild->nsSet = NULL; 13682 } 13683 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13684 if (completeWild->negNsSet == NULL) 13685 return (-1); 13686 completeWild->negNsSet->value = curWild->negNsSet->value; 13687 } 13688 } 13689 return (0); 13690 } 13691 /* 13692 * 6. 13693 */ 13694 if (((completeWild->negNsSet != NULL) && 13695 (completeWild->negNsSet->value == NULL) && 13696 (curWild->nsSet != NULL)) || 13697 ((curWild->negNsSet != NULL) && 13698 (curWild->negNsSet->value == NULL) && 13699 (completeWild->nsSet != NULL))) { 13700 13701 if (completeWild->nsSet != NULL) { 13702 cur = completeWild->nsSet; 13703 } else { 13704 cur = curWild->nsSet; 13705 } 13706 while (cur != NULL) { 13707 if (cur->value == NULL) { 13708 /* 13709 * 6.1 If the set S includes �absent�, then any must be the 13710 * value. 13711 */ 13712 completeWild->any = 1; 13713 if (completeWild->nsSet != NULL) { 13714 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13715 completeWild->nsSet = NULL; 13716 } 13717 if (completeWild->negNsSet != NULL) { 13718 xmlFree(completeWild->negNsSet); 13719 completeWild->negNsSet = NULL; 13720 } 13721 return (0); 13722 } 13723 cur = cur->next; 13724 } 13725 if (completeWild->negNsSet == NULL) { 13726 /* 13727 * 6.2 If the set S does not include �absent�, then a pair of not 13728 * and �absent� must be the value. 13729 */ 13730 if (completeWild->nsSet != NULL) { 13731 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13732 completeWild->nsSet = NULL; 13733 } 13734 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13735 if (completeWild->negNsSet == NULL) 13736 return (-1); 13737 completeWild->negNsSet->value = NULL; 13738 } 13739 return (0); 13740 } 13741 return (0); 13742 13743 } 13744 13756 static int 13757 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13758 xmlSchemaWildcardPtr completeWild, 13759 xmlSchemaWildcardPtr curWild) 13760 { 13761 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13762 13763 /* 13764 * 1 If O1 and O2 are the same value, then that value must be the 13765 * value. 13766 */ 13767 if ((completeWild->any == curWild->any) && 13768 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13769 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13770 13771 if ((completeWild->negNsSet == NULL) || 13772 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13773 13774 if (completeWild->nsSet != NULL) { 13775 int found = 0; 13776 13777 /* 13778 * Check equality of sets. 13779 */ 13780 cur = completeWild->nsSet; 13781 while (cur != NULL) { 13782 found = 0; 13783 curB = curWild->nsSet; 13784 while (curB != NULL) { 13785 if (cur->value == curB->value) { 13786 found = 1; 13787 break; 13788 } 13789 curB = curB->next; 13790 } 13791 if (!found) 13792 break; 13793 cur = cur->next; 13794 } 13795 if (found) 13796 return(0); 13797 } else 13798 return(0); 13799 } 13800 } 13801 /* 13802 * 2 If either O1 or O2 is any, then the other must be the value. 13803 */ 13804 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13805 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13806 return(-1); 13807 return(0); 13808 } 13809 /* 13810 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13811 * name or �absent�) and the other is a set of (namespace names or 13812 * �absent�), then that set, minus the negated value if it was in 13813 * the set, minus �absent� if it was in the set, must be the value. 13814 */ 13815 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13816 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13817 const xmlChar *neg; 13818 13819 if (completeWild->nsSet == NULL) { 13820 neg = completeWild->negNsSet->value; 13821 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13822 return(-1); 13823 } else 13824 neg = curWild->negNsSet->value; 13825 /* 13826 * Remove absent and negated. 13827 */ 13828 prev = NULL; 13829 cur = completeWild->nsSet; 13830 while (cur != NULL) { 13831 if (cur->value == NULL) { 13832 if (prev == NULL) 13833 completeWild->nsSet = cur->next; 13834 else 13835 prev->next = cur->next; 13836 xmlFree(cur); 13837 break; 13838 } 13839 prev = cur; 13840 cur = cur->next; 13841 } 13842 if (neg != NULL) { 13843 prev = NULL; 13844 cur = completeWild->nsSet; 13845 while (cur != NULL) { 13846 if (cur->value == neg) { 13847 if (prev == NULL) 13848 completeWild->nsSet = cur->next; 13849 else 13850 prev->next = cur->next; 13851 xmlFree(cur); 13852 break; 13853 } 13854 prev = cur; 13855 cur = cur->next; 13856 } 13857 } 13858 13859 return(0); 13860 } 13861 /* 13862 * 4 If both O1 and O2 are sets of (namespace names or �absent�), 13863 * then the intersection of those sets must be the value. 13864 */ 13865 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13866 int found; 13867 13868 cur = completeWild->nsSet; 13869 prev = NULL; 13870 while (cur != NULL) { 13871 found = 0; 13872 curB = curWild->nsSet; 13873 while (curB != NULL) { 13874 if (cur->value == curB->value) { 13875 found = 1; 13876 break; 13877 } 13878 curB = curB->next; 13879 } 13880 if (!found) { 13881 if (prev == NULL) 13882 completeWild->nsSet = cur->next; 13883 else 13884 prev->next = cur->next; 13885 tmp = cur->next; 13886 xmlFree(cur); 13887 cur = tmp; 13888 continue; 13889 } 13890 prev = cur; 13891 cur = cur->next; 13892 } 13893 13894 return(0); 13895 } 13896 /* 5 If the two are negations of different namespace names, 13897 * then the intersection is not expressible 13898 */ 13899 if ((completeWild->negNsSet != NULL) && 13900 (curWild->negNsSet != NULL) && 13901 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13902 (completeWild->negNsSet->value != NULL) && 13903 (curWild->negNsSet->value != NULL)) { 13904 13905 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13906 "The intersection of the wilcard is not expressible.\n", 13907 NULL, NULL); 13908 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13909 } 13910 /* 13911 * 6 If the one is a negation of a namespace name and the other 13912 * is a negation of �absent�, then the one which is the negation 13913 * of a namespace name must be the value. 13914 */ 13915 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13916 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13917 (completeWild->negNsSet->value == NULL)) { 13918 completeWild->negNsSet->value = curWild->negNsSet->value; 13919 } 13920 return(0); 13921 } 13922 13934 static int 13935 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13936 xmlSchemaWildcardPtr super) 13937 { 13938 /* 13939 * 1 super must be any. 13940 */ 13941 if (super->any) 13942 return (0); 13943 /* 13944 * 2.1 sub must be a pair of not and a namespace name or �absent�. 13945 * 2.2 super must be a pair of not and the same value. 13946 */ 13947 if ((sub->negNsSet != NULL) && 13948 (super->negNsSet != NULL) && 13949 (sub->negNsSet->value == sub->negNsSet->value)) 13950 return (0); 13951 /* 13952 * 3.1 sub must be a set whose members are either namespace names or �absent�. 13953 */ 13954 if (sub->nsSet != NULL) { 13955 /* 13956 * 3.2.1 super must be the same set or a superset thereof. 13957 */ 13958 if (super->nsSet != NULL) { 13959 xmlSchemaWildcardNsPtr cur, curB; 13960 int found = 0; 13961 13962 cur = sub->nsSet; 13963 while (cur != NULL) { 13964 found = 0; 13965 curB = super->nsSet; 13966 while (curB != NULL) { 13967 if (cur->value == curB->value) { 13968 found = 1; 13969 break; 13970 } 13971 curB = curB->next; 13972 } 13973 if (!found) 13974 return (1); 13975 cur = cur->next; 13976 } 13977 if (found) 13978 return (0); 13979 } else if (super->negNsSet != NULL) { 13980 xmlSchemaWildcardNsPtr cur; 13981 /* 13982 * 3.2.2 super must be a pair of not and a namespace name or 13983 * �absent� and that value must not be in sub's set. 13984 */ 13985 cur = sub->nsSet; 13986 while (cur != NULL) { 13987 if (cur->value == super->negNsSet->value) 13988 return (1); 13989 cur = cur->next; 13990 } 13991 return (0); 13992 } 13993 } 13994 return (1); 13995 } 13996 13997 static int 13998 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 13999 int *fixed, 14000 const xmlChar **value, 14001 xmlSchemaValPtr *val) 14002 { 14003 *fixed = 0; 14004 *value = NULL; 14005 if (val != 0) 14006 *val = NULL; 14007 14008 if (attruse->defValue != NULL) { 14009 *value = attruse->defValue; 14010 if (val != NULL) 14011 *val = attruse->defVal; 14012 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14013 *fixed = 1; 14014 return(1); 14015 } else if ((attruse->attrDecl != NULL) && 14016 (attruse->attrDecl->defValue != NULL)) { 14017 *value = attruse->attrDecl->defValue; 14018 if (val != NULL) 14019 *val = attruse->attrDecl->defVal; 14020 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14021 *fixed = 1; 14022 return(1); 14023 } 14024 return(0); 14025 } 14037 static int 14038 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14039 const xmlChar* ns) 14040 { 14041 if (wild == NULL) 14042 return(-1); 14043 14044 if (wild->any) 14045 return(0); 14046 else if (wild->nsSet != NULL) { 14047 xmlSchemaWildcardNsPtr cur; 14048 14049 cur = wild->nsSet; 14050 while (cur != NULL) { 14051 if (xmlStrEqual(cur->value, ns)) 14052 return(0); 14053 cur = cur->next; 14054 } 14055 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14056 (!xmlStrEqual(wild->negNsSet->value, ns))) 14057 return(0); 14058 14059 return(1); 14060 } 14061 14062 #define XML_SCHEMA_ACTION_DERIVE 0 14063 #define XML_SCHEMA_ACTION_REDEFINE 1 14064 14065 #define WXS_ACTION_STR(a) \ 14066 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14067 14068 /* 14069 * Schema Component Constraint: 14070 * Derivation Valid (Restriction, Complex) 14071 * derivation-ok-restriction (2) - (4) 14072 * 14073 * ATTENTION: 14074 * In XML Schema 1.1 this will be: 14075 * Validation Rule: 14076 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14077 * 14078 */ 14079 static int 14080 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14081 int action, 14082 xmlSchemaBasicItemPtr item, 14083 xmlSchemaBasicItemPtr baseItem, 14084 xmlSchemaItemListPtr uses, 14085 xmlSchemaItemListPtr baseUses, 14086 xmlSchemaWildcardPtr wild, 14087 xmlSchemaWildcardPtr baseWild) 14088 { 14089 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14090 int i, j, found; /* err = 0; */ 14091 const xmlChar *bEffValue; 14092 int effFixed; 14093 14094 if (uses != NULL) { 14095 for (i = 0; i < uses->nbItems; i++) { 14096 cur = uses->items[i]; 14097 found = 0; 14098 if (baseUses == NULL) 14099 goto not_found; 14100 for (j = 0; j < baseUses->nbItems; j++) { 14101 bcur = baseUses->items[j]; 14102 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14103 WXS_ATTRUSE_DECL_NAME(bcur)) && 14104 (WXS_ATTRUSE_DECL_TNS(cur) == 14105 WXS_ATTRUSE_DECL_TNS(bcur))) 14106 { 14107 /* 14108 * (2.1) "If there is an attribute use in the {attribute 14109 * uses} of the {base type definition} (call this B) whose 14110 * {attribute declaration} has the same {name} and {target 14111 * namespace}, then all of the following must be true:" 14112 */ 14113 found = 1; 14114 14115 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14116 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14117 { 14118 xmlChar *str = NULL; 14119 /* 14120 * (2.1.1) "one of the following must be true:" 14121 * (2.1.1.1) "B's {required} is false." 14122 * (2.1.1.2) "R's {required} is true." 14123 */ 14124 xmlSchemaPAttrUseErr4(pctxt, 14125 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14126 WXS_ITEM_NODE(item), item, cur, 14127 "The 'optional' attribute use is inconsistent " 14128 "with the corresponding 'required' attribute use of " 14129 "the %s %s", 14130 WXS_ACTION_STR(action), 14131 xmlSchemaGetComponentDesignation(&str, baseItem), 14132 NULL, NULL); 14133 FREE_AND_NULL(str); 14134 /* err = pctxt->err; */ 14135 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14136 WXS_ATTRUSE_TYPEDEF(cur), 14137 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14138 { 14139 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14140 14141 /* 14142 * SPEC (2.1.2) "R's {attribute declaration}'s 14143 * {type definition} must be validly derived from 14144 * B's {type definition} given the empty set as 14145 * defined in Type Derivation OK (Simple) (�3.14.6)." 14146 */ 14147 xmlSchemaPAttrUseErr4(pctxt, 14148 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14149 WXS_ITEM_NODE(item), item, cur, 14150 "The attribute declaration's %s " 14151 "is not validly derived from " 14152 "the corresponding %s of the " 14153 "attribute declaration in the %s %s", 14154 xmlSchemaGetComponentDesignation(&strA, 14155 WXS_ATTRUSE_TYPEDEF(cur)), 14156 xmlSchemaGetComponentDesignation(&strB, 14157 WXS_ATTRUSE_TYPEDEF(bcur)), 14158 WXS_ACTION_STR(action), 14159 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14160 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14161 FREE_AND_NULL(strA); 14162 FREE_AND_NULL(strB); 14163 FREE_AND_NULL(strC); 14164 /* err = pctxt->err; */ 14165 } else { 14166 /* 14167 * 2.1.3 [Definition:] Let the effective value 14168 * constraint of an attribute use be its {value 14169 * constraint}, if present, otherwise its {attribute 14170 * declaration}'s {value constraint} . 14171 */ 14172 xmlSchemaGetEffectiveValueConstraint(bcur, 14173 &effFixed, &bEffValue, NULL); 14174 /* 14175 * 2.1.3 ... one of the following must be true 14176 * 14177 * 2.1.3.1 B's �effective value constraint� is 14178 * �absent� or default. 14179 */ 14180 if ((bEffValue != NULL) && 14181 (effFixed == 1)) { 14182 const xmlChar *rEffValue = NULL; 14183 14184 xmlSchemaGetEffectiveValueConstraint(bcur, 14185 &effFixed, &rEffValue, NULL); 14186 /* 14187 * 2.1.3.2 R's �effective value constraint� is 14188 * fixed with the same string as B's. 14189 * MAYBE TODO: Compare the computed values. 14190 * Hmm, it says "same string" so 14191 * string-equality might really be sufficient. 14192 */ 14193 if ((effFixed == 0) || 14194 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14195 { 14196 xmlChar *str = NULL; 14197 14198 xmlSchemaPAttrUseErr4(pctxt, 14199 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14200 WXS_ITEM_NODE(item), item, cur, 14201 "The effective value constraint of the " 14202 "attribute use is inconsistent with " 14203 "its correspondent in the %s %s", 14204 WXS_ACTION_STR(action), 14205 xmlSchemaGetComponentDesignation(&str, 14206 baseItem), 14207 NULL, NULL); 14208 FREE_AND_NULL(str); 14209 /* err = pctxt->err; */ 14210 } 14211 } 14212 } 14213 break; 14214 } 14215 } 14216 not_found: 14217 if (!found) { 14218 /* 14219 * (2.2) "otherwise the {base type definition} must have an 14220 * {attribute wildcard} and the {target namespace} of the 14221 * R's {attribute declaration} must be �valid� with respect 14222 * to that wildcard, as defined in Wildcard allows Namespace 14223 * Name (�3.10.4)." 14224 */ 14225 if ((baseWild == NULL) || 14226 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14227 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14228 { 14229 xmlChar *str = NULL; 14230 14231 xmlSchemaPAttrUseErr4(pctxt, 14232 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14233 WXS_ITEM_NODE(item), item, cur, 14234 "Neither a matching attribute use, " 14235 "nor a matching wildcard exists in the %s %s", 14236 WXS_ACTION_STR(action), 14237 xmlSchemaGetComponentDesignation(&str, baseItem), 14238 NULL, NULL); 14239 FREE_AND_NULL(str); 14240 /* err = pctxt->err; */ 14241 } 14242 } 14243 } 14244 } 14245 /* 14246 * SPEC derivation-ok-restriction (3): 14247 * (3) "For each attribute use in the {attribute uses} of the {base type 14248 * definition} whose {required} is true, there must be an attribute 14249 * use with an {attribute declaration} with the same {name} and 14250 * {target namespace} as its {attribute declaration} in the {attribute 14251 * uses} of the complex type definition itself whose {required} is true. 14252 */ 14253 if (baseUses != NULL) { 14254 for (j = 0; j < baseUses->nbItems; j++) { 14255 bcur = baseUses->items[j]; 14256 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14257 continue; 14258 found = 0; 14259 if (uses != NULL) { 14260 for (i = 0; i < uses->nbItems; i++) { 14261 cur = uses->items[i]; 14262 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14263 WXS_ATTRUSE_DECL_NAME(bcur)) && 14264 (WXS_ATTRUSE_DECL_TNS(cur) == 14265 WXS_ATTRUSE_DECL_TNS(bcur))) { 14266 found = 1; 14267 break; 14268 } 14269 } 14270 } 14271 if (!found) { 14272 xmlChar *strA = NULL, *strB = NULL; 14273 14274 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14275 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14276 NULL, item, 14277 "A matching attribute use for the " 14278 "'required' %s of the %s %s is missing", 14279 xmlSchemaGetComponentDesignation(&strA, bcur), 14280 WXS_ACTION_STR(action), 14281 xmlSchemaGetComponentDesignation(&strB, baseItem), 14282 NULL); 14283 FREE_AND_NULL(strA); 14284 FREE_AND_NULL(strB); 14285 } 14286 } 14287 } 14288 /* 14289 * derivation-ok-restriction (4) 14290 */ 14291 if (wild != NULL) { 14292 /* 14293 * (4) "If there is an {attribute wildcard}, all of the 14294 * following must be true:" 14295 */ 14296 if (baseWild == NULL) { 14297 xmlChar *str = NULL; 14298 14299 /* 14300 * (4.1) "The {base type definition} must also have one." 14301 */ 14302 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14303 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14304 NULL, item, 14305 "The %s has an attribute wildcard, " 14306 "but the %s %s '%s' does not have one", 14307 WXS_ITEM_TYPE_NAME(item), 14308 WXS_ACTION_STR(action), 14309 WXS_ITEM_TYPE_NAME(baseItem), 14310 xmlSchemaGetComponentQName(&str, baseItem)); 14311 FREE_AND_NULL(str); 14312 return(pctxt->err); 14313 } else if ((baseWild->any == 0) && 14314 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14315 { 14316 xmlChar *str = NULL; 14317 /* 14318 * (4.2) "The complex type definition's {attribute wildcard}'s 14319 * {namespace constraint} must be a subset of the {base type 14320 * definition}'s {attribute wildcard}'s {namespace constraint}, 14321 * as defined by Wildcard Subset (�3.10.6)." 14322 */ 14323 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14324 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14325 NULL, item, 14326 "The attribute wildcard is not a valid " 14327 "subset of the wildcard in the %s %s '%s'", 14328 WXS_ACTION_STR(action), 14329 WXS_ITEM_TYPE_NAME(baseItem), 14330 xmlSchemaGetComponentQName(&str, baseItem), 14331 NULL); 14332 FREE_AND_NULL(str); 14333 return(pctxt->err); 14334 } 14335 /* 4.3 Unless the {base type definition} is the �ur-type 14336 * definition�, the complex type definition's {attribute 14337 * wildcard}'s {process contents} must be identical to or 14338 * stronger than the {base type definition}'s {attribute 14339 * wildcard}'s {process contents}, where strict is stronger 14340 * than lax is stronger than skip. 14341 */ 14342 if ((! WXS_IS_ANYTYPE(baseItem)) && 14343 (wild->processContents < baseWild->processContents)) { 14344 xmlChar *str = NULL; 14345 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14346 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14347 NULL, baseItem, 14348 "The {process contents} of the attribute wildcard is " 14349 "weaker than the one in the %s %s '%s'", 14350 WXS_ACTION_STR(action), 14351 WXS_ITEM_TYPE_NAME(baseItem), 14352 xmlSchemaGetComponentQName(&str, baseItem), 14353 NULL); 14354 FREE_AND_NULL(str) 14355 return(pctxt->err); 14356 } 14357 } 14358 return(0); 14359 } 14360 14361 14362 static int 14363 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14364 xmlSchemaBasicItemPtr item, 14365 xmlSchemaWildcardPtr *completeWild, 14366 xmlSchemaItemListPtr list, 14367 xmlSchemaItemListPtr prohibs); 14382 static int 14383 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14384 xmlSchemaTypePtr type) 14385 { 14386 xmlSchemaTypePtr baseType = NULL; 14387 xmlSchemaAttributeUsePtr use; 14388 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14389 14390 if (type->baseType == NULL) { 14391 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14392 "no base type"); 14393 return (-1); 14394 } 14395 baseType = type->baseType; 14396 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14397 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14398 return(-1); 14399 14400 uses = type->attrUses; 14401 baseUses = baseType->attrUses; 14402 /* 14403 * Expand attribute group references. And build the 'complete' 14404 * wildcard, i.e. intersect multiple wildcards. 14405 * Move attribute prohibitions into a separate list. 14406 */ 14407 if (uses != NULL) { 14408 if (WXS_IS_RESTRICTION(type)) { 14409 /* 14410 * This one will transfer all attr. prohibitions 14411 * into pctxt->attrProhibs. 14412 */ 14413 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14414 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14415 pctxt->attrProhibs) == -1) 14416 { 14417 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14418 "failed to expand attributes"); 14419 } 14420 if (pctxt->attrProhibs->nbItems != 0) 14421 prohibs = pctxt->attrProhibs; 14422 } else { 14423 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14424 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14425 NULL) == -1) 14426 { 14427 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14428 "failed to expand attributes"); 14429 } 14430 } 14431 } 14432 /* 14433 * Inherit the attribute uses of the base type. 14434 */ 14435 if (baseUses != NULL) { 14436 int i, j; 14437 xmlSchemaAttributeUseProhibPtr pro; 14438 14439 if (WXS_IS_RESTRICTION(type)) { 14440 int usesCount; 14441 xmlSchemaAttributeUsePtr tmp; 14442 14443 if (uses != NULL) 14444 usesCount = uses->nbItems; 14445 else 14446 usesCount = 0; 14447 14448 /* Restriction. */ 14449 for (i = 0; i < baseUses->nbItems; i++) { 14450 use = baseUses->items[i]; 14451 if (prohibs) { 14452 /* 14453 * Filter out prohibited uses. 14454 */ 14455 for (j = 0; j < prohibs->nbItems; j++) { 14456 pro = prohibs->items[j]; 14457 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14458 (WXS_ATTRUSE_DECL_TNS(use) == 14459 pro->targetNamespace)) 14460 { 14461 goto inherit_next; 14462 } 14463 } 14464 } 14465 if (usesCount) { 14466 /* 14467 * Filter out existing uses. 14468 */ 14469 for (j = 0; j < usesCount; j++) { 14470 tmp = uses->items[j]; 14471 if ((WXS_ATTRUSE_DECL_NAME(use) == 14472 WXS_ATTRUSE_DECL_NAME(tmp)) && 14473 (WXS_ATTRUSE_DECL_TNS(use) == 14474 WXS_ATTRUSE_DECL_TNS(tmp))) 14475 { 14476 goto inherit_next; 14477 } 14478 } 14479 } 14480 if (uses == NULL) { 14481 type->attrUses = xmlSchemaItemListCreate(); 14482 if (type->attrUses == NULL) 14483 goto exit_failure; 14484 uses = type->attrUses; 14485 } 14486 xmlSchemaItemListAddSize(uses, 2, use); 14487 inherit_next: {} 14488 } 14489 } else { 14490 /* Extension. */ 14491 for (i = 0; i < baseUses->nbItems; i++) { 14492 use = baseUses->items[i]; 14493 if (uses == NULL) { 14494 type->attrUses = xmlSchemaItemListCreate(); 14495 if (type->attrUses == NULL) 14496 goto exit_failure; 14497 uses = type->attrUses; 14498 } 14499 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14500 } 14501 } 14502 } 14503 /* 14504 * Shrink attr. uses. 14505 */ 14506 if (uses) { 14507 if (uses->nbItems == 0) { 14508 xmlSchemaItemListFree(uses); 14509 type->attrUses = NULL; 14510 } 14511 /* 14512 * TODO: We could shrink the size of the array 14513 * to fit the actual number of items. 14514 */ 14515 } 14516 /* 14517 * Compute the complete wildcard. 14518 */ 14519 if (WXS_IS_EXTENSION(type)) { 14520 if (baseType->attributeWildcard != NULL) { 14521 /* 14522 * (3.2.2.1) "If the �base wildcard� is non-�absent�, then 14523 * the appropriate case among the following:" 14524 */ 14525 if (type->attributeWildcard != NULL) { 14526 /* 14527 * Union the complete wildcard with the base wildcard. 14528 * SPEC {attribute wildcard} 14529 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14530 * and {annotation} are those of the �complete wildcard�, 14531 * and whose {namespace constraint} is the intensional union 14532 * of the {namespace constraint} of the �complete wildcard� 14533 * and of the �base wildcard�, as defined in Attribute 14534 * Wildcard Union (�3.10.6)." 14535 */ 14536 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14537 baseType->attributeWildcard) == -1) 14538 goto exit_failure; 14539 } else { 14540 /* 14541 * (3.2.2.1.1) "If the �complete wildcard� is �absent�, 14542 * then the �base wildcard�." 14543 */ 14544 type->attributeWildcard = baseType->attributeWildcard; 14545 } 14546 } else { 14547 /* 14548 * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the 14549 * �complete wildcard" 14550 * NOOP 14551 */ 14552 } 14553 } else { 14554 /* 14555 * SPEC {attribute wildcard} 14556 * (3.1) "If the <restriction> alternative is chosen, then the 14557 * �complete wildcard�;" 14558 * NOOP 14559 */ 14560 } 14561 14562 return (0); 14563 14564 exit_failure: 14565 return(-1); 14566 } 14567 14580 static int 14581 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14582 { 14583 if (type == NULL) 14584 return (0); 14585 if (type->flags & final) 14586 return (1); 14587 else 14588 return (0); 14589 } 14590 14598 static xmlSchemaTypeLinkPtr 14599 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14600 { 14601 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14602 if (type->memberTypes != NULL) 14603 return (type->memberTypes); 14604 else 14605 type = type->baseType; 14606 } 14607 return (NULL); 14608 } 14609 14619 static int 14620 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14621 { 14622 if ((particle->children == NULL) || 14623 (particle->minOccurs == 0)) 14624 return (0); 14625 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14626 int min = -1, cur; 14627 xmlSchemaParticlePtr part = 14628 (xmlSchemaParticlePtr) particle->children->children; 14629 14630 if (part == NULL) 14631 return (0); 14632 while (part != NULL) { 14633 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14634 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14635 cur = part->minOccurs; 14636 else 14637 cur = xmlSchemaGetParticleTotalRangeMin(part); 14638 if (cur == 0) 14639 return (0); 14640 if ((min > cur) || (min == -1)) 14641 min = cur; 14642 part = (xmlSchemaParticlePtr) part->next; 14643 } 14644 return (particle->minOccurs * min); 14645 } else { 14646 /* <all> and <sequence> */ 14647 int sum = 0; 14648 xmlSchemaParticlePtr part = 14649 (xmlSchemaParticlePtr) particle->children->children; 14650 14651 if (part == NULL) 14652 return (0); 14653 do { 14654 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14655 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14656 sum += part->minOccurs; 14657 else 14658 sum += xmlSchemaGetParticleTotalRangeMin(part); 14659 part = (xmlSchemaParticlePtr) part->next; 14660 } while (part != NULL); 14661 return (particle->minOccurs * sum); 14662 } 14663 } 14664 14665 #if 0 14666 14675 static int 14676 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14677 { 14678 if ((particle->children == NULL) || 14679 (particle->children->children == NULL)) 14680 return (0); 14681 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14682 int max = -1, cur; 14683 xmlSchemaParticlePtr part = 14684 (xmlSchemaParticlePtr) particle->children->children; 14685 14686 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14687 if (part->children == NULL) 14688 continue; 14689 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14690 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14691 cur = part->maxOccurs; 14692 else 14693 cur = xmlSchemaGetParticleTotalRangeMax(part); 14694 if (cur == UNBOUNDED) 14695 return (UNBOUNDED); 14696 if ((max < cur) || (max == -1)) 14697 max = cur; 14698 } 14699 /* TODO: Handle overflows? */ 14700 return (particle->maxOccurs * max); 14701 } else { 14702 /* <all> and <sequence> */ 14703 int sum = 0, cur; 14704 xmlSchemaParticlePtr part = 14705 (xmlSchemaParticlePtr) particle->children->children; 14706 14707 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14708 if (part->children == NULL) 14709 continue; 14710 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14711 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14712 cur = part->maxOccurs; 14713 else 14714 cur = xmlSchemaGetParticleTotalRangeMax(part); 14715 if (cur == UNBOUNDED) 14716 return (UNBOUNDED); 14717 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14718 return (UNBOUNDED); 14719 sum += cur; 14720 } 14721 /* TODO: Handle overflows? */ 14722 return (particle->maxOccurs * sum); 14723 } 14724 } 14725 #endif 14726 14736 static int 14737 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14738 { 14739 /* 14740 * SPEC (1) "Its {min occurs} is 0." 14741 */ 14742 if ((particle == NULL) || (particle->minOccurs == 0) || 14743 (particle->children == NULL)) 14744 return (1); 14745 /* 14746 * SPEC (2) "Its {term} is a group and the minimum part of the 14747 * effective total range of that group, [...] is 0." 14748 */ 14749 if (WXS_IS_MODEL_GROUP(particle->children)) { 14750 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14751 return (1); 14752 } 14753 return (0); 14754 } 14755 14771 static int 14772 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14773 xmlSchemaTypePtr type, 14774 xmlSchemaTypePtr baseType, 14775 int subset) 14776 { 14777 /* 14778 * 1 They are the same type definition. 14779 * TODO: The identy check might have to be more complex than this. 14780 */ 14781 if (type == baseType) 14782 return (0); 14783 /* 14784 * 2.1 restriction is not in the subset, or in the {final} 14785 * of its own {base type definition}; 14786 * 14787 * NOTE that this will be used also via "xsi:type". 14788 * 14789 * TODO: Revise this, it looks strange. How can the "type" 14790 * not be fixed or *in* fixing? 14791 */ 14792 if (WXS_IS_TYPE_NOT_FIXED(type)) 14793 if (xmlSchemaTypeFixup(type, actxt) == -1) 14794 return(-1); 14795 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14796 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14797 return(-1); 14798 if ((subset & SUBSET_RESTRICTION) || 14799 (xmlSchemaTypeFinalContains(type->baseType, 14800 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14801 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14802 } 14803 /* 2.2 */ 14804 if (type->baseType == baseType) { 14805 /* 14806 * 2.2.1 D's �base type definition� is B. 14807 */ 14808 return (0); 14809 } 14810 /* 14811 * 2.2.2 D's �base type definition� is not the �ur-type definition� 14812 * and is validly derived from B given the subset, as defined by this 14813 * constraint. 14814 */ 14815 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14816 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14817 baseType, subset) == 0)) { 14818 return (0); 14819 } 14820 /* 14821 * 2.2.3 D's {variety} is list or union and B is the �simple ur-type 14822 * definition�. 14823 */ 14824 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14825 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14826 return (0); 14827 } 14828 /* 14829 * 2.2.4 B's {variety} is union and D is validly derived from a type 14830 * definition in B's {member type definitions} given the subset, as 14831 * defined by this constraint. 14832 * 14833 * NOTE: This seems not to involve built-in types, since there is no 14834 * built-in Union Simple Type. 14835 */ 14836 if (WXS_IS_UNION(baseType)) { 14837 xmlSchemaTypeLinkPtr cur; 14838 14839 cur = baseType->memberTypes; 14840 while (cur != NULL) { 14841 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14842 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14843 return(-1); 14844 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14845 type, cur->type, subset) == 0) 14846 { 14847 /* 14848 * It just has to be validly derived from at least one 14849 * member-type. 14850 */ 14851 return (0); 14852 } 14853 cur = cur->next; 14854 } 14855 } 14856 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14857 } 14858 14871 static int 14872 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14873 xmlSchemaTypePtr ctxtType, 14874 xmlSchemaTypePtr ancestor) 14875 { 14876 int ret; 14877 14878 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14879 return (0); 14880 14881 if (ctxtType == ancestor) { 14882 xmlSchemaPCustomErr(pctxt, 14883 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14884 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14885 "The definition is circular", NULL); 14886 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14887 } 14888 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14889 /* 14890 * Avoid inifinite recursion on circular types not yet checked. 14891 */ 14892 return (0); 14893 } 14894 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14895 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14896 ancestor->baseType); 14897 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14898 return (ret); 14899 } 14900 14909 static void 14910 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14911 xmlSchemaParserCtxtPtr ctxt) 14912 { 14913 if ((item == NULL) || 14914 (item->type == XML_SCHEMA_TYPE_BASIC) || 14915 (item->baseType == NULL)) 14916 return; 14917 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14918 item->baseType); 14919 } 14920 14921 /* 14922 * Simple Type Definition Representation OK (src-simple-type) 4 14923 * 14924 * "4 Circular union type definition is disallowed. That is, if the 14925 * <union> alternative is chosen, there must not be any entries in the 14926 * memberTypes [attribute] at any depth which resolve to the component 14927 * corresponding to the <simpleType>." 14928 * 14929 * Note that this should work on the *representation* of a component, 14930 * thus assumes any union types in the member types not being yet 14931 * substituted. At this stage we need the variety of the types 14932 * to be already computed. 14933 */ 14934 static int 14935 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14936 xmlSchemaTypePtr ctxType, 14937 xmlSchemaTypeLinkPtr members) 14938 { 14939 xmlSchemaTypeLinkPtr member; 14940 xmlSchemaTypePtr memberType; 14941 14942 member = members; 14943 while (member != NULL) { 14944 memberType = member->type; 14945 while ((memberType != NULL) && 14946 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14947 if (memberType == ctxType) { 14948 xmlSchemaPCustomErr(pctxt, 14949 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14950 WXS_BASIC_CAST ctxType, NULL, 14951 "The union type definition is circular", NULL); 14952 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14953 } 14954 if ((WXS_IS_UNION(memberType)) && 14955 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14956 { 14957 int res; 14958 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 14959 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 14960 ctxType, 14961 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 14962 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 14963 if (res != 0) 14964 return(res); 14965 } 14966 memberType = memberType->baseType; 14967 } 14968 member = member->next; 14969 } 14970 return(0); 14971 } 14972 14973 static int 14974 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 14975 xmlSchemaTypePtr type) 14976 { 14977 if (! WXS_IS_UNION(type)) 14978 return(0); 14979 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 14980 type->memberTypes)); 14981 } 14982 14991 static void 14992 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 14993 xmlSchemaParserCtxtPtr ctxt) 14994 { 14995 if (typeDef == NULL) 14996 return; 14997 14998 /* 14999 * Resolve the base type. 15000 */ 15001 if (typeDef->baseType == NULL) { 15002 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15003 typeDef->base, typeDef->baseNs); 15004 if (typeDef->baseType == NULL) { 15005 xmlSchemaPResCompAttrErr(ctxt, 15006 XML_SCHEMAP_SRC_RESOLVE, 15007 WXS_BASIC_CAST typeDef, typeDef->node, 15008 "base", typeDef->base, typeDef->baseNs, 15009 XML_SCHEMA_TYPE_SIMPLE, NULL); 15010 return; 15011 } 15012 } 15013 if (WXS_IS_SIMPLE(typeDef)) { 15014 if (WXS_IS_UNION(typeDef)) { 15015 /* 15016 * Resolve the memberTypes. 15017 */ 15018 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15019 return; 15020 } else if (WXS_IS_LIST(typeDef)) { 15021 /* 15022 * Resolve the itemType. 15023 */ 15024 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15025 15026 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15027 typeDef->base, typeDef->baseNs); 15028 15029 if ((typeDef->subtypes == NULL) || 15030 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15031 { 15032 typeDef->subtypes = NULL; 15033 xmlSchemaPResCompAttrErr(ctxt, 15034 XML_SCHEMAP_SRC_RESOLVE, 15035 WXS_BASIC_CAST typeDef, typeDef->node, 15036 "itemType", typeDef->base, typeDef->baseNs, 15037 XML_SCHEMA_TYPE_SIMPLE, NULL); 15038 } 15039 } 15040 return; 15041 } 15042 } 15043 /* 15044 * The ball of letters below means, that if we have a particle 15045 * which has a QName-helper component as its {term}, we want 15046 * to resolve it... 15047 */ 15048 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15049 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15050 XML_SCHEMA_TYPE_PARTICLE) && 15051 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15052 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15053 XML_SCHEMA_EXTRA_QNAMEREF)) 15054 { 15055 xmlSchemaQNameRefPtr ref = 15056 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15057 xmlSchemaModelGroupDefPtr groupDef; 15058 15059 /* 15060 * URGENT TODO: Test this. 15061 */ 15062 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15063 /* 15064 * Resolve the MG definition reference. 15065 */ 15066 groupDef = 15067 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15068 ref->itemType, ref->name, ref->targetNamespace); 15069 if (groupDef == NULL) { 15070 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15071 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15072 "ref", ref->name, ref->targetNamespace, ref->itemType, 15073 NULL); 15074 /* Remove the particle. */ 15075 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15076 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15077 /* Remove the particle. */ 15078 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15079 else { 15080 /* 15081 * Assign the MG definition's {model group} to the 15082 * particle's {term}. 15083 */ 15084 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15085 15086 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15087 /* 15088 * SPEC cos-all-limited (1.2) 15089 * "1.2 the {term} property of a particle with 15090 * {max occurs}=1 which is part of a pair which constitutes 15091 * the {content type} of a complex type definition." 15092 */ 15093 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15094 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15095 /* TODO: error code */ 15096 XML_SCHEMAP_COS_ALL_LIMITED, 15097 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15098 "The particle's {max occurs} must be 1, since the " 15099 "reference resolves to an 'all' model group", 15100 NULL, NULL); 15101 } 15102 } 15103 } 15104 } 15105 } 15106 15107 15108 15120 static int 15121 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15122 xmlSchemaTypePtr type) 15123 { 15124 xmlSchemaTypePtr baseType = type->baseType; 15125 xmlChar *str = NULL; 15126 15127 /* STATE: error funcs converted. */ 15128 /* 15129 * Schema Component Constraint: Simple Type Definition Properties Correct 15130 * 15131 * NOTE: This is somehow redundant, since we actually built a simple type 15132 * to have all the needed information; this acts as an self test. 15133 */ 15134 /* Base type: If the datatype has been �derived� by �restriction� 15135 * then the Simple Type Definition component from which it is �derived�, 15136 * otherwise the Simple Type Definition for anySimpleType (�4.1.6). 15137 */ 15138 if (baseType == NULL) { 15139 /* 15140 * TODO: Think about: "modulo the impact of Missing 15141 * Sub-components (�5.3)." 15142 */ 15143 xmlSchemaPCustomErr(ctxt, 15144 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15145 WXS_BASIC_CAST type, NULL, 15146 "No base type existent", NULL); 15147 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15148 15149 } 15150 if (! WXS_IS_SIMPLE(baseType)) { 15151 xmlSchemaPCustomErr(ctxt, 15152 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15153 WXS_BASIC_CAST type, NULL, 15154 "The base type '%s' is not a simple type", 15155 xmlSchemaGetComponentQName(&str, baseType)); 15156 FREE_AND_NULL(str) 15157 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15158 } 15159 if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15160 (WXS_IS_RESTRICTION(type) == 0) && 15161 (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) { 15162 xmlSchemaPCustomErr(ctxt, 15163 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15164 WXS_BASIC_CAST type, NULL, 15165 "A type, derived by list or union, must have " 15166 "the simple ur-type definition as base type, not '%s'", 15167 xmlSchemaGetComponentQName(&str, baseType)); 15168 FREE_AND_NULL(str) 15169 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15170 } 15171 /* 15172 * Variety: One of {atomic, list, union}. 15173 */ 15174 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15175 (! WXS_IS_LIST(type))) { 15176 xmlSchemaPCustomErr(ctxt, 15177 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15178 WXS_BASIC_CAST type, NULL, 15179 "The variety is absent", NULL); 15180 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15181 } 15182 /* TODO: Finish this. Hmm, is this finished? */ 15183 15184 /* 15185 * 3 The {final} of the {base type definition} must not contain restriction. 15186 */ 15187 if (xmlSchemaTypeFinalContains(baseType, 15188 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15189 xmlSchemaPCustomErr(ctxt, 15190 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15191 WXS_BASIC_CAST type, NULL, 15192 "The 'final' of its base type '%s' must not contain " 15193 "'restriction'", 15194 xmlSchemaGetComponentQName(&str, baseType)); 15195 FREE_AND_NULL(str) 15196 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15197 } 15198 15199 /* 15200 * 2 All simple type definitions must be derived ultimately from the �simple 15201 * ur-type definition (so� circular definitions are disallowed). That is, it 15202 * must be possible to reach a built-in primitive datatype or the �simple 15203 * ur-type definition� by repeatedly following the {base type definition}. 15204 * 15205 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15206 */ 15207 return (0); 15208 } 15209 15224 static int 15225 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15226 xmlSchemaTypePtr type) 15227 { 15228 xmlChar *str = NULL; 15229 15230 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15231 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15232 "given type is not a user-derived simpleType"); 15233 return (-1); 15234 } 15235 15236 if (WXS_IS_ATOMIC(type)) { 15237 xmlSchemaTypePtr primitive; 15238 /* 15239 * 1.1 The {base type definition} must be an atomic simple 15240 * type definition or a built-in primitive datatype. 15241 */ 15242 if (! WXS_IS_ATOMIC(type->baseType)) { 15243 xmlSchemaPCustomErr(pctxt, 15244 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15245 WXS_BASIC_CAST type, NULL, 15246 "The base type '%s' is not an atomic simple type", 15247 xmlSchemaGetComponentQName(&str, type->baseType)); 15248 FREE_AND_NULL(str) 15249 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15250 } 15251 /* 1.2 The {final} of the {base type definition} must not contain 15252 * restriction. 15253 */ 15254 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15255 if (xmlSchemaTypeFinalContains(type->baseType, 15256 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15257 xmlSchemaPCustomErr(pctxt, 15258 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15259 WXS_BASIC_CAST type, NULL, 15260 "The final of its base type '%s' must not contain 'restriction'", 15261 xmlSchemaGetComponentQName(&str, type->baseType)); 15262 FREE_AND_NULL(str) 15263 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15264 } 15265 15266 /* 15267 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15268 * type definition}, as specified in the appropriate subsection of 3.2 15269 * Primitive datatypes. 15270 */ 15271 if (type->facets != NULL) { 15272 xmlSchemaFacetPtr facet; 15273 int ok = 1; 15274 15275 primitive = xmlSchemaGetPrimitiveType(type); 15276 if (primitive == NULL) { 15277 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15278 "failed to get primitive type"); 15279 return (-1); 15280 } 15281 facet = type->facets; 15282 do { 15283 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15284 ok = 0; 15285 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15286 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15287 type, primitive, facet); 15288 } 15289 facet = facet->next; 15290 } while (facet != NULL); 15291 if (ok == 0) 15292 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15293 } 15294 /* 15295 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15296 * of the {base type definition} (call this BF),then the DF's {value} 15297 * must be a valid restriction of BF's {value} as defined in 15298 * [XML Schemas: Datatypes]." 15299 * 15300 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15301 * xmlSchemaDeriveAndValidateFacets() 15302 */ 15303 } else if (WXS_IS_LIST(type)) { 15304 xmlSchemaTypePtr itemType = NULL; 15305 15306 itemType = type->subtypes; 15307 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15308 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15309 "failed to evaluate the item type"); 15310 return (-1); 15311 } 15312 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15313 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15314 /* 15315 * 2.1 The {item type definition} must have a {variety} of atomic or 15316 * union (in which case all the {member type definitions} 15317 * must be atomic). 15318 */ 15319 if ((! WXS_IS_ATOMIC(itemType)) && 15320 (! WXS_IS_UNION(itemType))) { 15321 xmlSchemaPCustomErr(pctxt, 15322 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15323 WXS_BASIC_CAST type, NULL, 15324 "The item type '%s' does not have a variety of atomic or union", 15325 xmlSchemaGetComponentQName(&str, itemType)); 15326 FREE_AND_NULL(str) 15327 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15328 } else if (WXS_IS_UNION(itemType)) { 15329 xmlSchemaTypeLinkPtr member; 15330 15331 member = itemType->memberTypes; 15332 while (member != NULL) { 15333 if (! WXS_IS_ATOMIC(member->type)) { 15334 xmlSchemaPCustomErr(pctxt, 15335 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15336 WXS_BASIC_CAST type, NULL, 15337 "The item type is a union type, but the " 15338 "member type '%s' of this item type is not atomic", 15339 xmlSchemaGetComponentQName(&str, member->type)); 15340 FREE_AND_NULL(str) 15341 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15342 } 15343 member = member->next; 15344 } 15345 } 15346 15347 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15348 xmlSchemaFacetPtr facet; 15349 /* 15350 * This is the case if we have: <simpleType><list .. 15351 */ 15352 /* 15353 * 2.3.1 15354 * 2.3.1.1 The {final} of the {item type definition} must not 15355 * contain list. 15356 */ 15357 if (xmlSchemaTypeFinalContains(itemType, 15358 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15359 xmlSchemaPCustomErr(pctxt, 15360 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15361 WXS_BASIC_CAST type, NULL, 15362 "The final of its item type '%s' must not contain 'list'", 15363 xmlSchemaGetComponentQName(&str, itemType)); 15364 FREE_AND_NULL(str) 15365 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15366 } 15367 /* 15368 * 2.3.1.2 The {facets} must only contain the whiteSpace 15369 * facet component. 15370 * OPTIMIZE TODO: the S4S already disallows any facet 15371 * to be specified. 15372 */ 15373 if (type->facets != NULL) { 15374 facet = type->facets; 15375 do { 15376 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15377 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15378 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15379 type, facet); 15380 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15381 } 15382 facet = facet->next; 15383 } while (facet != NULL); 15384 } 15385 /* 15386 * MAYBE TODO: (Hmm, not really) Datatypes states: 15387 * A �list� datatype can be �derived� from an �atomic� datatype 15388 * whose �lexical space� allows space (such as string or anyURI)or 15389 * a �union� datatype any of whose {member type definitions}'s 15390 * �lexical space� allows space. 15391 */ 15392 } else { 15393 /* 15394 * This is the case if we have: <simpleType><restriction ... 15395 * I.e. the variety of "list" is inherited. 15396 */ 15397 /* 15398 * 2.3.2 15399 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15400 */ 15401 if (! WXS_IS_LIST(type->baseType)) { 15402 xmlSchemaPCustomErr(pctxt, 15403 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15404 WXS_BASIC_CAST type, NULL, 15405 "The base type '%s' must be a list type", 15406 xmlSchemaGetComponentQName(&str, type->baseType)); 15407 FREE_AND_NULL(str) 15408 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15409 } 15410 /* 15411 * 2.3.2.2 The {final} of the {base type definition} must not 15412 * contain restriction. 15413 */ 15414 if (xmlSchemaTypeFinalContains(type->baseType, 15415 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15416 xmlSchemaPCustomErr(pctxt, 15417 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15418 WXS_BASIC_CAST type, NULL, 15419 "The 'final' of the base type '%s' must not contain 'restriction'", 15420 xmlSchemaGetComponentQName(&str, type->baseType)); 15421 FREE_AND_NULL(str) 15422 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15423 } 15424 /* 15425 * 2.3.2.3 The {item type definition} must be validly derived 15426 * from the {base type definition}'s {item type definition} given 15427 * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6). 15428 */ 15429 { 15430 xmlSchemaTypePtr baseItemType; 15431 15432 baseItemType = type->baseType->subtypes; 15433 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15434 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15435 "failed to eval the item type of a base type"); 15436 return (-1); 15437 } 15438 if ((itemType != baseItemType) && 15439 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15440 baseItemType, 0) != 0)) { 15441 xmlChar *strBIT = NULL, *strBT = NULL; 15442 xmlSchemaPCustomErrExt(pctxt, 15443 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15444 WXS_BASIC_CAST type, NULL, 15445 "The item type '%s' is not validly derived from " 15446 "the item type '%s' of the base type '%s'", 15447 xmlSchemaGetComponentQName(&str, itemType), 15448 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15449 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15450 15451 FREE_AND_NULL(str) 15452 FREE_AND_NULL(strBIT) 15453 FREE_AND_NULL(strBT) 15454 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15455 } 15456 } 15457 15458 if (type->facets != NULL) { 15459 xmlSchemaFacetPtr facet; 15460 int ok = 1; 15461 /* 15462 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15463 * and enumeration facet components are allowed among the {facets}. 15464 */ 15465 facet = type->facets; 15466 do { 15467 switch (facet->type) { 15468 case XML_SCHEMA_FACET_LENGTH: 15469 case XML_SCHEMA_FACET_MINLENGTH: 15470 case XML_SCHEMA_FACET_MAXLENGTH: 15471 case XML_SCHEMA_FACET_WHITESPACE: 15472 /* 15473 * TODO: 2.5.1.2 List datatypes 15474 * The value of �whiteSpace� is fixed to the value collapse. 15475 */ 15476 case XML_SCHEMA_FACET_PATTERN: 15477 case XML_SCHEMA_FACET_ENUMERATION: 15478 break; 15479 default: { 15480 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15481 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15482 type, facet); 15483 /* 15484 * We could return, but it's nicer to report all 15485 * invalid facets. 15486 */ 15487 ok = 0; 15488 } 15489 } 15490 facet = facet->next; 15491 } while (facet != NULL); 15492 if (ok == 0) 15493 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15494 /* 15495 * SPEC (2.3.2.5) (same as 1.3.2) 15496 * 15497 * NOTE (2.3.2.5) This is currently done in 15498 * xmlSchemaDeriveAndValidateFacets() 15499 */ 15500 } 15501 } 15502 } else if (WXS_IS_UNION(type)) { 15503 /* 15504 * 3.1 The {member type definitions} must all have {variety} of 15505 * atomic or list. 15506 */ 15507 xmlSchemaTypeLinkPtr member; 15508 15509 member = type->memberTypes; 15510 while (member != NULL) { 15511 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15512 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15513 15514 if ((! WXS_IS_ATOMIC(member->type)) && 15515 (! WXS_IS_LIST(member->type))) { 15516 xmlSchemaPCustomErr(pctxt, 15517 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15518 WXS_BASIC_CAST type, NULL, 15519 "The member type '%s' is neither an atomic, nor a list type", 15520 xmlSchemaGetComponentQName(&str, member->type)); 15521 FREE_AND_NULL(str) 15522 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15523 } 15524 member = member->next; 15525 } 15526 /* 15527 * 3.3.1 If the {base type definition} is the �simple ur-type 15528 * definition� 15529 */ 15530 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15531 /* 15532 * 3.3.1.1 All of the {member type definitions} must have a 15533 * {final} which does not contain union. 15534 */ 15535 member = type->memberTypes; 15536 while (member != NULL) { 15537 if (xmlSchemaTypeFinalContains(member->type, 15538 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15539 xmlSchemaPCustomErr(pctxt, 15540 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15541 WXS_BASIC_CAST type, NULL, 15542 "The 'final' of member type '%s' contains 'union'", 15543 xmlSchemaGetComponentQName(&str, member->type)); 15544 FREE_AND_NULL(str) 15545 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15546 } 15547 member = member->next; 15548 } 15549 /* 15550 * 3.3.1.2 The {facets} must be empty. 15551 */ 15552 if (type->facetSet != NULL) { 15553 xmlSchemaPCustomErr(pctxt, 15554 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15555 WXS_BASIC_CAST type, NULL, 15556 "No facets allowed", NULL); 15557 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15558 } 15559 } else { 15560 /* 15561 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15562 * I.e. the variety of "list" is inherited. 15563 */ 15564 if (! WXS_IS_UNION(type->baseType)) { 15565 xmlSchemaPCustomErr(pctxt, 15566 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15567 WXS_BASIC_CAST type, NULL, 15568 "The base type '%s' is not a union type", 15569 xmlSchemaGetComponentQName(&str, type->baseType)); 15570 FREE_AND_NULL(str) 15571 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15572 } 15573 /* 15574 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15575 */ 15576 if (xmlSchemaTypeFinalContains(type->baseType, 15577 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15578 xmlSchemaPCustomErr(pctxt, 15579 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15580 WXS_BASIC_CAST type, NULL, 15581 "The 'final' of its base type '%s' must not contain 'restriction'", 15582 xmlSchemaGetComponentQName(&str, type->baseType)); 15583 FREE_AND_NULL(str) 15584 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15585 } 15586 /* 15587 * 3.3.2.3 The {member type definitions}, in order, must be validly 15588 * derived from the corresponding type definitions in the {base 15589 * type definition}'s {member type definitions} given the empty set, 15590 * as defined in Type Derivation OK (Simple) (�3.14.6). 15591 */ 15592 { 15593 xmlSchemaTypeLinkPtr baseMember; 15594 15595 /* 15596 * OPTIMIZE: if the type is restricting, it has no local defined 15597 * member types and inherits the member types of the base type; 15598 * thus a check for equality can be skipped. 15599 */ 15600 /* 15601 * Even worse: I cannot see a scenario where a restricting 15602 * union simple type can have other member types as the member 15603 * types of it's base type. This check seems not necessary with 15604 * respect to the derivation process in libxml2. 15605 * But necessary if constructing types with an API. 15606 */ 15607 if (type->memberTypes != NULL) { 15608 member = type->memberTypes; 15609 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15610 if ((member == NULL) && (baseMember != NULL)) { 15611 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15612 "different number of member types in base"); 15613 } 15614 while (member != NULL) { 15615 if (baseMember == NULL) { 15616 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15617 "different number of member types in base"); 15618 } else if ((member->type != baseMember->type) && 15619 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15620 member->type, baseMember->type, 0) != 0)) { 15621 xmlChar *strBMT = NULL, *strBT = NULL; 15622 15623 xmlSchemaPCustomErrExt(pctxt, 15624 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15625 WXS_BASIC_CAST type, NULL, 15626 "The member type %s is not validly " 15627 "derived from its corresponding member " 15628 "type %s of the base type %s", 15629 xmlSchemaGetComponentQName(&str, member->type), 15630 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15631 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15632 FREE_AND_NULL(str) 15633 FREE_AND_NULL(strBMT) 15634 FREE_AND_NULL(strBT) 15635 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15636 } 15637 member = member->next; 15638 if (baseMember != NULL) 15639 baseMember = baseMember->next; 15640 } 15641 } 15642 } 15643 /* 15644 * 3.3.2.4 Only pattern and enumeration facet components are 15645 * allowed among the {facets}. 15646 */ 15647 if (type->facets != NULL) { 15648 xmlSchemaFacetPtr facet; 15649 int ok = 1; 15650 15651 facet = type->facets; 15652 do { 15653 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15654 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15655 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15656 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15657 type, facet); 15658 ok = 0; 15659 } 15660 facet = facet->next; 15661 } while (facet != NULL); 15662 if (ok == 0) 15663 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15664 15665 } 15666 /* 15667 * SPEC (3.3.2.5) (same as 1.3.2) 15668 * 15669 * NOTE (3.3.2.5) This is currently done in 15670 * xmlSchemaDeriveAndValidateFacets() 15671 */ 15672 } 15673 } 15674 15675 return (0); 15676 } 15677 15689 #if 0 15690 static int 15691 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15692 xmlSchemaTypePtr type) 15693 { 15694 /* 15695 * src-simple-type.1 The corresponding simple type definition, if any, 15696 * must satisfy the conditions set out in Constraints on Simple Type 15697 * Definition Schema Components (�3.14.6). 15698 */ 15699 if (WXS_IS_RESTRICTION(type)) { 15700 /* 15701 * src-simple-type.2 "If the <restriction> alternative is chosen, 15702 * either it must have a base [attribute] or a <simpleType> among its 15703 * [children], but not both." 15704 * NOTE: This is checked in the parse function of <restriction>. 15705 */ 15706 /* 15707 * 15708 */ 15709 } else if (WXS_IS_LIST(type)) { 15710 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15711 * an itemType [attribute] or a <simpleType> among its [children], 15712 * but not both." 15713 * 15714 * NOTE: This is checked in the parse function of <list>. 15715 */ 15716 } else if (WXS_IS_UNION(type)) { 15717 /* 15718 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15719 */ 15720 } 15721 return (0); 15722 } 15723 #endif 15724 15725 static int 15726 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15727 { 15728 if (ctxt->vctxt == NULL) { 15729 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15730 if (ctxt->vctxt == NULL) { 15731 xmlSchemaPErr(ctxt, NULL, 15732 XML_SCHEMAP_INTERNAL, 15733 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15734 "failed to create a temp. validation context.\n", 15735 NULL, NULL); 15736 return (-1); 15737 } 15738 /* TODO: Pass user data. */ 15739 xmlSchemaSetValidErrors(ctxt->vctxt, 15740 ctxt->error, ctxt->warning, ctxt->errCtxt); 15741 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15742 ctxt->serror, ctxt->errCtxt); 15743 } 15744 return (0); 15745 } 15746 15747 static int 15748 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15749 xmlNodePtr node, 15750 xmlSchemaTypePtr type, 15751 const xmlChar *value, 15752 xmlSchemaValPtr *retVal, 15753 int fireErrors, 15754 int normalize, 15755 int isNormalized); 15756 15773 static int 15774 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15775 xmlNodePtr node, 15776 xmlSchemaTypePtr type, 15777 const xmlChar *value, 15778 xmlSchemaValPtr *val) 15779 { 15780 int ret = 0; 15781 15782 /* 15783 * cos-valid-default: 15784 * Schema Component Constraint: Element Default Valid (Immediate) 15785 * For a string to be a valid default with respect to a type 15786 * definition the appropriate case among the following must be true: 15787 */ 15788 if WXS_IS_COMPLEX(type) { 15789 /* 15790 * Complex type. 15791 * 15792 * SPEC (2.1) "its {content type} must be a simple type definition 15793 * or mixed." 15794 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15795 * type}'s particle must be �emptiable� as defined by 15796 * Particle Emptiable (�3.9.6)." 15797 */ 15798 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15799 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15800 /* NOTE that this covers (2.2.2) as well. */ 15801 xmlSchemaPCustomErr(pctxt, 15802 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15803 WXS_BASIC_CAST type, type->node, 15804 "For a string to be a valid default, the type definition " 15805 "must be a simple type or a complex type with mixed content " 15806 "and a particle emptiable", NULL); 15807 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15808 } 15809 } 15810 /* 15811 * 1 If the type definition is a simple type definition, then the string 15812 * must be �valid� with respect to that definition as defined by String 15813 * Valid (�3.14.4). 15814 * 15815 * AND 15816 * 15817 * 2.2.1 If the {content type} is a simple type definition, then the 15818 * string must be �valid� with respect to that simple type definition 15819 * as defined by String Valid (�3.14.4). 15820 */ 15821 if (WXS_IS_SIMPLE(type)) 15822 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15823 type, value, val, 1, 1, 0); 15824 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15825 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15826 type->contentTypeDef, value, val, 1, 1, 0); 15827 else 15828 return (ret); 15829 15830 if (ret < 0) { 15831 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15832 "calling xmlSchemaVCheckCVCSimpleType()"); 15833 } 15834 15835 return (ret); 15836 } 15837 15851 static int 15852 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15853 xmlSchemaTypePtr type) 15854 { 15855 /* 15856 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15857 * 15858 * SPEC (1) "The values of the properties of a complex type definition must 15859 * be as described in the property tableau in The Complex Type Definition 15860 * Schema Component (�3.4.1), modulo the impact of Missing 15861 * Sub-components (�5.3)." 15862 */ 15863 if ((type->baseType != NULL) && 15864 (WXS_IS_SIMPLE(type->baseType)) && 15865 (WXS_IS_EXTENSION(type) == 0)) { 15866 /* 15867 * SPEC (2) "If the {base type definition} is a simple type definition, 15868 * the {derivation method} must be extension." 15869 */ 15870 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15871 XML_SCHEMAP_SRC_CT_1, 15872 NULL, WXS_BASIC_CAST type, 15873 "If the base type is a simple type, the derivation method must be " 15874 "'extension'", NULL, NULL); 15875 return (XML_SCHEMAP_SRC_CT_1); 15876 } 15877 /* 15878 * SPEC (3) "Circular definitions are disallowed, except for the �ur-type 15879 * definition�. That is, it must be possible to reach the �ur-type 15880 * definition by repeatedly following the {base type definition}." 15881 * 15882 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15883 */ 15884 /* 15885 * NOTE that (4) and (5) need the following: 15886 * - attribute uses need to be already inherited (apply attr. prohibitions) 15887 * - attribute group references need to be expanded already 15888 * - simple types need to be typefixed already 15889 */ 15890 if (type->attrUses && 15891 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15892 { 15893 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15894 xmlSchemaAttributeUsePtr use, tmp; 15895 int i, j, hasId = 0; 15896 15897 for (i = uses->nbItems -1; i >= 0; i--) { 15898 use = uses->items[i]; 15899 15900 /* 15901 * SPEC ct-props-correct 15902 * (4) "Two distinct attribute declarations in the 15903 * {attribute uses} must not have identical {name}s and 15904 * {target namespace}s." 15905 */ 15906 if (i > 0) { 15907 for (j = i -1; j >= 0; j--) { 15908 tmp = uses->items[j]; 15909 if ((WXS_ATTRUSE_DECL_NAME(use) == 15910 WXS_ATTRUSE_DECL_NAME(tmp)) && 15911 (WXS_ATTRUSE_DECL_TNS(use) == 15912 WXS_ATTRUSE_DECL_TNS(tmp))) 15913 { 15914 xmlChar *str = NULL; 15915 15916 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15917 XML_SCHEMAP_AG_PROPS_CORRECT, 15918 NULL, WXS_BASIC_CAST type, 15919 "Duplicate %s", 15920 xmlSchemaGetComponentDesignation(&str, use), 15921 NULL); 15922 FREE_AND_NULL(str); 15923 /* 15924 * Remove the duplicate. 15925 */ 15926 if (xmlSchemaItemListRemove(uses, i) == -1) 15927 goto exit_failure; 15928 goto next_use; 15929 } 15930 } 15931 } 15932 /* 15933 * SPEC ct-props-correct 15934 * (5) "Two distinct attribute declarations in the 15935 * {attribute uses} must not have {type definition}s which 15936 * are or are derived from ID." 15937 */ 15938 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15939 if (xmlSchemaIsDerivedFromBuiltInType( 15940 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15941 { 15942 if (hasId) { 15943 xmlChar *str = NULL; 15944 15945 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15946 XML_SCHEMAP_AG_PROPS_CORRECT, 15947 NULL, WXS_BASIC_CAST type, 15948 "There must not exist more than one attribute " 15949 "declaration of type 'xs:ID' " 15950 "(or derived from 'xs:ID'). The %s violates this " 15951 "constraint", 15952 xmlSchemaGetComponentDesignation(&str, use), 15953 NULL); 15954 FREE_AND_NULL(str); 15955 if (xmlSchemaItemListRemove(uses, i) == -1) 15956 goto exit_failure; 15957 } 15958 15959 hasId = 1; 15960 } 15961 } 15962 next_use: {} 15963 } 15964 } 15965 return (0); 15966 exit_failure: 15967 return(-1); 15968 } 15969 15970 static int 15971 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 15972 xmlSchemaTypePtr typeB) 15973 { 15974 /* 15975 * TODO: This should implement component-identity 15976 * in the future. 15977 */ 15978 if ((typeA == NULL) || (typeB == NULL)) 15979 return (0); 15980 return (typeA == typeB); 15981 } 15982 15998 static int 15999 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16000 xmlSchemaTypePtr type, 16001 xmlSchemaTypePtr baseType, 16002 int set) 16003 { 16004 int equal = xmlSchemaAreEqualTypes(type, baseType); 16005 /* TODO: Error codes. */ 16006 /* 16007 * SPEC "For a complex type definition (call it D, for derived) 16008 * to be validly derived from a type definition (call this 16009 * B, for base) given a subset of {extension, restriction} 16010 * all of the following must be true:" 16011 */ 16012 if (! equal) { 16013 /* 16014 * SPEC (1) "If B and D are not the same type definition, then the 16015 * {derivation method} of D must not be in the subset." 16016 */ 16017 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16018 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16019 return (1); 16020 } else { 16021 /* 16022 * SPEC (2.1) "B and D must be the same type definition." 16023 */ 16024 return (0); 16025 } 16026 /* 16027 * SPEC (2.2) "B must be D's {base type definition}." 16028 */ 16029 if (type->baseType == baseType) 16030 return (0); 16031 /* 16032 * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type 16033 * definition�." 16034 */ 16035 if (WXS_IS_ANYTYPE(type->baseType)) 16036 return (1); 16037 16038 if (WXS_IS_COMPLEX(type->baseType)) { 16039 /* 16040 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16041 * must be validly derived from B given the subset as defined by this 16042 * constraint." 16043 */ 16044 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16045 baseType, set)); 16046 } else { 16047 /* 16048 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16049 * must be validly derived from B given the subset as defined in Type 16050 * Derivation OK (Simple) (�3.14.6). 16051 */ 16052 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16053 baseType, set)); 16054 } 16055 } 16056 16069 static int 16070 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16071 xmlSchemaTypePtr type, 16072 xmlSchemaTypePtr baseType, 16073 int set) 16074 { 16075 if (WXS_IS_SIMPLE(type)) 16076 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16077 else 16078 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16079 } 16080 16098 static int 16099 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16100 xmlSchemaTypePtr type) 16101 { 16102 xmlSchemaTypePtr base = type->baseType; 16103 /* 16104 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16105 * temporarily only. 16106 */ 16107 /* 16108 * SPEC (1) "If the {base type definition} is a complex type definition, 16109 * then all of the following must be true:" 16110 */ 16111 if (WXS_IS_COMPLEX(base)) { 16112 /* 16113 * SPEC (1.1) "The {final} of the {base type definition} must not 16114 * contain extension." 16115 */ 16116 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16117 xmlSchemaPCustomErr(ctxt, 16118 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16119 WXS_BASIC_CAST type, NULL, 16120 "The 'final' of the base type definition " 16121 "contains 'extension'", NULL); 16122 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16123 } 16124 16125 /* 16126 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16127 * since they are automatically satisfied through the 16128 * inheriting mechanism. 16129 * Note that even if redefining components, the inheriting mechanism 16130 * is used. 16131 */ 16132 #if 0 16133 /* 16134 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16135 * uses} 16136 * of the complex type definition itself, that is, for every attribute 16137 * use in the {attribute uses} of the {base type definition}, there 16138 * must be an attribute use in the {attribute uses} of the complex 16139 * type definition itself whose {attribute declaration} has the same 16140 * {name}, {target namespace} and {type definition} as its attribute 16141 * declaration" 16142 */ 16143 if (base->attrUses != NULL) { 16144 int i, j, found; 16145 xmlSchemaAttributeUsePtr use, buse; 16146 16147 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16148 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16149 found = 0; 16150 if (type->attrUses != NULL) { 16151 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16152 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16153 { 16154 if ((WXS_ATTRUSE_DECL_NAME(use) == 16155 WXS_ATTRUSE_DECL_NAME(buse)) && 16156 (WXS_ATTRUSE_DECL_TNS(use) == 16157 WXS_ATTRUSE_DECL_TNS(buse)) && 16158 (WXS_ATTRUSE_TYPEDEF(use) == 16159 WXS_ATTRUSE_TYPEDEF(buse)) 16160 { 16161 found = 1; 16162 break; 16163 } 16164 } 16165 } 16166 if (! found) { 16167 xmlChar *str = NULL; 16168 16169 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16170 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16171 NULL, WXS_BASIC_CAST type, 16172 /* 16173 * TODO: The report does not indicate that also the 16174 * type needs to be the same. 16175 */ 16176 "This type is missing a matching correspondent " 16177 "for its {base type}'s %s in its {attribute uses}", 16178 xmlSchemaGetComponentDesignation(&str, 16179 buse->children), 16180 NULL); 16181 FREE_AND_NULL(str) 16182 } 16183 } 16184 } 16185 /* 16186 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16187 * definition must also have one, and the base type definition's 16188 * {attribute wildcard}'s {namespace constraint} must be a subset 16189 * of the complex type definition's {attribute wildcard}'s {namespace 16190 * constraint}, as defined by Wildcard Subset (�3.10.6)." 16191 */ 16192 16193 /* 16194 * MAYBE TODO: Enable if ever needed. But this will be needed only 16195 * if created the type via a schema construction API. 16196 */ 16197 if (base->attributeWildcard != NULL) { 16198 if (type->attributeWilcard == NULL) { 16199 xmlChar *str = NULL; 16200 16201 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16202 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16203 NULL, type, 16204 "The base %s has an attribute wildcard, " 16205 "but this type is missing an attribute wildcard", 16206 xmlSchemaGetComponentDesignation(&str, base)); 16207 FREE_AND_NULL(str) 16208 16209 } else if (xmlSchemaCheckCOSNSSubset( 16210 base->attributeWildcard, type->attributeWildcard)) 16211 { 16212 xmlChar *str = NULL; 16213 16214 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16215 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16216 NULL, type, 16217 "The attribute wildcard is not a valid " 16218 "superset of the one in the base %s", 16219 xmlSchemaGetComponentDesignation(&str, base)); 16220 FREE_AND_NULL(str) 16221 } 16222 } 16223 #endif 16224 /* 16225 * SPEC (1.4) "One of the following must be true:" 16226 */ 16227 if ((type->contentTypeDef != NULL) && 16228 (type->contentTypeDef == base->contentTypeDef)) { 16229 /* 16230 * SPEC (1.4.1) "The {content type} of the {base type definition} 16231 * and the {content type} of the complex type definition itself 16232 * must be the same simple type definition" 16233 * PASS 16234 */ 16235 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16236 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16237 /* 16238 * SPEC (1.4.2) "The {content type} of both the {base type 16239 * definition} and the complex type definition itself must 16240 * be empty." 16241 * PASS 16242 */ 16243 } else { 16244 /* 16245 * SPEC (1.4.3) "All of the following must be true:" 16246 */ 16247 if (type->subtypes == NULL) { 16248 /* 16249 * SPEC 1.4.3.1 The {content type} of the complex type 16250 * definition itself must specify a particle. 16251 */ 16252 xmlSchemaPCustomErr(ctxt, 16253 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16254 WXS_BASIC_CAST type, NULL, 16255 "The content type must specify a particle", NULL); 16256 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16257 } 16258 /* 16259 * SPEC (1.4.3.2) "One of the following must be true:" 16260 */ 16261 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16262 /* 16263 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16264 * definition} must be empty. 16265 * PASS 16266 */ 16267 } else { 16268 /* 16269 * SPEC (1.4.3.2.2) "All of the following must be true:" 16270 */ 16271 if ((type->contentType != base->contentType) || 16272 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16273 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16274 /* 16275 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16276 * or both must be element-only." 16277 */ 16278 xmlSchemaPCustomErr(ctxt, 16279 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16280 WXS_BASIC_CAST type, NULL, 16281 "The content type of both, the type and its base " 16282 "type, must either 'mixed' or 'element-only'", NULL); 16283 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16284 } 16285 /* 16286 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16287 * complex type definition must be a �valid extension� 16288 * of the {base type definition}'s particle, as defined 16289 * in Particle Valid (Extension) (�3.9.6)." 16290 * 16291 * NOTE that we won't check "Particle Valid (Extension)", 16292 * since it is ensured by the derivation process in 16293 * xmlSchemaTypeFixup(). We need to implement this when heading 16294 * for a construction API 16295 * TODO: !! This is needed to be checked if redefining a type !! 16296 */ 16297 } 16298 /* 16299 * URGENT TODO (1.5) 16300 */ 16301 } 16302 } else { 16303 /* 16304 * SPEC (2) "If the {base type definition} is a simple type definition, 16305 * then all of the following must be true:" 16306 */ 16307 if (type->contentTypeDef != base) { 16308 /* 16309 * SPEC (2.1) "The {content type} must be the same simple type 16310 * definition." 16311 */ 16312 xmlSchemaPCustomErr(ctxt, 16313 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16314 WXS_BASIC_CAST type, NULL, 16315 "The content type must be the simple base type", NULL); 16316 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16317 } 16318 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16319 /* 16320 * SPEC (2.2) "The {final} of the {base type definition} must not 16321 * contain extension" 16322 * NOTE that this is the same as (1.1). 16323 */ 16324 xmlSchemaPCustomErr(ctxt, 16325 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16326 WXS_BASIC_CAST type, NULL, 16327 "The 'final' of the base type definition " 16328 "contains 'extension'", NULL); 16329 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16330 } 16331 } 16332 return (0); 16333 } 16334 16355 static int 16356 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16357 xmlSchemaTypePtr type) 16358 { 16359 xmlSchemaTypePtr base; 16360 16361 /* 16362 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16363 * temporarily only. 16364 */ 16365 base = type->baseType; 16366 if (! WXS_IS_COMPLEX(base)) { 16367 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16368 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16369 type->node, WXS_BASIC_CAST type, 16370 "The base type must be a complex type", NULL, NULL); 16371 return(ctxt->err); 16372 } 16373 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16374 /* 16375 * SPEC (1) "The {base type definition} must be a complex type 16376 * definition whose {final} does not contain restriction." 16377 */ 16378 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16379 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16380 type->node, WXS_BASIC_CAST type, 16381 "The 'final' of the base type definition " 16382 "contains 'restriction'", NULL, NULL); 16383 return (ctxt->err); 16384 } 16385 /* 16386 * SPEC (2), (3) and (4) 16387 * Those are handled in a separate function, since the 16388 * same constraints are needed for redefinition of 16389 * attribute groups as well. 16390 */ 16391 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16392 XML_SCHEMA_ACTION_DERIVE, 16393 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16394 type->attrUses, base->attrUses, 16395 type->attributeWildcard, 16396 base->attributeWildcard) == -1) 16397 { 16398 return(-1); 16399 } 16400 /* 16401 * SPEC (5) "One of the following must be true:" 16402 */ 16403 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16404 /* 16405 * SPEC (5.1) "The {base type definition} must be the 16406 * �ur-type definition�." 16407 * PASS 16408 */ 16409 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16410 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16411 /* 16412 * SPEC (5.2.1) "The {content type} of the complex type definition 16413 * must be a simple type definition" 16414 * 16415 * SPEC (5.2.2) "One of the following must be true:" 16416 */ 16417 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16418 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16419 { 16420 int err; 16421 /* 16422 * SPEC (5.2.2.1) "The {content type} of the {base type 16423 * definition} must be a simple type definition from which 16424 * the {content type} is validly derived given the empty 16425 * set as defined in Type Derivation OK (Simple) (�3.14.6)." 16426 * 16427 * ATTENTION TODO: This seems not needed if the type implicitely 16428 * derived from the base type. 16429 * 16430 */ 16431 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16432 type->contentTypeDef, base->contentTypeDef, 0); 16433 if (err != 0) { 16434 xmlChar *strA = NULL, *strB = NULL; 16435 16436 if (err == -1) 16437 return(-1); 16438 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16439 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16440 NULL, WXS_BASIC_CAST type, 16441 "The {content type} %s is not validly derived from the " 16442 "base type's {content type} %s", 16443 xmlSchemaGetComponentDesignation(&strA, 16444 type->contentTypeDef), 16445 xmlSchemaGetComponentDesignation(&strB, 16446 base->contentTypeDef)); 16447 FREE_AND_NULL(strA); 16448 FREE_AND_NULL(strB); 16449 return(ctxt->err); 16450 } 16451 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16452 (xmlSchemaIsParticleEmptiable( 16453 (xmlSchemaParticlePtr) base->subtypes))) { 16454 /* 16455 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16456 * and have a particle which is �emptiable� as defined in 16457 * Particle Emptiable (�3.9.6)." 16458 * PASS 16459 */ 16460 } else { 16461 xmlSchemaPCustomErr(ctxt, 16462 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16463 WXS_BASIC_CAST type, NULL, 16464 "The content type of the base type must be either " 16465 "a simple type or 'mixed' and an emptiable particle", NULL); 16466 return (ctxt->err); 16467 } 16468 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16469 /* 16470 * SPEC (5.3.1) "The {content type} of the complex type itself must 16471 * be empty" 16472 */ 16473 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16474 /* 16475 * SPEC (5.3.2.1) "The {content type} of the {base type 16476 * definition} must also be empty." 16477 * PASS 16478 */ 16479 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16480 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16481 xmlSchemaIsParticleEmptiable( 16482 (xmlSchemaParticlePtr) base->subtypes)) { 16483 /* 16484 * SPEC (5.3.2.2) "The {content type} of the {base type 16485 * definition} must be elementOnly or mixed and have a particle 16486 * which is �emptiable� as defined in Particle Emptiable (�3.9.6)." 16487 * PASS 16488 */ 16489 } else { 16490 xmlSchemaPCustomErr(ctxt, 16491 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16492 WXS_BASIC_CAST type, NULL, 16493 "The content type of the base type must be either " 16494 "empty or 'mixed' (or 'elements-only') and an emptiable " 16495 "particle", NULL); 16496 return (ctxt->err); 16497 } 16498 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16499 WXS_HAS_MIXED_CONTENT(type)) { 16500 /* 16501 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16502 * itself must be element-only" 16503 */ 16504 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16505 /* 16506 * SPEC (5.4.1.2) "The {content type} of the complex type 16507 * definition itself and of the {base type definition} must be 16508 * mixed" 16509 */ 16510 xmlSchemaPCustomErr(ctxt, 16511 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16512 WXS_BASIC_CAST type, NULL, 16513 "If the content type is 'mixed', then the content type of the " 16514 "base type must also be 'mixed'", NULL); 16515 return (ctxt->err); 16516 } 16517 /* 16518 * SPEC (5.4.2) "The particle of the complex type definition itself 16519 * must be a �valid restriction� of the particle of the {content 16520 * type} of the {base type definition} as defined in Particle Valid 16521 * (Restriction) (�3.9.6). 16522 * 16523 * URGENT TODO: (5.4.2) 16524 */ 16525 } else { 16526 xmlSchemaPCustomErr(ctxt, 16527 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16528 WXS_BASIC_CAST type, NULL, 16529 "The type is not a valid restriction of its base type", NULL); 16530 return (ctxt->err); 16531 } 16532 return (0); 16533 } 16534 16545 static int 16546 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16547 xmlSchemaTypePtr type) 16548 { 16549 int ret; 16550 /* 16551 * Complex Type Definition Properties Correct 16552 */ 16553 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16554 if (ret != 0) 16555 return (ret); 16556 if (WXS_IS_EXTENSION(type)) 16557 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16558 else 16559 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16560 return (ret); 16561 } 16562 16575 static int 16576 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16577 xmlSchemaTypePtr type) 16578 { 16579 xmlSchemaTypePtr base; 16580 int ret = 0; 16581 16582 /* 16583 * TODO: Adjust the error codes here, as I used 16584 * XML_SCHEMAP_SRC_CT_1 only yet. 16585 */ 16586 base = type->baseType; 16587 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16588 /* 16589 * 1 If the <complexContent> alternative is chosen, the type definition 16590 * �resolved� to by the �actual value� of the base [attribute] 16591 * must be a complex type definition; 16592 */ 16593 if (! WXS_IS_COMPLEX(base)) { 16594 xmlChar *str = NULL; 16595 xmlSchemaPCustomErr(ctxt, 16596 XML_SCHEMAP_SRC_CT_1, 16597 WXS_BASIC_CAST type, type->node, 16598 "If using <complexContent>, the base type is expected to be " 16599 "a complex type. The base type '%s' is a simple type", 16600 xmlSchemaFormatQName(&str, base->targetNamespace, 16601 base->name)); 16602 FREE_AND_NULL(str) 16603 return (XML_SCHEMAP_SRC_CT_1); 16604 } 16605 } else { 16606 /* 16607 * SPEC 16608 * 2 If the <simpleContent> alternative is chosen, all of the 16609 * following must be true: 16610 * 2.1 The type definition �resolved� to by the �actual value� of the 16611 * base [attribute] must be one of the following: 16612 */ 16613 if (WXS_IS_SIMPLE(base)) { 16614 if (WXS_IS_EXTENSION(type) == 0) { 16615 xmlChar *str = NULL; 16616 /* 16617 * 2.1.3 only if the <extension> alternative is also 16618 * chosen, a simple type definition. 16619 */ 16620 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16621 xmlSchemaPCustomErr(ctxt, 16622 XML_SCHEMAP_SRC_CT_1, 16623 WXS_BASIC_CAST type, NULL, 16624 "If using <simpleContent> and <restriction>, the base " 16625 "type must be a complex type. The base type '%s' is " 16626 "a simple type", 16627 xmlSchemaFormatQName(&str, base->targetNamespace, 16628 base->name)); 16629 FREE_AND_NULL(str) 16630 return (XML_SCHEMAP_SRC_CT_1); 16631 } 16632 } else { 16633 /* Base type is a complex type. */ 16634 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16635 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16636 /* 16637 * 2.1.1 a complex type definition whose {content type} is a 16638 * simple type definition; 16639 * PASS 16640 */ 16641 if (base->contentTypeDef == NULL) { 16642 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16643 WXS_BASIC_CAST type, NULL, 16644 "Internal error: xmlSchemaCheckSRCCT, " 16645 "'%s', base type has no content type", 16646 type->name); 16647 return (-1); 16648 } 16649 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16650 (WXS_IS_RESTRICTION(type))) { 16651 16652 /* 16653 * 2.1.2 only if the <restriction> alternative is also 16654 * chosen, a complex type definition whose {content type} 16655 * is mixed and a particle emptiable. 16656 */ 16657 if (! xmlSchemaIsParticleEmptiable( 16658 (xmlSchemaParticlePtr) base->subtypes)) { 16659 ret = XML_SCHEMAP_SRC_CT_1; 16660 } else 16661 /* 16662 * Attention: at this point the <simpleType> child is in 16663 * ->contentTypeDef (put there during parsing). 16664 */ 16665 if (type->contentTypeDef == NULL) { 16666 xmlChar *str = NULL; 16667 /* 16668 * 2.2 If clause 2.1.2 above is satisfied, then there 16669 * must be a <simpleType> among the [children] of 16670 * <restriction>. 16671 */ 16672 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16673 xmlSchemaPCustomErr(ctxt, 16674 XML_SCHEMAP_SRC_CT_1, 16675 WXS_BASIC_CAST type, NULL, 16676 "A <simpleType> is expected among the children " 16677 "of <restriction>, if <simpleContent> is used and " 16678 "the base type '%s' is a complex type", 16679 xmlSchemaFormatQName(&str, base->targetNamespace, 16680 base->name)); 16681 FREE_AND_NULL(str) 16682 return (XML_SCHEMAP_SRC_CT_1); 16683 } 16684 } else { 16685 ret = XML_SCHEMAP_SRC_CT_1; 16686 } 16687 } 16688 if (ret > 0) { 16689 xmlChar *str = NULL; 16690 if (WXS_IS_RESTRICTION(type)) { 16691 xmlSchemaPCustomErr(ctxt, 16692 XML_SCHEMAP_SRC_CT_1, 16693 WXS_BASIC_CAST type, NULL, 16694 "If <simpleContent> and <restriction> is used, the " 16695 "base type must be a simple type or a complex type with " 16696 "mixed content and particle emptiable. The base type " 16697 "'%s' is none of those", 16698 xmlSchemaFormatQName(&str, base->targetNamespace, 16699 base->name)); 16700 } else { 16701 xmlSchemaPCustomErr(ctxt, 16702 XML_SCHEMAP_SRC_CT_1, 16703 WXS_BASIC_CAST type, NULL, 16704 "If <simpleContent> and <extension> is used, the " 16705 "base type must be a simple type. The base type '%s' " 16706 "is a complex type", 16707 xmlSchemaFormatQName(&str, base->targetNamespace, 16708 base->name)); 16709 } 16710 FREE_AND_NULL(str) 16711 } 16712 } 16713 /* 16714 * SPEC (3) "The corresponding complex type definition component must 16715 * satisfy the conditions set out in Constraints on Complex Type 16716 * Definition Schema Components (�3.4.6);" 16717 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16718 */ 16719 /* 16720 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16721 * above for {attribute wildcard} is satisfied, the intensional 16722 * intersection must be expressible, as defined in Attribute Wildcard 16723 * Intersection (�3.10.6). 16724 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16725 */ 16726 return (ret); 16727 } 16728 16729 #ifdef ENABLE_PARTICLE_RESTRICTION 16730 16744 static int 16745 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16746 int bmin, int bmax) 16747 { 16748 if (rmin < bmin) 16749 return (1); 16750 if ((bmax != UNBOUNDED) && 16751 (rmax > bmax)) 16752 return (1); 16753 return (0); 16754 } 16755 16774 static int 16775 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16776 xmlSchemaParticlePtr r, 16777 xmlSchemaParticlePtr b) 16778 { 16779 xmlSchemaElementPtr elemR, elemB; 16780 16781 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16782 elemR = (xmlSchemaElementPtr) r->children; 16783 elemB = (xmlSchemaElementPtr) b->children; 16784 /* 16785 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16786 * the same." 16787 */ 16788 if ((elemR != elemB) && 16789 ((! xmlStrEqual(elemR->name, elemB->name)) || 16790 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16791 return (1); 16792 /* 16793 * SPEC (2) "R's occurrence range is a valid restriction of B's 16794 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 16795 */ 16796 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16797 b->minOccurs, b->maxOccurs) != 0) 16798 return (1); 16799 /* 16800 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16801 * {scope} are global." 16802 */ 16803 if (elemR == elemB) 16804 return (0); 16805 /* 16806 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16807 */ 16808 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16809 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16810 return (1); 16811 /* 16812 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16813 * or is not fixed, or R's declaration's {value constraint} is fixed 16814 * with the same value." 16815 */ 16816 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16817 ((elemR->value == NULL) || 16818 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16819 /* TODO: Equality of the initial value or normalized or canonical? */ 16820 (! xmlStrEqual(elemR->value, elemB->value)))) 16821 return (1); 16822 /* 16823 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16824 * definitions} is a subset of B's declaration's {identity-constraint 16825 * definitions}, if any." 16826 */ 16827 if (elemB->idcs != NULL) { 16828 /* TODO */ 16829 } 16830 /* 16831 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16832 * superset of B's declaration's {disallowed substitutions}." 16833 */ 16834 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16835 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16836 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16837 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16838 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16839 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16840 return (1); 16841 /* 16842 * SPEC (3.2.5) "R's {type definition} is validly derived given 16843 * {extension, list, union} from B's {type definition}" 16844 * 16845 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16846 * set, if the corresponding constraints handle "restriction" and 16847 * "extension" only? 16848 * 16849 */ 16850 { 16851 int set = 0; 16852 16853 set |= SUBSET_EXTENSION; 16854 set |= SUBSET_LIST; 16855 set |= SUBSET_UNION; 16856 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16857 elemB->subtypes, set) != 0) 16858 return (1); 16859 } 16860 return (0); 16861 } 16862 16879 static int 16880 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16881 xmlSchemaParticlePtr r, 16882 xmlSchemaParticlePtr b) 16883 { 16884 /* TODO:Error codes (rcase-NSCompat). */ 16885 /* 16886 * SPEC "For an element declaration particle to be a �valid restriction� 16887 * of a wildcard particle all of the following must be true:" 16888 * 16889 * SPEC (1) "The element declaration's {target namespace} is �valid� 16890 * with respect to the wildcard's {namespace constraint} as defined by 16891 * Wildcard allows Namespace Name (�3.10.4)." 16892 */ 16893 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16894 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16895 return (1); 16896 /* 16897 * SPEC (2) "R's occurrence range is a valid restriction of B's 16898 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 16899 */ 16900 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16901 b->minOccurs, b->maxOccurs) != 0) 16902 return (1); 16903 16904 return (0); 16905 } 16906 16923 static int 16924 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16925 xmlSchemaParticlePtr r, 16926 xmlSchemaParticlePtr b) 16927 { 16928 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16929 TODO 16930 return (0); 16931 } 16932 16949 static int 16950 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16951 xmlSchemaParticlePtr r, 16952 xmlSchemaParticlePtr b, 16953 int isAnyTypeBase) 16954 { 16955 /* TODO: Error codes (rcase-NSSubset). */ 16956 /* 16957 * SPEC (1) "R's occurrence range is a valid restriction of B's 16958 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 16959 */ 16960 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16961 b->minOccurs, b->maxOccurs)) 16962 return (1); 16963 /* 16964 * SPEC (2) "R's {namespace constraint} must be an intensional subset 16965 * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)." 16966 */ 16967 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 16968 (xmlSchemaWildcardPtr) b->children)) 16969 return (1); 16970 /* 16971 * SPEC (3) "Unless B is the content model wildcard of the �ur-type 16972 * definition�, R's {process contents} must be identical to or stronger 16973 * than B's {process contents}, where strict is stronger than lax is 16974 * stronger than skip." 16975 */ 16976 if (! isAnyTypeBase) { 16977 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 16978 ((xmlSchemaWildcardPtr) b->children)->processContents) 16979 return (1); 16980 } 16981 16982 return (0); 16983 } 16984 16999 static int 17000 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17001 xmlSchemaParticlePtr r, 17002 xmlSchemaParticlePtr b) 17003 { 17004 int ret = 0; 17005 17006 /*part = WXS_TYPE_PARTICLE(type); 17007 basePart = WXS_TYPE_PARTICLE(base); 17008 */ 17009 17010 TODO 17011 17012 /* 17013 * SPEC (1) "They are the same particle." 17014 */ 17015 if (r == b) 17016 return (0); 17017 17018 17019 return (0); 17020 } 17021 17022 #if 0 17023 17040 static int 17041 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17042 xmlSchemaParticlePtr r, 17043 xmlSchemaParticlePtr b) 17044 { 17045 xmlSchemaParticlePtr part; 17046 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17047 if ((r->children == NULL) || (r->children->children == NULL)) 17048 return (-1); 17049 /* 17050 * SPEC "For a group particle to be a �valid restriction� of a 17051 * wildcard particle..." 17052 * 17053 * SPEC (1) "Every member of the {particles} of the group is a �valid 17054 * restriction� of the wildcard as defined by 17055 * Particle Valid (Restriction) (�3.9.6)." 17056 */ 17057 part = (xmlSchemaParticlePtr) r->children->children; 17058 do { 17059 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17060 return (1); 17061 part = (xmlSchemaParticlePtr) part->next; 17062 } while (part != NULL); 17063 /* 17064 * SPEC (2) "The effective total range of the group [...] is a 17065 * valid restriction of B's occurrence range as defined by 17066 * Occurrence Range OK (�3.9.6)." 17067 */ 17068 if (xmlSchemaCheckParticleRangeOK( 17069 xmlSchemaGetParticleTotalRangeMin(r), 17070 xmlSchemaGetParticleTotalRangeMax(r), 17071 b->minOccurs, b->maxOccurs) != 0) 17072 return (1); 17073 return (0); 17074 } 17075 #endif 17076 17095 static int 17096 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17097 xmlSchemaParticlePtr r, 17098 xmlSchemaParticlePtr b) 17099 { 17100 /* xmlSchemaParticlePtr part; */ 17101 /* TODO: Error codes (rcase-Recurse). */ 17102 if ((r->children == NULL) || (b->children == NULL) || 17103 (r->children->type != b->children->type)) 17104 return (-1); 17105 /* 17106 * SPEC "For an all or sequence group particle to be a �valid 17107 * restriction� of another group particle with the same {compositor}..." 17108 * 17109 * SPEC (1) "R's occurrence range is a valid restriction of B's 17110 * occurrence range as defined by Occurrence Range OK (�3.9.6)." 17111 */ 17112 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17113 b->minOccurs, b->maxOccurs)) 17114 return (1); 17115 17116 17117 return (0); 17118 } 17119 17120 #endif 17121 17122 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17123 xmlSchemaPCustomErrExt(pctxt, \ 17124 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17125 WXS_BASIC_CAST fac1, fac1->node, \ 17126 "It is an error for both '%s' and '%s' to be specified on the "\ 17127 "same type definition", \ 17128 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17129 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17130 17131 #define FACET_RESTR_ERR(fac1, msg) \ 17132 xmlSchemaPCustomErr(pctxt, \ 17133 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17134 WXS_BASIC_CAST fac1, fac1->node, \ 17135 msg, NULL); 17136 17137 #define FACET_RESTR_FIXED_ERR(fac) \ 17138 xmlSchemaPCustomErr(pctxt, \ 17139 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17140 WXS_BASIC_CAST fac, fac->node, \ 17141 "The base type's facet is 'fixed', thus the value must not " \ 17142 "differ", NULL); 17143 17144 static void 17145 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17146 xmlSchemaFacetPtr facet1, 17147 xmlSchemaFacetPtr facet2, 17148 int lessGreater, 17149 int orEqual, 17150 int ofBase) 17151 { 17152 xmlChar *msg = NULL; 17153 17154 msg = xmlStrdup(BAD_CAST "'"); 17155 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17156 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17157 if (lessGreater == 0) 17158 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17159 if (lessGreater == 1) 17160 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17161 else 17162 msg = xmlStrcat(msg, BAD_CAST " less than"); 17163 17164 if (orEqual) 17165 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17166 msg = xmlStrcat(msg, BAD_CAST " '"); 17167 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17168 if (ofBase) 17169 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17170 else 17171 msg = xmlStrcat(msg, BAD_CAST "'"); 17172 17173 xmlSchemaPCustomErr(pctxt, 17174 XML_SCHEMAP_INVALID_FACET_VALUE, 17175 WXS_BASIC_CAST facet1, NULL, 17176 (const char *) msg, NULL); 17177 17178 if (msg != NULL) 17179 xmlFree(msg); 17180 } 17181 17182 /* 17183 * xmlSchemaDeriveAndValidateFacets: 17184 * 17185 * Schema Component Constraint: Simple Type Restriction (Facets) 17186 * (st-restrict-facets) 17187 */ 17188 static int 17189 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17190 xmlSchemaTypePtr type) 17191 { 17192 xmlSchemaTypePtr base = type->baseType; 17193 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17194 xmlSchemaFacetPtr facet, bfacet, 17195 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17196 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17197 fmininc = NULL, fmaxinc = NULL, 17198 fminexc = NULL, fmaxexc = NULL, 17199 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17200 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17201 bfmininc = NULL, bfmaxinc = NULL, 17202 bfminexc = NULL, bfmaxexc = NULL; 17203 int res; /* err = 0, fixedErr; */ 17204 17205 /* 17206 * SPEC st-restrict-facets 1: 17207 * "The {variety} of R is the same as that of B." 17208 */ 17209 /* 17210 * SPEC st-restrict-facets 2: 17211 * "If {variety} is atomic, the {primitive type definition} 17212 * of R is the same as that of B." 17213 * 17214 * NOTE: we leave 1 & 2 out for now, since this will be 17215 * satisfied by the derivation process. 17216 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17217 */ 17218 /* 17219 * SPEC st-restrict-facets 3: 17220 * "The {facets} of R are the union of S and the {facets} 17221 * of B, eliminating duplicates. To eliminate duplicates, 17222 * when a facet of the same kind occurs in both S and the 17223 * {facets} of B, the one in the {facets} of B is not 17224 * included, with the exception of enumeration and pattern 17225 * facets, for which multiple occurrences with distinct values 17226 * are allowed." 17227 */ 17228 17229 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17230 return (0); 17231 17232 last = type->facetSet; 17233 if (last != NULL) 17234 while (last->next != NULL) 17235 last = last->next; 17236 17237 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17238 facet = cur->facet; 17239 switch (facet->type) { 17240 case XML_SCHEMA_FACET_LENGTH: 17241 flength = facet; break; 17242 case XML_SCHEMA_FACET_MINLENGTH: 17243 fminlen = facet; break; 17244 case XML_SCHEMA_FACET_MININCLUSIVE: 17245 fmininc = facet; break; 17246 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17247 fminexc = facet; break; 17248 case XML_SCHEMA_FACET_MAXLENGTH: 17249 fmaxlen = facet; break; 17250 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17251 fmaxinc = facet; break; 17252 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17253 fmaxexc = facet; break; 17254 case XML_SCHEMA_FACET_TOTALDIGITS: 17255 ftotdig = facet; break; 17256 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17257 ffracdig = facet; break; 17258 default: 17259 break; 17260 } 17261 } 17262 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17263 facet = cur->facet; 17264 switch (facet->type) { 17265 case XML_SCHEMA_FACET_LENGTH: 17266 bflength = facet; break; 17267 case XML_SCHEMA_FACET_MINLENGTH: 17268 bfminlen = facet; break; 17269 case XML_SCHEMA_FACET_MININCLUSIVE: 17270 bfmininc = facet; break; 17271 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17272 bfminexc = facet; break; 17273 case XML_SCHEMA_FACET_MAXLENGTH: 17274 bfmaxlen = facet; break; 17275 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17276 bfmaxinc = facet; break; 17277 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17278 bfmaxexc = facet; break; 17279 case XML_SCHEMA_FACET_TOTALDIGITS: 17280 bftotdig = facet; break; 17281 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17282 bffracdig = facet; break; 17283 default: 17284 break; 17285 } 17286 } 17287 /* 17288 * length and minLength or maxLength (2.2) + (3.2) 17289 */ 17290 if (flength && (fminlen || fmaxlen)) { 17291 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17292 "either of 'minLength' or 'maxLength' to be specified on " 17293 "the same type definition") 17294 } 17295 /* 17296 * Mutual exclusions in the same derivation step. 17297 */ 17298 if ((fmaxinc) && (fmaxexc)) { 17299 /* 17300 * SCC "maxInclusive and maxExclusive" 17301 */ 17302 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17303 } 17304 if ((fmininc) && (fminexc)) { 17305 /* 17306 * SCC "minInclusive and minExclusive" 17307 */ 17308 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17309 } 17310 17311 if (flength && bflength) { 17312 /* 17313 * SCC "length valid restriction" 17314 * The values have to be equal. 17315 */ 17316 res = xmlSchemaCompareValues(flength->val, bflength->val); 17317 if (res == -2) 17318 goto internal_error; 17319 if (res != 0) 17320 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17321 if ((res != 0) && (bflength->fixed)) { 17322 FACET_RESTR_FIXED_ERR(flength) 17323 } 17324 17325 } 17326 if (fminlen && bfminlen) { 17327 /* 17328 * SCC "minLength valid restriction" 17329 * minLength >= BASE minLength 17330 */ 17331 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17332 if (res == -2) 17333 goto internal_error; 17334 if (res == -1) 17335 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17336 if ((res != 0) && (bfminlen->fixed)) { 17337 FACET_RESTR_FIXED_ERR(fminlen) 17338 } 17339 } 17340 if (fmaxlen && bfmaxlen) { 17341 /* 17342 * SCC "maxLength valid restriction" 17343 * maxLength <= BASE minLength 17344 */ 17345 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17346 if (res == -2) 17347 goto internal_error; 17348 if (res == 1) 17349 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17350 if ((res != 0) && (bfmaxlen->fixed)) { 17351 FACET_RESTR_FIXED_ERR(fmaxlen) 17352 } 17353 } 17354 /* 17355 * SCC "length and minLength or maxLength" 17356 */ 17357 if (! flength) 17358 flength = bflength; 17359 if (flength) { 17360 if (! fminlen) 17361 fminlen = bfminlen; 17362 if (fminlen) { 17363 /* (1.1) length >= minLength */ 17364 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17365 if (res == -2) 17366 goto internal_error; 17367 if (res == -1) 17368 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17369 } 17370 if (! fmaxlen) 17371 fmaxlen = bfmaxlen; 17372 if (fmaxlen) { 17373 /* (2.1) length <= maxLength */ 17374 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17375 if (res == -2) 17376 goto internal_error; 17377 if (res == 1) 17378 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17379 } 17380 } 17381 if (fmaxinc) { 17382 /* 17383 * "maxInclusive" 17384 */ 17385 if (fmininc) { 17386 /* SCC "maxInclusive >= minInclusive" */ 17387 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17388 if (res == -2) 17389 goto internal_error; 17390 if (res == -1) { 17391 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17392 } 17393 } 17394 /* 17395 * SCC "maxInclusive valid restriction" 17396 */ 17397 if (bfmaxinc) { 17398 /* maxInclusive <= BASE maxInclusive */ 17399 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17400 if (res == -2) 17401 goto internal_error; 17402 if (res == 1) 17403 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17404 if ((res != 0) && (bfmaxinc->fixed)) { 17405 FACET_RESTR_FIXED_ERR(fmaxinc) 17406 } 17407 } 17408 if (bfmaxexc) { 17409 /* maxInclusive < BASE maxExclusive */ 17410 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17411 if (res == -2) 17412 goto internal_error; 17413 if (res != -1) { 17414 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17415 } 17416 } 17417 if (bfmininc) { 17418 /* maxInclusive >= BASE minInclusive */ 17419 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17420 if (res == -2) 17421 goto internal_error; 17422 if (res == -1) { 17423 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17424 } 17425 } 17426 if (bfminexc) { 17427 /* maxInclusive > BASE minExclusive */ 17428 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17429 if (res == -2) 17430 goto internal_error; 17431 if (res != 1) { 17432 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17433 } 17434 } 17435 } 17436 if (fmaxexc) { 17437 /* 17438 * "maxExclusive >= minExclusive" 17439 */ 17440 if (fminexc) { 17441 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17442 if (res == -2) 17443 goto internal_error; 17444 if (res == -1) { 17445 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17446 } 17447 } 17448 /* 17449 * "maxExclusive valid restriction" 17450 */ 17451 if (bfmaxexc) { 17452 /* maxExclusive <= BASE maxExclusive */ 17453 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17454 if (res == -2) 17455 goto internal_error; 17456 if (res == 1) { 17457 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17458 } 17459 if ((res != 0) && (bfmaxexc->fixed)) { 17460 FACET_RESTR_FIXED_ERR(fmaxexc) 17461 } 17462 } 17463 if (bfmaxinc) { 17464 /* maxExclusive <= BASE maxInclusive */ 17465 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17466 if (res == -2) 17467 goto internal_error; 17468 if (res == 1) { 17469 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17470 } 17471 } 17472 if (bfmininc) { 17473 /* maxExclusive > BASE minInclusive */ 17474 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17475 if (res == -2) 17476 goto internal_error; 17477 if (res != 1) { 17478 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17479 } 17480 } 17481 if (bfminexc) { 17482 /* maxExclusive > BASE minExclusive */ 17483 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17484 if (res == -2) 17485 goto internal_error; 17486 if (res != 1) { 17487 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17488 } 17489 } 17490 } 17491 if (fminexc) { 17492 /* 17493 * "minExclusive < maxInclusive" 17494 */ 17495 if (fmaxinc) { 17496 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17497 if (res == -2) 17498 goto internal_error; 17499 if (res != -1) { 17500 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17501 } 17502 } 17503 /* 17504 * "minExclusive valid restriction" 17505 */ 17506 if (bfminexc) { 17507 /* minExclusive >= BASE minExclusive */ 17508 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17509 if (res == -2) 17510 goto internal_error; 17511 if (res == -1) { 17512 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17513 } 17514 if ((res != 0) && (bfminexc->fixed)) { 17515 FACET_RESTR_FIXED_ERR(fminexc) 17516 } 17517 } 17518 if (bfmaxinc) { 17519 /* minExclusive <= BASE maxInclusive */ 17520 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17521 if (res == -2) 17522 goto internal_error; 17523 if (res == 1) { 17524 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17525 } 17526 } 17527 if (bfmininc) { 17528 /* minExclusive >= BASE minInclusive */ 17529 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17530 if (res == -2) 17531 goto internal_error; 17532 if (res == -1) { 17533 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17534 } 17535 } 17536 if (bfmaxexc) { 17537 /* minExclusive < BASE maxExclusive */ 17538 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17539 if (res == -2) 17540 goto internal_error; 17541 if (res != -1) { 17542 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17543 } 17544 } 17545 } 17546 if (fmininc) { 17547 /* 17548 * "minInclusive < maxExclusive" 17549 */ 17550 if (fmaxexc) { 17551 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17552 if (res == -2) 17553 goto internal_error; 17554 if (res != -1) { 17555 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17556 } 17557 } 17558 /* 17559 * "minExclusive valid restriction" 17560 */ 17561 if (bfmininc) { 17562 /* minInclusive >= BASE minInclusive */ 17563 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17564 if (res == -2) 17565 goto internal_error; 17566 if (res == -1) { 17567 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17568 } 17569 if ((res != 0) && (bfmininc->fixed)) { 17570 FACET_RESTR_FIXED_ERR(fmininc) 17571 } 17572 } 17573 if (bfmaxinc) { 17574 /* minInclusive <= BASE maxInclusive */ 17575 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17576 if (res == -2) 17577 goto internal_error; 17578 if (res == 1) { 17579 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17580 } 17581 } 17582 if (bfminexc) { 17583 /* minInclusive > BASE minExclusive */ 17584 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17585 if (res == -2) 17586 goto internal_error; 17587 if (res != 1) 17588 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17589 } 17590 if (bfmaxexc) { 17591 /* minInclusive < BASE maxExclusive */ 17592 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17593 if (res == -2) 17594 goto internal_error; 17595 if (res != -1) 17596 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17597 } 17598 } 17599 if (ftotdig && bftotdig) { 17600 /* 17601 * SCC " totalDigits valid restriction" 17602 * totalDigits <= BASE totalDigits 17603 */ 17604 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17605 if (res == -2) 17606 goto internal_error; 17607 if (res == 1) 17608 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17609 -1, 1, 1); 17610 if ((res != 0) && (bftotdig->fixed)) { 17611 FACET_RESTR_FIXED_ERR(ftotdig) 17612 } 17613 } 17614 if (ffracdig && bffracdig) { 17615 /* 17616 * SCC "fractionDigits valid restriction" 17617 * fractionDigits <= BASE fractionDigits 17618 */ 17619 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17620 if (res == -2) 17621 goto internal_error; 17622 if (res == 1) 17623 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17624 -1, 1, 1); 17625 if ((res != 0) && (bffracdig->fixed)) { 17626 FACET_RESTR_FIXED_ERR(ffracdig) 17627 } 17628 } 17629 /* 17630 * SCC "fractionDigits less than or equal to totalDigits" 17631 */ 17632 if (! ftotdig) 17633 ftotdig = bftotdig; 17634 if (! ffracdig) 17635 ffracdig = bffracdig; 17636 if (ftotdig && ffracdig) { 17637 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17638 if (res == -2) 17639 goto internal_error; 17640 if (res == 1) 17641 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17642 -1, 1, 0); 17643 } 17644 /* 17645 * *Enumerations* won' be added here, since only the first set 17646 * of enumerations in the ancestor-or-self axis is used 17647 * for validation, plus we need to use the base type of those 17648 * enumerations for whitespace. 17649 * 17650 * *Patterns*: won't be add here, since they are ORed at 17651 * type level and ANDed at ancestor level. This will 17652 * happed during validation by walking the base axis 17653 * of the type. 17654 */ 17655 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17656 bfacet = cur->facet; 17657 /* 17658 * Special handling of enumerations and patterns. 17659 * TODO: hmm, they should not appear in the set, so remove this. 17660 */ 17661 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17662 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17663 continue; 17664 /* 17665 * Search for a duplicate facet in the current type. 17666 */ 17667 link = type->facetSet; 17668 /* err = 0; */ 17669 /* fixedErr = 0; */ 17670 while (link != NULL) { 17671 facet = link->facet; 17672 if (facet->type == bfacet->type) { 17673 switch (facet->type) { 17674 case XML_SCHEMA_FACET_WHITESPACE: 17675 /* 17676 * The whitespace must be stronger. 17677 */ 17678 if (facet->whitespace < bfacet->whitespace) { 17679 FACET_RESTR_ERR(facet, 17680 "The 'whitespace' value has to be equal to " 17681 "or stronger than the 'whitespace' value of " 17682 "the base type") 17683 } 17684 if ((bfacet->fixed) && 17685 (facet->whitespace != bfacet->whitespace)) { 17686 FACET_RESTR_FIXED_ERR(facet) 17687 } 17688 break; 17689 default: 17690 break; 17691 } 17692 /* Duplicate found. */ 17693 break; 17694 } 17695 link = link->next; 17696 } 17697 /* 17698 * If no duplicate was found: add the base types's facet 17699 * to the set. 17700 */ 17701 if (link == NULL) { 17702 link = (xmlSchemaFacetLinkPtr) 17703 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17704 if (link == NULL) { 17705 xmlSchemaPErrMemory(pctxt, 17706 "deriving facets, creating a facet link", NULL); 17707 return (-1); 17708 } 17709 link->facet = cur->facet; 17710 link->next = NULL; 17711 if (last == NULL) 17712 type->facetSet = link; 17713 else 17714 last->next = link; 17715 last = link; 17716 } 17717 17718 } 17719 17720 return (0); 17721 internal_error: 17722 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17723 "an error occured"); 17724 return (-1); 17725 } 17726 17727 static int 17728 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17729 xmlSchemaTypePtr type) 17730 { 17731 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17732 /* 17733 * The actual value is then formed by replacing any union type 17734 * definition in the �explicit members� with the members of their 17735 * {member type definitions}, in order. 17736 * 17737 * TODO: There's a bug entry at 17738 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17739 * which indicates that we'll keep the union types the future. 17740 */ 17741 link = type->memberTypes; 17742 while (link != NULL) { 17743 17744 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17745 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17746 17747 if (WXS_IS_UNION(link->type)) { 17748 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17749 if (subLink != NULL) { 17750 link->type = subLink->type; 17751 if (subLink->next != NULL) { 17752 lastLink = link->next; 17753 subLink = subLink->next; 17754 prevLink = link; 17755 while (subLink != NULL) { 17756 newLink = (xmlSchemaTypeLinkPtr) 17757 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17758 if (newLink == NULL) { 17759 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17760 NULL); 17761 return (-1); 17762 } 17763 newLink->type = subLink->type; 17764 prevLink->next = newLink; 17765 prevLink = newLink; 17766 newLink->next = lastLink; 17767 17768 subLink = subLink->next; 17769 } 17770 } 17771 } 17772 } 17773 link = link->next; 17774 } 17775 return (0); 17776 } 17777 17778 static void 17779 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17780 { 17781 int has = 0, needVal = 0, normVal = 0; 17782 17783 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17784 if (has) { 17785 needVal = (type->baseType->flags & 17786 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17787 normVal = (type->baseType->flags & 17788 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17789 } 17790 if (type->facets != NULL) { 17791 xmlSchemaFacetPtr fac; 17792 17793 for (fac = type->facets; fac != NULL; fac = fac->next) { 17794 switch (fac->type) { 17795 case XML_SCHEMA_FACET_WHITESPACE: 17796 break; 17797 case XML_SCHEMA_FACET_PATTERN: 17798 normVal = 1; 17799 has = 1; 17800 break; 17801 case XML_SCHEMA_FACET_ENUMERATION: 17802 needVal = 1; 17803 normVal = 1; 17804 has = 1; 17805 break; 17806 default: 17807 has = 1; 17808 break; 17809 } 17810 } 17811 } 17812 if (normVal) 17813 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17814 if (needVal) 17815 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17816 if (has) 17817 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17818 17819 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17820 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17821 /* 17822 * OPTIMIZE VAL TODO: Some facets need a computed value. 17823 */ 17824 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17825 (prim->builtInType != XML_SCHEMAS_STRING)) { 17826 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17827 } 17828 } 17829 } 17830 17831 static int 17832 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17833 { 17834 17835 17836 /* 17837 * Evaluate the whitespace-facet value. 17838 */ 17839 if (WXS_IS_LIST(type)) { 17840 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17841 return (0); 17842 } else if (WXS_IS_UNION(type)) 17843 return (0); 17844 17845 if (type->facetSet != NULL) { 17846 xmlSchemaFacetLinkPtr lin; 17847 17848 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17849 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17850 switch (lin->facet->whitespace) { 17851 case XML_SCHEMAS_FACET_PRESERVE: 17852 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17853 break; 17854 case XML_SCHEMAS_FACET_REPLACE: 17855 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17856 break; 17857 case XML_SCHEMAS_FACET_COLLAPSE: 17858 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17859 break; 17860 default: 17861 return (-1); 17862 } 17863 return (0); 17864 } 17865 } 17866 } 17867 /* 17868 * For all �atomic� datatypes other than string (and types �derived� 17869 * by �restriction� from it) the value of whiteSpace is fixed to 17870 * collapse 17871 */ 17872 { 17873 xmlSchemaTypePtr anc; 17874 17875 for (anc = type->baseType; anc != NULL && 17876 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17877 anc = anc->baseType) { 17878 17879 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17880 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17881 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17882 17883 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17884 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17885 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17886 17887 } else 17888 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17889 break; 17890 } 17891 } 17892 } 17893 return (0); 17894 } 17895 17896 static int 17897 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17898 xmlSchemaTypePtr type) 17899 { 17900 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17901 return(0); 17902 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17903 return(0); 17904 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17905 17906 if (WXS_IS_LIST(type)) { 17907 /* 17908 * Corresponds to <simpleType><list>... 17909 */ 17910 if (type->subtypes == NULL) { 17911 /* 17912 * This one is really needed, so get out. 17913 */ 17914 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17915 "list type has no item-type assigned"); 17916 return(-1); 17917 } 17918 } else if (WXS_IS_UNION(type)) { 17919 /* 17920 * Corresponds to <simpleType><union>... 17921 */ 17922 if (type->memberTypes == NULL) { 17923 /* 17924 * This one is really needed, so get out. 17925 */ 17926 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17927 "union type has no member-types assigned"); 17928 return(-1); 17929 } 17930 } else { 17931 /* 17932 * Corresponds to <simpleType><restriction>... 17933 */ 17934 if (type->baseType == NULL) { 17935 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17936 "type has no base-type assigned"); 17937 return(-1); 17938 } 17939 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17940 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17941 return(-1); 17942 /* 17943 * Variety 17944 * If the <restriction> alternative is chosen, then the 17945 * {variety} of the {base type definition}. 17946 */ 17947 if (WXS_IS_ATOMIC(type->baseType)) 17948 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17949 else if (WXS_IS_LIST(type->baseType)) { 17950 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17951 /* 17952 * Inherit the itemType. 17953 */ 17954 type->subtypes = type->baseType->subtypes; 17955 } else if (WXS_IS_UNION(type->baseType)) { 17956 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 17957 /* 17958 * NOTE that we won't assign the memberTypes of the base, 17959 * since this will make trouble when freeing them; we will 17960 * use a lookup function to access them instead. 17961 */ 17962 } 17963 } 17964 return(0); 17965 } 17966 17967 #ifdef DEBUG_TYPE 17968 static void 17969 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 17970 xmlSchemaTypePtr type) 17971 { 17972 if (type->node != NULL) { 17973 xmlGenericError(xmlGenericErrorContext, 17974 "Type of %s : %s:%d :", name, 17975 type->node->doc->URL, 17976 xmlGetLineNo(type->node)); 17977 } else { 17978 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 17979 } 17980 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 17981 switch (type->contentType) { 17982 case XML_SCHEMA_CONTENT_SIMPLE: 17983 xmlGenericError(xmlGenericErrorContext, "simple\n"); 17984 break; 17985 case XML_SCHEMA_CONTENT_ELEMENTS: 17986 xmlGenericError(xmlGenericErrorContext, "elements\n"); 17987 break; 17988 case XML_SCHEMA_CONTENT_UNKNOWN: 17989 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 17990 break; 17991 case XML_SCHEMA_CONTENT_EMPTY: 17992 xmlGenericError(xmlGenericErrorContext, "empty\n"); 17993 break; 17994 case XML_SCHEMA_CONTENT_MIXED: 17995 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 17996 type->subtypes)) 17997 xmlGenericError(xmlGenericErrorContext, 17998 "mixed as emptiable particle\n"); 17999 else 18000 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18001 break; 18002 /* Removed, since not used. */ 18003 /* 18004 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18005 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18006 break; 18007 */ 18008 case XML_SCHEMA_CONTENT_BASIC: 18009 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18010 break; 18011 default: 18012 xmlGenericError(xmlGenericErrorContext, 18013 "not registered !!!\n"); 18014 break; 18015 } 18016 } 18017 } 18018 #endif 18019 18020 /* 18021 * 3.14.6 Constraints on Simple Type Definition Schema Components 18022 */ 18023 static int 18024 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18025 xmlSchemaTypePtr type) 18026 { 18027 int res, olderrs = pctxt->nberrors; 18028 18029 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18030 return(-1); 18031 18032 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18033 return(0); 18034 18035 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18036 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18037 18038 if (type->baseType == NULL) { 18039 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18040 "missing baseType"); 18041 goto exit_failure; 18042 } 18043 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18044 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18045 /* 18046 * If a member type of a union is a union itself, we need to substitute 18047 * that member type for its member types. 18048 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18049 * types in WXS 1.1. 18050 */ 18051 if ((type->memberTypes != NULL) && 18052 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18053 return(-1); 18054 /* 18055 * SPEC src-simple-type 1 18056 * "The corresponding simple type definition, if any, must satisfy 18057 * the conditions set out in Constraints on Simple Type Definition 18058 * Schema Components (�3.14.6)." 18059 */ 18060 /* 18061 * Schema Component Constraint: Simple Type Definition Properties Correct 18062 * (st-props-correct) 18063 */ 18064 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18065 HFAILURE HERROR 18066 /* 18067 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18068 * (cos-st-restricts) 18069 */ 18070 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18071 HFAILURE HERROR 18072 /* 18073 * TODO: Removed the error report, since it got annoying to get an 18074 * extra error report, if anything failed until now. 18075 * Enable this if needed. 18076 * 18077 * xmlSchemaPErr(ctxt, type->node, 18078 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18079 * "Simple type '%s' does not satisfy the constraints " 18080 * "on simple type definitions.\n", 18081 * type->name, NULL); 18082 */ 18083 /* 18084 * Schema Component Constraint: Simple Type Restriction (Facets) 18085 * (st-restrict-facets) 18086 */ 18087 res = xmlSchemaCheckFacetValues(type, pctxt); 18088 HFAILURE HERROR 18089 if ((type->facetSet != NULL) || 18090 (type->baseType->facetSet != NULL)) { 18091 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18092 HFAILURE HERROR 18093 } 18094 /* 18095 * Whitespace value. 18096 */ 18097 res = xmlSchemaTypeFixupWhitespace(type); 18098 HFAILURE HERROR 18099 xmlSchemaTypeFixupOptimFacets(type); 18100 18101 exit_error: 18102 #ifdef DEBUG_TYPE 18103 xmlSchemaDebugFixedType(pctxt, type); 18104 #endif 18105 if (olderrs != pctxt->nberrors) 18106 return(pctxt->err); 18107 return(0); 18108 18109 exit_failure: 18110 #ifdef DEBUG_TYPE 18111 xmlSchemaDebugFixedType(pctxt, type); 18112 #endif 18113 return(-1); 18114 } 18115 18116 static int 18117 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18118 xmlSchemaTypePtr type) 18119 { 18120 int res = 0, olderrs = pctxt->nberrors; 18121 xmlSchemaTypePtr baseType = type->baseType; 18122 18123 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18124 return(0); 18125 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18126 if (baseType == NULL) { 18127 PERROR_INT("xmlSchemaFixupComplexType", 18128 "missing baseType"); 18129 goto exit_failure; 18130 } 18131 /* 18132 * Fixup the base type. 18133 */ 18134 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18135 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18136 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18137 /* 18138 * Skip fixup if the base type is invalid. 18139 * TODO: Generate a warning! 18140 */ 18141 return(0); 18142 } 18143 /* 18144 * This basically checks if the base type can be derived. 18145 */ 18146 res = xmlSchemaCheckSRCCT(pctxt, type); 18147 HFAILURE HERROR 18148 /* 18149 * Fixup the content type. 18150 */ 18151 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18152 /* 18153 * Corresponds to <complexType><simpleContent>... 18154 */ 18155 if ((WXS_IS_COMPLEX(baseType)) && 18156 (baseType->contentTypeDef != NULL) && 18157 (WXS_IS_RESTRICTION(type))) { 18158 xmlSchemaTypePtr contentBase, content; 18159 #ifdef ENABLE_NAMED_LOCALS 18160 char buf[30]; 18161 const xmlChar *tmpname; 18162 #endif 18163 /* 18164 * SPEC (1) If <restriction> + base type is <complexType>, 18165 * "whose own {content type} is a simple type..." 18166 */ 18167 if (type->contentTypeDef != NULL) { 18168 /* 18169 * SPEC (1.1) "the simple type definition corresponding to the 18170 * <simpleType> among the [children] of <restriction> if there 18171 * is one;" 18172 * Note that this "<simpleType> among the [children]" was put 18173 * into ->contentTypeDef during parsing. 18174 */ 18175 contentBase = type->contentTypeDef; 18176 type->contentTypeDef = NULL; 18177 } else { 18178 /* 18179 * (1.2) "...otherwise (<restriction> has no <simpleType> 18180 * among its [children]), the simple type definition which 18181 * is the {content type} of the ... base type." 18182 */ 18183 contentBase = baseType->contentTypeDef; 18184 } 18185 /* 18186 * SPEC 18187 * "... a simple type definition which restricts the simple 18188 * type definition identified in clause 1.1 or clause 1.2 18189 * with a set of facet components" 18190 * 18191 * Create the anonymous simple type, which will be the content 18192 * type of the complex type. 18193 */ 18194 #ifdef ENABLE_NAMED_LOCALS 18195 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18196 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18197 content = xmlSchemaAddType(pctxt, pctxt->schema, 18198 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18199 type->node, 0); 18200 #else 18201 content = xmlSchemaAddType(pctxt, pctxt->schema, 18202 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18203 type->node, 0); 18204 #endif 18205 if (content == NULL) 18206 goto exit_failure; 18207 /* 18208 * We will use the same node as for the <complexType> 18209 * to have it somehow anchored in the schema doc. 18210 */ 18211 content->type = XML_SCHEMA_TYPE_SIMPLE; 18212 content->baseType = contentBase; 18213 /* 18214 * Move the facets, previously anchored on the 18215 * complexType during parsing. 18216 */ 18217 content->facets = type->facets; 18218 type->facets = NULL; 18219 content->facetSet = type->facetSet; 18220 type->facetSet = NULL; 18221 18222 type->contentTypeDef = content; 18223 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18224 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18225 /* 18226 * Fixup the newly created type. We don't need to check 18227 * for circularity here. 18228 */ 18229 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18230 HFAILURE HERROR 18231 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18232 HFAILURE HERROR 18233 18234 } else if ((WXS_IS_COMPLEX(baseType)) && 18235 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18236 (WXS_IS_RESTRICTION(type))) { 18237 /* 18238 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18239 * an emptiable particle, then a simple type definition which 18240 * restricts the <restriction>'s <simpleType> child. 18241 */ 18242 if ((type->contentTypeDef == NULL) || 18243 (type->contentTypeDef->baseType == NULL)) { 18244 /* 18245 * TODO: Check if this ever happens. 18246 */ 18247 xmlSchemaPCustomErr(pctxt, 18248 XML_SCHEMAP_INTERNAL, 18249 WXS_BASIC_CAST type, NULL, 18250 "Internal error: xmlSchemaTypeFixup, " 18251 "complex type '%s': the <simpleContent><restriction> " 18252 "is missing a <simpleType> child, but was not catched " 18253 "by xmlSchemaCheckSRCCT()", type->name); 18254 goto exit_failure; 18255 } 18256 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18257 /* 18258 * SPEC (3) If <extension> + base is <complexType> with 18259 * <simpleType> content, "...then the {content type} of that 18260 * complex type definition" 18261 */ 18262 if (baseType->contentTypeDef == NULL) { 18263 /* 18264 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18265 * should have catched this already. 18266 */ 18267 xmlSchemaPCustomErr(pctxt, 18268 XML_SCHEMAP_INTERNAL, 18269 WXS_BASIC_CAST type, NULL, 18270 "Internal error: xmlSchemaTypeFixup, " 18271 "complex type '%s': the <extension>ed base type is " 18272 "a complex type with no simple content type", 18273 type->name); 18274 goto exit_failure; 18275 } 18276 type->contentTypeDef = baseType->contentTypeDef; 18277 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18278 /* 18279 * SPEC (4) <extension> + base is <simpleType> 18280 * "... then that simple type definition" 18281 */ 18282 type->contentTypeDef = baseType; 18283 } else { 18284 /* 18285 * TODO: Check if this ever happens. 18286 */ 18287 xmlSchemaPCustomErr(pctxt, 18288 XML_SCHEMAP_INTERNAL, 18289 WXS_BASIC_CAST type, NULL, 18290 "Internal error: xmlSchemaTypeFixup, " 18291 "complex type '%s' with <simpleContent>: unhandled " 18292 "derivation case", type->name); 18293 goto exit_failure; 18294 } 18295 } else { 18296 int dummySequence = 0; 18297 xmlSchemaParticlePtr particle = 18298 (xmlSchemaParticlePtr) type->subtypes; 18299 /* 18300 * Corresponds to <complexType><complexContent>... 18301 * 18302 * NOTE that the effective mixed was already set during parsing of 18303 * <complexType> and <complexContent>; its flag value is 18304 * XML_SCHEMAS_TYPE_MIXED. 18305 * 18306 * Compute the "effective content": 18307 * (2.1.1) + (2.1.2) + (2.1.3) 18308 */ 18309 if ((particle == NULL) || 18310 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18311 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18312 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18313 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18314 (particle->minOccurs == 0))) && 18315 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18316 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18317 /* 18318 * SPEC (2.1.4) "If the �effective mixed� is true, then 18319 * a particle whose properties are as follows:..." 18320 * 18321 * Empty sequence model group with 18322 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18323 * NOTE that we sill assign it the <complexType> node to 18324 * somehow anchor it in the doc. 18325 */ 18326 if ((particle == NULL) || 18327 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18328 /* 18329 * Create the particle. 18330 */ 18331 particle = xmlSchemaAddParticle(pctxt, 18332 type->node, 1, 1); 18333 if (particle == NULL) 18334 goto exit_failure; 18335 /* 18336 * Create the model group. 18337 */ /* URGENT TODO: avoid adding to pending items. */ 18338 particle->children = (xmlSchemaTreeItemPtr) 18339 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18340 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18341 if (particle->children == NULL) 18342 goto exit_failure; 18343 18344 type->subtypes = (xmlSchemaTypePtr) particle; 18345 } 18346 dummySequence = 1; 18347 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18348 } else { 18349 /* 18350 * SPEC (2.1.5) "otherwise empty" 18351 */ 18352 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18353 } 18354 } else { 18355 /* 18356 * SPEC (2.2) "otherwise the particle corresponding to the 18357 * <all>, <choice>, <group> or <sequence> among the 18358 * [children]." 18359 */ 18360 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18361 } 18362 /* 18363 * Compute the "content type". 18364 */ 18365 if (WXS_IS_RESTRICTION(type)) { 18366 /* 18367 * SPEC (3.1) "If <restriction>..." 18368 * (3.1.1) + (3.1.2) */ 18369 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18370 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18371 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18372 } 18373 } else { 18374 /* 18375 * SPEC (3.2) "If <extension>..." 18376 */ 18377 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18378 /* 18379 * SPEC (3.2.1) 18380 * "If the �effective content� is empty, then the 18381 * {content type} of the [...] base ..." 18382 */ 18383 type->contentType = baseType->contentType; 18384 type->subtypes = baseType->subtypes; 18385 /* 18386 * Fixes bug #347316: 18387 * This is the case when the base type has a simple 18388 * type definition as content. 18389 */ 18390 type->contentTypeDef = baseType->contentTypeDef; 18391 /* 18392 * NOTE that the effective mixed is ignored here. 18393 */ 18394 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18395 /* 18396 * SPEC (3.2.2) 18397 */ 18398 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18399 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18400 } else { 18401 /* 18402 * SPEC (3.2.3) 18403 */ 18404 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18405 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18406 /* 18407 * "A model group whose {compositor} is sequence and whose 18408 * {particles} are..." 18409 */ 18410 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18411 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18412 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18413 XML_SCHEMA_TYPE_ALL)) 18414 { 18415 /* 18416 * SPEC cos-all-limited (1) 18417 */ 18418 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18419 /* TODO: error code */ 18420 XML_SCHEMAP_COS_ALL_LIMITED, 18421 WXS_ITEM_NODE(type), NULL, 18422 "The type has an 'all' model group in its " 18423 "{content type} and thus cannot be derived from " 18424 "a non-empty type, since this would produce a " 18425 "'sequence' model group containing the 'all' " 18426 "model group; 'all' model groups are not " 18427 "allowed to appear inside other model groups", 18428 NULL, NULL); 18429 18430 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18431 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18432 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18433 XML_SCHEMA_TYPE_ALL)) 18434 { 18435 /* 18436 * SPEC cos-all-limited (1) 18437 */ 18438 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18439 /* TODO: error code */ 18440 XML_SCHEMAP_COS_ALL_LIMITED, 18441 WXS_ITEM_NODE(type), NULL, 18442 "A type cannot be derived by extension from a type " 18443 "which has an 'all' model group in its " 18444 "{content type}, since this would produce a " 18445 "'sequence' model group containing the 'all' " 18446 "model group; 'all' model groups are not " 18447 "allowed to appear inside other model groups", 18448 NULL, NULL); 18449 18450 } else if (! dummySequence) { 18451 xmlSchemaTreeItemPtr effectiveContent = 18452 (xmlSchemaTreeItemPtr) type->subtypes; 18453 /* 18454 * Create the particle. 18455 */ 18456 particle = xmlSchemaAddParticle(pctxt, 18457 type->node, 1, 1); 18458 if (particle == NULL) 18459 goto exit_failure; 18460 /* 18461 * Create the "sequence" model group. 18462 */ 18463 particle->children = (xmlSchemaTreeItemPtr) 18464 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18465 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18466 if (particle->children == NULL) 18467 goto exit_failure; 18468 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18469 /* 18470 * SPEC "the particle of the {content type} of 18471 * the ... base ..." 18472 * Create a duplicate of the base type's particle 18473 * and assign its "term" to it. 18474 */ 18475 particle->children->children = 18476 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18477 type->node, 18478 ((xmlSchemaParticlePtr) type->subtypes)->minOccurs, 18479 ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs); 18480 if (particle->children->children == NULL) 18481 goto exit_failure; 18482 particle = (xmlSchemaParticlePtr) 18483 particle->children->children; 18484 particle->children = 18485 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18486 /* 18487 * SPEC "followed by the �effective content�." 18488 */ 18489 particle->next = effectiveContent; 18490 /* 18491 * This all will result in: 18492 * new-particle 18493 * --> new-sequence( 18494 * new-particle 18495 * --> base-model, 18496 * this-particle 18497 * --> this-model 18498 * ) 18499 */ 18500 } else { 18501 /* 18502 * This is the case when there is already an empty 18503 * <sequence> with minOccurs==maxOccurs==1. 18504 * Just add the base types's content type. 18505 * NOTE that, although we miss to add an intermediate 18506 * <sequence>, this should produce no difference to 18507 * neither the regex compilation of the content model, 18508 * nor to the complex type contraints. 18509 */ 18510 particle->children->children = 18511 (xmlSchemaTreeItemPtr) baseType->subtypes; 18512 } 18513 } 18514 } 18515 } 18516 /* 18517 * Now fixup attribute uses: 18518 * - expand attr. group references 18519 * - intersect attribute wildcards 18520 * - inherit attribute uses of the base type 18521 * - inherit or union attr. wildcards if extending 18522 * - apply attr. use prohibitions if restricting 18523 */ 18524 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18525 HFAILURE HERROR 18526 /* 18527 * Apply the complex type component constraints; this will not 18528 * check attributes, since this is done in 18529 * xmlSchemaFixupTypeAttributeUses(). 18530 */ 18531 res = xmlSchemaCheckCTComponent(pctxt, type); 18532 HFAILURE HERROR 18533 18534 #ifdef DEBUG_TYPE 18535 xmlSchemaDebugFixedType(pctxt, type); 18536 #endif 18537 if (olderrs != pctxt->nberrors) 18538 return(pctxt->err); 18539 else 18540 return(0); 18541 18542 exit_error: 18543 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18544 #ifdef DEBUG_TYPE 18545 xmlSchemaDebugFixedType(pctxt, type); 18546 #endif 18547 return(pctxt->err); 18548 18549 exit_failure: 18550 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18551 #ifdef DEBUG_TYPE 18552 xmlSchemaDebugFixedType(pctxt, type); 18553 #endif 18554 return(-1); 18555 } 18556 18557 18566 static int 18567 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18568 xmlSchemaAbstractCtxtPtr actxt) 18569 { 18570 if (type == NULL) 18571 return(0); 18572 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18573 AERROR_INT("xmlSchemaTypeFixup", 18574 "this function needs a parser context"); 18575 return(-1); 18576 } 18577 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18578 return(0); 18579 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18580 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18581 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18582 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18583 return(0); 18584 } 18585 18598 int 18599 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18600 xmlSchemaTypePtr typeDecl, 18601 xmlSchemaParserCtxtPtr pctxt, 18602 const xmlChar * name ATTRIBUTE_UNUSED) 18603 { 18604 int ret = 0, ctxtGiven; 18605 18606 if ((facet == NULL) || (typeDecl == NULL)) 18607 return(-1); 18608 /* 18609 * TODO: will the parser context be given if used from 18610 * the relaxNG module? 18611 */ 18612 if (pctxt == NULL) 18613 ctxtGiven = 0; 18614 else 18615 ctxtGiven = 1; 18616 18617 switch (facet->type) { 18618 case XML_SCHEMA_FACET_MININCLUSIVE: 18619 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18620 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18621 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18622 case XML_SCHEMA_FACET_ENUMERATION: { 18623 /* 18624 * Okay we need to validate the value 18625 * at that point. 18626 */ 18627 xmlSchemaTypePtr base; 18628 18629 /* 4.3.5.5 Constraints on enumeration Schema Components 18630 * Schema Component Constraint: enumeration valid restriction 18631 * It is an �error� if any member of {value} is not in the 18632 * �value space� of {base type definition}. 18633 * 18634 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18635 * The value �must� be in the 18636 * �value space� of the �base type�. 18637 */ 18638 /* 18639 * This function is intended to deliver a compiled value 18640 * on the facet. In this implementation of XML Schemata the 18641 * type holding a facet, won't be a built-in type. 18642 * Thus to ensure that other API 18643 * calls (relaxng) do work, if the given type is a built-in 18644 * type, we will assume that the given built-in type *is 18645 * already* the base type. 18646 */ 18647 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18648 base = typeDecl->baseType; 18649 if (base == NULL) { 18650 PERROR_INT("xmlSchemaCheckFacet", 18651 "a type user derived type has no base type"); 18652 return (-1); 18653 } 18654 } else 18655 base = typeDecl; 18656 18657 if (! ctxtGiven) { 18658 /* 18659 * A context is needed if called from RelaxNG. 18660 */ 18661 pctxt = xmlSchemaNewParserCtxt("*"); 18662 if (pctxt == NULL) 18663 return (-1); 18664 } 18665 /* 18666 * NOTE: This call does not check the content nodes, 18667 * since they are not available: 18668 * facet->node is just the node holding the facet 18669 * definition, *not* the attribute holding the *value* 18670 * of the facet. 18671 */ 18672 ret = xmlSchemaVCheckCVCSimpleType( 18673 ACTXT_CAST pctxt, facet->node, base, 18674 facet->value, &(facet->val), 1, 1, 0); 18675 if (ret != 0) { 18676 if (ret < 0) { 18677 /* No error message for RelaxNG. */ 18678 if (ctxtGiven) { 18679 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18680 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18681 "Internal error: xmlSchemaCheckFacet, " 18682 "failed to validate the value '%s' of the " 18683 "facet '%s' against the base type", 18684 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18685 } 18686 goto internal_error; 18687 } 18688 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18689 /* No error message for RelaxNG. */ 18690 if (ctxtGiven) { 18691 xmlChar *str = NULL; 18692 18693 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18694 ret, facet->node, WXS_BASIC_CAST facet, 18695 "The value '%s' of the facet does not validate " 18696 "against the base type '%s'", 18697 facet->value, 18698 xmlSchemaFormatQName(&str, 18699 base->targetNamespace, base->name)); 18700 FREE_AND_NULL(str); 18701 } 18702 goto exit; 18703 } else if (facet->val == NULL) { 18704 if (ctxtGiven) { 18705 PERROR_INT("xmlSchemaCheckFacet", 18706 "value was not computed"); 18707 } 18708 TODO 18709 } 18710 break; 18711 } 18712 case XML_SCHEMA_FACET_PATTERN: 18713 facet->regexp = xmlRegexpCompile(facet->value); 18714 if (facet->regexp == NULL) { 18715 ret = XML_SCHEMAP_REGEXP_INVALID; 18716 /* No error message for RelaxNG. */ 18717 if (ctxtGiven) { 18718 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18719 ret, facet->node, WXS_BASIC_CAST typeDecl, 18720 "The value '%s' of the facet 'pattern' is not a " 18721 "valid regular expression", 18722 facet->value, NULL); 18723 } 18724 } 18725 break; 18726 case XML_SCHEMA_FACET_TOTALDIGITS: 18727 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18728 case XML_SCHEMA_FACET_LENGTH: 18729 case XML_SCHEMA_FACET_MAXLENGTH: 18730 case XML_SCHEMA_FACET_MINLENGTH: 18731 18732 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18733 ret = xmlSchemaValidatePredefinedType( 18734 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18735 facet->value, &(facet->val)); 18736 } else { 18737 ret = xmlSchemaValidatePredefinedType( 18738 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18739 facet->value, &(facet->val)); 18740 } 18741 if (ret != 0) { 18742 if (ret < 0) { 18743 /* No error message for RelaxNG. */ 18744 if (ctxtGiven) { 18745 PERROR_INT("xmlSchemaCheckFacet", 18746 "validating facet value"); 18747 } 18748 goto internal_error; 18749 } 18750 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18751 /* No error message for RelaxNG. */ 18752 if (ctxtGiven) { 18753 /* error code */ 18754 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18755 ret, facet->node, WXS_BASIC_CAST typeDecl, 18756 "The value '%s' of the facet '%s' is not a valid '%s'", 18757 facet->value, 18758 xmlSchemaFacetTypeToString(facet->type), 18759 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18760 BAD_CAST "nonNegativeInteger" : 18761 BAD_CAST "positiveInteger", 18762 NULL); 18763 } 18764 } 18765 break; 18766 18767 case XML_SCHEMA_FACET_WHITESPACE:{ 18768 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18769 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18770 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18771 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18772 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18773 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18774 } else { 18775 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18776 /* No error message for RelaxNG. */ 18777 if (ctxtGiven) { 18778 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18779 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18780 ret, facet->node, WXS_BASIC_CAST typeDecl, 18781 "The value '%s' of the facet 'whitespace' is not " 18782 "valid", facet->value, NULL); 18783 } 18784 } 18785 } 18786 default: 18787 break; 18788 } 18789 exit: 18790 if ((! ctxtGiven) && (pctxt != NULL)) 18791 xmlSchemaFreeParserCtxt(pctxt); 18792 return (ret); 18793 internal_error: 18794 if ((! ctxtGiven) && (pctxt != NULL)) 18795 xmlSchemaFreeParserCtxt(pctxt); 18796 return (-1); 18797 } 18798 18806 static int 18807 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18808 xmlSchemaParserCtxtPtr pctxt) 18809 { 18810 int res, olderrs = pctxt->nberrors; 18811 const xmlChar *name = typeDecl->name; 18812 /* 18813 * NOTE: It is intended to use the facets list, instead 18814 * of facetSet. 18815 */ 18816 if (typeDecl->facets != NULL) { 18817 xmlSchemaFacetPtr facet = typeDecl->facets; 18818 18819 /* 18820 * Temporarily assign the "schema" to the validation context 18821 * of the parser context. This is needed for NOTATION validation. 18822 */ 18823 if (pctxt->vctxt == NULL) { 18824 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18825 return(-1); 18826 } 18827 pctxt->vctxt->schema = pctxt->schema; 18828 while (facet != NULL) { 18829 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18830 HFAILURE 18831 facet = facet->next; 18832 } 18833 pctxt->vctxt->schema = NULL; 18834 } 18835 if (olderrs != pctxt->nberrors) 18836 return(pctxt->err); 18837 return(0); 18838 exit_failure: 18839 return(-1); 18840 } 18841 18854 static xmlSchemaTreeItemPtr 18855 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18856 xmlSchemaTreeItemPtr particle) 18857 { 18858 xmlSchemaTreeItemPtr circ = NULL; 18859 xmlSchemaTreeItemPtr term; 18860 xmlSchemaModelGroupDefPtr gdef; 18861 18862 for (; particle != NULL; particle = particle->next) { 18863 term = particle->children; 18864 if (term == NULL) 18865 continue; 18866 switch (term->type) { 18867 case XML_SCHEMA_TYPE_GROUP: 18868 gdef = (xmlSchemaModelGroupDefPtr) term; 18869 if (gdef == groupDef) 18870 return (particle); 18871 /* 18872 * Mark this model group definition to avoid infinite 18873 * recursion on circular references not yet examined. 18874 */ 18875 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18876 continue; 18877 if (gdef->children != NULL) { 18878 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18879 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18880 gdef->children->children); 18881 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18882 if (circ != NULL) 18883 return (circ); 18884 } 18885 break; 18886 case XML_SCHEMA_TYPE_SEQUENCE: 18887 case XML_SCHEMA_TYPE_CHOICE: 18888 case XML_SCHEMA_TYPE_ALL: 18889 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18890 if (circ != NULL) 18891 return (circ); 18892 break; 18893 default: 18894 break; 18895 } 18896 } 18897 return (NULL); 18898 } 18899 18908 static void 18909 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18910 xmlSchemaParserCtxtPtr ctxt) 18911 { 18912 /* 18913 * Schema Component Constraint: Model Group Correct 18914 * 2 Circular groups are disallowed. That is, within the {particles} 18915 * of a group there must not be at any depth a particle whose {term} 18916 * is the group itself. 18917 */ 18918 if ((item == NULL) || 18919 (item->type != XML_SCHEMA_TYPE_GROUP) || 18920 (item->children == NULL)) 18921 return; 18922 { 18923 xmlSchemaTreeItemPtr circ; 18924 18925 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18926 if (circ != NULL) { 18927 xmlChar *str = NULL; 18928 /* 18929 * TODO: The error report is not adequate: this constraint 18930 * is defined for model groups but not definitions, but since 18931 * there cannot be any circular model groups without a model group 18932 * definition (if not using a construction API), we check those 18933 * defintions only. 18934 */ 18935 xmlSchemaPCustomErr(ctxt, 18936 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18937 NULL, WXS_ITEM_NODE(circ), 18938 "Circular reference to the model group definition '%s' " 18939 "defined", xmlSchemaFormatQName(&str, 18940 item->targetNamespace, item->name)); 18941 FREE_AND_NULL(str) 18942 /* 18943 * NOTE: We will cut the reference to avoid further 18944 * confusion of the processor. This is a fatal error. 18945 */ 18946 circ->children = NULL; 18947 } 18948 } 18949 } 18950 18965 static void 18966 xmlSchemaModelGroupToModelGroupDefFixup( 18967 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 18968 xmlSchemaModelGroupPtr mg) 18969 { 18970 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 18971 18972 while (particle != NULL) { 18973 if ((WXS_PARTICLE_TERM(particle) == NULL) || 18974 ((WXS_PARTICLE_TERM(particle))->type != 18975 XML_SCHEMA_TYPE_GROUP)) 18976 { 18977 particle = WXS_PTC_CAST particle->next; 18978 continue; 18979 } 18980 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 18981 /* 18982 * TODO: Remove the particle. 18983 */ 18984 WXS_PARTICLE_TERM(particle) = NULL; 18985 particle = WXS_PTC_CAST particle->next; 18986 continue; 18987 } 18988 /* 18989 * Assign the model group to the {term} of the particle. 18990 */ 18991 WXS_PARTICLE_TERM(particle) = 18992 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 18993 18994 particle = WXS_PTC_CAST particle->next; 18995 } 18996 } 18997 19008 static xmlSchemaQNameRefPtr 19009 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19010 xmlSchemaItemListPtr list) 19011 { 19012 xmlSchemaAttributeGroupPtr gr; 19013 xmlSchemaQNameRefPtr ref, circ; 19014 int i; 19015 /* 19016 * We will search for an attribute group reference which 19017 * references the context attribute group. 19018 */ 19019 for (i = 0; i < list->nbItems; i++) { 19020 ref = list->items[i]; 19021 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19022 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19023 (ref->item != NULL)) 19024 { 19025 gr = WXS_ATTR_GROUP_CAST ref->item; 19026 if (gr == ctxtGr) 19027 return(ref); 19028 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19029 continue; 19030 /* 19031 * Mark as visited to avoid infinite recursion on 19032 * circular references not yet examined. 19033 */ 19034 if ((gr->attrUses) && 19035 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19036 { 19037 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19038 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19039 (xmlSchemaItemListPtr) gr->attrUses); 19040 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19041 if (circ != NULL) 19042 return (circ); 19043 } 19044 19045 } 19046 } 19047 return (NULL); 19048 } 19049 19058 static int 19059 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19060 xmlSchemaParserCtxtPtr ctxt) 19061 { 19062 /* 19063 * Schema Representation Constraint: 19064 * Attribute Group Definition Representation OK 19065 * 3 Circular group reference is disallowed outside <redefine>. 19066 * That is, unless this element information item's parent is 19067 * <redefine>, then among the [children], if any, there must 19068 * not be an <attributeGroup> with ref [attribute] which resolves 19069 * to the component corresponding to this <attributeGroup>. Indirect 19070 * circularity is also ruled out. That is, when QName resolution 19071 * (Schema Document) (�3.15.3) is applied to a �QName� arising from 19072 * any <attributeGroup>s with a ref [attribute] among the [children], 19073 * it must not be the case that a �QName� is encountered at any depth 19074 * which resolves to the component corresponding to this <attributeGroup>. 19075 */ 19076 if (attrGr->attrUses == NULL) 19077 return(0); 19078 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19079 return(0); 19080 else { 19081 xmlSchemaQNameRefPtr circ; 19082 19083 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19084 (xmlSchemaItemListPtr) attrGr->attrUses); 19085 if (circ != NULL) { 19086 xmlChar *str = NULL; 19087 /* 19088 * TODO: Report the referenced attr group as QName. 19089 */ 19090 xmlSchemaPCustomErr(ctxt, 19091 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19092 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19093 "Circular reference to the attribute group '%s' " 19094 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19095 FREE_AND_NULL(str); 19096 /* 19097 * NOTE: We will cut the reference to avoid further 19098 * confusion of the processor. 19099 * BADSPEC TODO: The spec should define how to process in this case. 19100 */ 19101 circ->item = NULL; 19102 return(ctxt->err); 19103 } 19104 } 19105 return(0); 19106 } 19107 19108 static int 19109 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19110 xmlSchemaAttributeGroupPtr attrGr); 19111 19126 static int 19127 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19128 xmlSchemaBasicItemPtr item, 19129 xmlSchemaWildcardPtr *completeWild, 19130 xmlSchemaItemListPtr list, 19131 xmlSchemaItemListPtr prohibs) 19132 { 19133 xmlSchemaAttributeGroupPtr gr; 19134 xmlSchemaAttributeUsePtr use; 19135 xmlSchemaItemListPtr sublist; 19136 int i, j; 19137 int created = (*completeWild == NULL) ? 0 : 1; 19138 19139 if (prohibs) 19140 prohibs->nbItems = 0; 19141 19142 for (i = 0; i < list->nbItems; i++) { 19143 use = list->items[i]; 19144 19145 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19146 if (prohibs == NULL) { 19147 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19148 "unexpected attr prohibition found"); 19149 return(-1); 19150 } 19151 /* 19152 * Remove from attribute uses. 19153 */ 19154 if (xmlSchemaItemListRemove(list, i) == -1) 19155 return(-1); 19156 i--; 19157 /* 19158 * Note that duplicate prohibitions were already 19159 * handled at parsing time. 19160 */ 19161 /* 19162 * Add to list of prohibitions. 19163 */ 19164 xmlSchemaItemListAddSize(prohibs, 2, use); 19165 continue; 19166 } 19167 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19168 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19169 { 19170 if ((WXS_QNAME_CAST use)->item == NULL) 19171 return(-1); 19172 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19173 /* 19174 * Expand the referenced attr. group. 19175 * TODO: remove this, this is done in a previous step, so 19176 * already done here. 19177 */ 19178 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19179 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19180 return(-1); 19181 } 19182 /* 19183 * Build the 'complete' wildcard; i.e. intersect multiple 19184 * wildcards. 19185 */ 19186 if (gr->attributeWildcard != NULL) { 19187 if (*completeWild == NULL) { 19188 *completeWild = gr->attributeWildcard; 19189 } else { 19190 if (! created) { 19191 xmlSchemaWildcardPtr tmpWild; 19192 19193 /* 19194 * Copy the first encountered wildcard as context, 19195 * except for the annotation. 19196 * 19197 * Although the complete wildcard might not correspond 19198 * to any node in the schema, we will anchor it on 19199 * the node of the owner component. 19200 */ 19201 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19202 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19203 WXS_ITEM_NODE(item)); 19204 if (tmpWild == NULL) 19205 return(-1); 19206 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19207 tmpWild, *completeWild) == -1) 19208 return (-1); 19209 tmpWild->processContents = (*completeWild)->processContents; 19210 *completeWild = tmpWild; 19211 created = 1; 19212 } 19213 19214 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19215 gr->attributeWildcard) == -1) 19216 return(-1); 19217 } 19218 } 19219 /* 19220 * Just remove the reference if the referenced group does not 19221 * contain any attribute uses. 19222 */ 19223 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19224 if ((sublist == NULL) || sublist->nbItems == 0) { 19225 if (xmlSchemaItemListRemove(list, i) == -1) 19226 return(-1); 19227 i--; 19228 continue; 19229 } 19230 /* 19231 * Add the attribute uses. 19232 */ 19233 list->items[i] = sublist->items[0]; 19234 if (sublist->nbItems != 1) { 19235 for (j = 1; j < sublist->nbItems; j++) { 19236 i++; 19237 if (xmlSchemaItemListInsert(list, 19238 sublist->items[j], i) == -1) 19239 return(-1); 19240 } 19241 } 19242 } 19243 19244 } 19245 /* 19246 * Handle pointless prohibitions of declared attributes. 19247 */ 19248 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19249 xmlSchemaAttributeUseProhibPtr prohib; 19250 19251 for (i = prohibs->nbItems -1; i >= 0; i--) { 19252 prohib = prohibs->items[i]; 19253 for (j = 0; j < list->nbItems; j++) { 19254 use = list->items[j]; 19255 19256 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19257 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19258 { 19259 xmlChar *str = NULL; 19260 19261 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19262 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19263 prohib->node, NULL, 19264 "Skipping pointless attribute use prohibition " 19265 "'%s', since a corresponding attribute use " 19266 "exists already in the type definition", 19267 xmlSchemaFormatQName(&str, 19268 prohib->targetNamespace, prohib->name), 19269 NULL, NULL); 19270 FREE_AND_NULL(str); 19271 /* 19272 * Remove the prohibition. 19273 */ 19274 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19275 return(-1); 19276 break; 19277 } 19278 } 19279 } 19280 } 19281 return(0); 19282 } 19283 19296 static int 19297 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19298 xmlSchemaAttributeGroupPtr attrGr) 19299 { 19300 if ((attrGr->attrUses == NULL) || 19301 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19302 return(0); 19303 19304 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19305 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19306 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19307 return(-1); 19308 return(0); 19309 } 19310 19322 static int 19323 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19324 xmlSchemaAttributeGroupPtr attrGr) 19325 { 19326 /* 19327 * SPEC ag-props-correct 19328 * (1) "The values of the properties of an attribute group definition 19329 * must be as described in the property tableau in The Attribute 19330 * Group Definition Schema Component (�3.6.1), modulo the impact of 19331 * Missing Sub-components (�5.3);" 19332 */ 19333 19334 if ((attrGr->attrUses != NULL) && 19335 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19336 { 19337 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19338 xmlSchemaAttributeUsePtr use, tmp; 19339 int i, j, hasId = 0; 19340 19341 for (i = uses->nbItems -1; i >= 0; i--) { 19342 use = uses->items[i]; 19343 /* 19344 * SPEC ag-props-correct 19345 * (2) "Two distinct members of the {attribute uses} must not have 19346 * {attribute declaration}s both of whose {name}s match and whose 19347 * {target namespace}s are identical." 19348 */ 19349 if (i > 0) { 19350 for (j = i -1; j >= 0; j--) { 19351 tmp = uses->items[j]; 19352 if ((WXS_ATTRUSE_DECL_NAME(use) == 19353 WXS_ATTRUSE_DECL_NAME(tmp)) && 19354 (WXS_ATTRUSE_DECL_TNS(use) == 19355 WXS_ATTRUSE_DECL_TNS(tmp))) 19356 { 19357 xmlChar *str = NULL; 19358 19359 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19360 XML_SCHEMAP_AG_PROPS_CORRECT, 19361 attrGr->node, WXS_BASIC_CAST attrGr, 19362 "Duplicate %s", 19363 xmlSchemaGetComponentDesignation(&str, use), 19364 NULL); 19365 FREE_AND_NULL(str); 19366 /* 19367 * Remove the duplicate. 19368 */ 19369 if (xmlSchemaItemListRemove(uses, i) == -1) 19370 return(-1); 19371 goto next_use; 19372 } 19373 } 19374 } 19375 /* 19376 * SPEC ag-props-correct 19377 * (3) "Two distinct members of the {attribute uses} must not have 19378 * {attribute declaration}s both of whose {type definition}s are or 19379 * are derived from ID." 19380 * TODO: Does 'derived' include member-types of unions? 19381 */ 19382 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19383 if (xmlSchemaIsDerivedFromBuiltInType( 19384 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19385 { 19386 if (hasId) { 19387 xmlChar *str = NULL; 19388 19389 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19390 XML_SCHEMAP_AG_PROPS_CORRECT, 19391 attrGr->node, WXS_BASIC_CAST attrGr, 19392 "There must not exist more than one attribute " 19393 "declaration of type 'xs:ID' " 19394 "(or derived from 'xs:ID'). The %s violates this " 19395 "constraint", 19396 xmlSchemaGetComponentDesignation(&str, use), 19397 NULL); 19398 FREE_AND_NULL(str); 19399 if (xmlSchemaItemListRemove(uses, i) == -1) 19400 return(-1); 19401 } 19402 hasId = 1; 19403 } 19404 } 19405 next_use: {} 19406 } 19407 } 19408 return(0); 19409 } 19410 19419 static int 19420 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19421 xmlSchemaParserCtxtPtr ctxt) 19422 { 19423 xmlSchemaAttributeGroupPtr group; 19424 19425 if (ref->item != NULL) 19426 return(0); 19427 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19428 ref->name, 19429 ref->targetNamespace); 19430 if (group == NULL) { 19431 xmlSchemaPResCompAttrErr(ctxt, 19432 XML_SCHEMAP_SRC_RESOLVE, 19433 NULL, ref->node, 19434 "ref", ref->name, ref->targetNamespace, 19435 ref->itemType, NULL); 19436 return(ctxt->err); 19437 } 19438 ref->item = WXS_BASIC_CAST group; 19439 return(0); 19440 } 19441 19456 static int 19457 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19458 xmlSchemaAttributePtr attr) 19459 { 19460 19461 /* 19462 * SPEC a-props-correct (1) 19463 * "The values of the properties of an attribute declaration must 19464 * be as described in the property tableau in The Attribute 19465 * Declaration Schema Component (�3.2.1), modulo the impact of 19466 * Missing Sub-components (�5.3)." 19467 */ 19468 19469 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19470 return(0); 19471 19472 if (attr->defValue != NULL) { 19473 int ret; 19474 19475 /* 19476 * SPEC a-props-correct (3) 19477 * "If the {type definition} is or is derived from ID then there 19478 * must not be a {value constraint}." 19479 */ 19480 if (xmlSchemaIsDerivedFromBuiltInType( 19481 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19482 { 19483 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19484 XML_SCHEMAP_A_PROPS_CORRECT_3, 19485 NULL, WXS_BASIC_CAST attr, 19486 "Value constraints are not allowed if the type definition " 19487 "is or is derived from xs:ID", 19488 NULL, NULL); 19489 return(pctxt->err); 19490 } 19491 /* 19492 * SPEC a-props-correct (2) 19493 * "if there is a {value constraint}, the canonical lexical 19494 * representation of its value must be �valid� with respect 19495 * to the {type definition} as defined in String Valid (�3.14.4)." 19496 * TODO: Don't care about the *cononical* stuff here, this requirement 19497 * will be removed in WXS 1.1 anyway. 19498 */ 19499 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19500 attr->node, WXS_ATTR_TYPEDEF(attr), 19501 attr->defValue, &(attr->defVal), 19502 1, 1, 0); 19503 if (ret != 0) { 19504 if (ret < 0) { 19505 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19506 "calling xmlSchemaVCheckCVCSimpleType()"); 19507 return(-1); 19508 } 19509 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19510 XML_SCHEMAP_A_PROPS_CORRECT_2, 19511 NULL, WXS_BASIC_CAST attr, 19512 "The value of the value constraint is not valid", 19513 NULL, NULL); 19514 return(pctxt->err); 19515 } 19516 } 19517 19518 return(0); 19519 } 19520 19521 static xmlSchemaElementPtr 19522 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19523 xmlSchemaElementPtr ancestor) 19524 { 19525 xmlSchemaElementPtr ret; 19526 19527 if (WXS_SUBST_HEAD(ancestor) == NULL) 19528 return (NULL); 19529 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19530 return (ancestor); 19531 19532 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19533 return (NULL); 19534 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19535 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19536 WXS_SUBST_HEAD(ancestor)); 19537 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19538 19539 return (ret); 19540 } 19541 19554 static int 19555 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19556 xmlSchemaElementPtr elemDecl) 19557 { 19558 int ret = 0; 19559 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19560 /* 19561 * SPEC (1) "The values of the properties of an element declaration 19562 * must be as described in the property tableau in The Element 19563 * Declaration Schema Component (�3.3.1), modulo the impact of Missing 19564 * Sub-components (�5.3)." 19565 */ 19566 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19567 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19568 19569 xmlSchemaCheckElementDeclComponent(head, pctxt); 19570 /* 19571 * SPEC (3) "If there is a non-�absent� {substitution group 19572 * affiliation}, then {scope} must be global." 19573 */ 19574 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19575 xmlSchemaPCustomErr(pctxt, 19576 XML_SCHEMAP_E_PROPS_CORRECT_3, 19577 WXS_BASIC_CAST elemDecl, NULL, 19578 "Only global element declarations can have a " 19579 "substitution group affiliation", NULL); 19580 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19581 } 19582 /* 19583 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19584 * That is, it must not be possible to return to an element declaration 19585 * by repeatedly following the {substitution group affiliation} 19586 * property." 19587 */ 19588 if (head == elemDecl) 19589 circ = head; 19590 else if (WXS_SUBST_HEAD(head) != NULL) 19591 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19592 else 19593 circ = NULL; 19594 if (circ != NULL) { 19595 xmlChar *strA = NULL, *strB = NULL; 19596 19597 xmlSchemaPCustomErrExt(pctxt, 19598 XML_SCHEMAP_E_PROPS_CORRECT_6, 19599 WXS_BASIC_CAST circ, NULL, 19600 "The element declaration '%s' defines a circular " 19601 "substitution group to element declaration '%s'", 19602 xmlSchemaGetComponentQName(&strA, circ), 19603 xmlSchemaGetComponentQName(&strB, head), 19604 NULL); 19605 FREE_AND_NULL(strA) 19606 FREE_AND_NULL(strB) 19607 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19608 } 19609 /* 19610 * SPEC (4) "If there is a {substitution group affiliation}, 19611 * the {type definition} 19612 * of the element declaration must be validly derived from the {type 19613 * definition} of the {substitution group affiliation}, given the value 19614 * of the {substitution group exclusions} of the {substitution group 19615 * affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6) 19616 * (if the {type definition} is complex) or as defined in 19617 * Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is 19618 * simple)." 19619 * 19620 * NOTE: {substitution group exclusions} means the values of the 19621 * attribute "final". 19622 */ 19623 19624 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19625 int set = 0; 19626 19627 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19628 set |= SUBSET_EXTENSION; 19629 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19630 set |= SUBSET_RESTRICTION; 19631 19632 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19633 WXS_ELEM_TYPEDEF(head), set) != 0) { 19634 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19635 19636 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19637 xmlSchemaPCustomErrExt(pctxt, 19638 XML_SCHEMAP_E_PROPS_CORRECT_4, 19639 WXS_BASIC_CAST elemDecl, NULL, 19640 "The type definition '%s' was " 19641 "either rejected by the substitution group " 19642 "affiliation '%s', or not validly derived from its type " 19643 "definition '%s'", 19644 xmlSchemaGetComponentQName(&strA, typeDef), 19645 xmlSchemaGetComponentQName(&strB, head), 19646 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19647 FREE_AND_NULL(strA) 19648 FREE_AND_NULL(strB) 19649 FREE_AND_NULL(strC) 19650 } 19651 } 19652 } 19653 /* 19654 * SPEC (5) "If the {type definition} or {type definition}'s 19655 * {content type} 19656 * is or is derived from ID then there must not be a {value constraint}. 19657 * Note: The use of ID as a type definition for elements goes beyond 19658 * XML 1.0, and should be avoided if backwards compatibility is desired" 19659 */ 19660 if ((elemDecl->value != NULL) && 19661 ((WXS_IS_SIMPLE(typeDef) && 19662 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19663 (WXS_IS_COMPLEX(typeDef) && 19664 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19665 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19666 XML_SCHEMAS_ID)))) { 19667 19668 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19669 xmlSchemaPCustomErr(pctxt, 19670 XML_SCHEMAP_E_PROPS_CORRECT_5, 19671 WXS_BASIC_CAST elemDecl, NULL, 19672 "The type definition (or type definition's content type) is or " 19673 "is derived from ID; value constraints are not allowed in " 19674 "conjunction with such a type definition", NULL); 19675 } else if (elemDecl->value != NULL) { 19676 int vcret; 19677 xmlNodePtr node = NULL; 19678 19679 /* 19680 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19681 * representation of its value must be �valid� with respect to the 19682 * {type definition} as defined in Element Default Valid (Immediate) 19683 * (�3.3.6)." 19684 */ 19685 if (typeDef == NULL) { 19686 xmlSchemaPErr(pctxt, elemDecl->node, 19687 XML_SCHEMAP_INTERNAL, 19688 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19689 "type is missing... skipping validation of " 19690 "the value constraint", NULL, NULL); 19691 return (-1); 19692 } 19693 if (elemDecl->node != NULL) { 19694 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19695 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19696 BAD_CAST "fixed"); 19697 else 19698 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19699 BAD_CAST "default"); 19700 } 19701 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19702 typeDef, elemDecl->value, &(elemDecl->defVal)); 19703 if (vcret != 0) { 19704 if (vcret < 0) { 19705 PERROR_INT("xmlSchemaElemCheckValConstr", 19706 "failed to validate the value constraint of an " 19707 "element declaration"); 19708 return (-1); 19709 } 19710 return (vcret); 19711 } 19712 } 19713 19714 return (ret); 19715 } 19716 19736 static void 19737 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19738 xmlSchemaElementPtr elemDecl) 19739 { 19740 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19741 /* SPEC (1) "Its {abstract} is false." */ 19742 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19743 return; 19744 { 19745 xmlSchemaElementPtr head; 19746 xmlSchemaTypePtr headType, type; 19747 int set, methSet; 19748 /* 19749 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's 19750 * {disallowed substitutions} as the blocking constraint, as defined in 19751 * Substitution Group OK (Transitive) (�3.3.6)." 19752 */ 19753 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL; 19754 head = WXS_SUBST_HEAD(head)) { 19755 set = 0; 19756 methSet = 0; 19757 /* 19758 * The blocking constraints. 19759 */ 19760 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) 19761 continue; 19762 headType = head->subtypes; 19763 type = elemDecl->subtypes; 19764 if (headType == type) 19765 goto add_member; 19766 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) 19767 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19768 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) 19769 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19770 /* 19771 * SPEC: Substitution Group OK (Transitive) (2.3) 19772 * "The set of all {derivation method}s involved in the 19773 * derivation of D's {type definition} from C's {type definition} 19774 * does not intersect with the union of the blocking constraint, 19775 * C's {prohibited substitutions} (if C is complex, otherwise the 19776 * empty set) and the {prohibited substitutions} (respectively the 19777 * empty set) of any intermediate {type definition}s in the 19778 * derivation of D's {type definition} from C's {type definition}." 19779 */ 19780 /* 19781 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the 19782 * subst.head axis, the methSet does not need to be computed for 19783 * the full depth over and over. 19784 */ 19785 /* 19786 * The set of all {derivation method}s involved in the derivation 19787 */ 19788 while ((type != NULL) && (type != headType)) { 19789 if ((WXS_IS_EXTENSION(type)) && 19790 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19791 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19792 19793 if (WXS_IS_RESTRICTION(type) && 19794 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19795 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19796 19797 type = type->baseType; 19798 } 19799 /* 19800 * The {prohibited substitutions} of all intermediate types + 19801 * the head's type. 19802 */ 19803 type = elemDecl->subtypes->baseType; 19804 while (type != NULL) { 19805 if (WXS_IS_COMPLEX(type)) { 19806 if ((type->flags & 19807 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19808 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0)) 19809 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 19810 if ((type->flags & 19811 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19812 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0)) 19813 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 19814 } else 19815 break; 19816 if (type == headType) 19817 break; 19818 type = type->baseType; 19819 } 19820 if ((set != 0) && 19821 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) && 19822 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) || 19823 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) && 19824 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) { 19825 continue; 19826 } 19827 add_member: 19828 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl); 19829 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0) 19830 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD; 19831 } 19832 } 19833 } 19834 19835 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */ 19836 19845 static int 19846 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt, 19847 xmlSchemaBasicItemPtr ctxtComponent, 19848 xmlSchemaParticlePtr ctxtParticle, 19849 xmlSchemaParticlePtr searchParticle, 19850 xmlSchemaParticlePtr curParticle, 19851 int search) 19852 { 19853 return(0); 19854 19855 int ret = 0; 19856 xmlSchemaParticlePtr cur = curParticle; 19857 if (curParticle == NULL) { 19858 return(0); 19859 } 19860 if (WXS_PARTICLE_TERM(curParticle) == NULL) { 19861 /* 19862 * Just return in this case. A missing "term" of the particle 19863 * might arise due to an invalid "term" component. 19864 */ 19865 return(0); 19866 } 19867 while (cur != NULL) { 19868 switch (WXS_PARTICLE_TERM(cur)->type) { 19869 case XML_SCHEMA_TYPE_ANY: 19870 break; 19871 case XML_SCHEMA_TYPE_ELEMENT: 19872 if (search == 0) { 19873 ret = xmlSchemaCheckElementDeclConsistent(pctxt, 19874 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1); 19875 if (ret != 0) 19876 return(ret); 19877 } else { 19878 xmlSchemaElementPtr elem = 19879 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur)); 19880 /* 19881 * SPEC Element Declarations Consistent: 19882 * "If the {particles} contains, either directly, 19883 * indirectly (that is, within the {particles} of a 19884 * contained model group, recursively) or �implicitly� 19885 * two or more element declaration particles with 19886 * the same {name} and {target namespace}, then 19887 * all their type definitions must be the same 19888 * top-level definition [...]" 19889 */ 19890 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name, 19891 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) && 19892 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19893 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace)) 19894 { 19895 xmlChar *strA = NULL, *strB = NULL; 19896 19897 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19898 /* TODO: error code */ 19899 XML_SCHEMAP_COS_NONAMBIG, 19900 WXS_ITEM_NODE(cur), NULL, 19901 "In the content model of %s, there are multiple " 19902 "element declarations for '%s' with different " 19903 "type definitions", 19904 xmlSchemaGetComponentDesignation(&strA, 19905 ctxtComponent), 19906 xmlSchemaFormatQName(&strB, 19907 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace, 19908 WXS_PARTICLE_TERM_AS_ELEM(cur)->name)); 19909 FREE_AND_NULL(strA); 19910 FREE_AND_NULL(strB); 19911 return(XML_SCHEMAP_COS_NONAMBIG); 19912 } 19913 } 19914 break; 19915 case XML_SCHEMA_TYPE_SEQUENCE: { 19916 break; 19917 } 19918 case XML_SCHEMA_TYPE_CHOICE:{ 19919 /* 19920 xmlSchemaTreeItemPtr sub; 19921 19922 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr) 19923 while (sub != NULL) { 19924 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent, 19925 ctxtParticle, ctxtElem); 19926 if (ret != 0) 19927 return(ret); 19928 sub = sub->next; 19929 } 19930 */ 19931 break; 19932 } 19933 case XML_SCHEMA_TYPE_ALL: 19934 break; 19935 case XML_SCHEMA_TYPE_GROUP: 19936 break; 19937 default: 19938 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 19939 "xmlSchemaCheckElementDeclConsistent", 19940 "found unexpected term of type '%s' in content model", 19941 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL); 19942 return(-1); 19943 } 19944 cur = (xmlSchemaParticlePtr) cur->next; 19945 } 19946 19947 exit: 19948 return(ret); 19949 } 19950 #endif 19951 19961 static void 19962 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 19963 xmlSchemaParserCtxtPtr ctxt) 19964 { 19965 if (elemDecl == NULL) 19966 return; 19967 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) 19968 return; 19969 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED; 19970 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) { 19971 /* 19972 * Adds substitution group members. 19973 */ 19974 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl); 19975 } 19976 } 19977 19986 static void 19987 xmlSchemaResolveModelGroupParticleReferences( 19988 xmlSchemaParserCtxtPtr ctxt, 19989 xmlSchemaModelGroupPtr mg) 19990 { 19991 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19992 xmlSchemaQNameRefPtr ref; 19993 xmlSchemaBasicItemPtr refItem; 19994 19995 /* 19996 * URGENT TODO: Test this. 19997 */ 19998 while (particle != NULL) { 19999 if ((WXS_PARTICLE_TERM(particle) == NULL) || 20000 ((WXS_PARTICLE_TERM(particle))->type != 20001 XML_SCHEMA_EXTRA_QNAMEREF)) 20002 { 20003 goto next_particle; 20004 } 20005 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle); 20006 /* 20007 * Resolve the reference. 20008 * NULL the {term} by default. 20009 */ 20010 particle->children = NULL; 20011 20012 refItem = xmlSchemaGetNamedComponent(ctxt->schema, 20013 ref->itemType, ref->name, ref->targetNamespace); 20014 if (refItem == NULL) { 20015 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 20016 NULL, WXS_ITEM_NODE(particle), "ref", ref->name, 20017 ref->targetNamespace, ref->itemType, NULL); 20018 /* TODO: remove the particle. */ 20019 goto next_particle; 20020 } 20021 if (refItem->type == XML_SCHEMA_TYPE_GROUP) { 20022 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL) 20023 /* TODO: remove the particle. */ 20024 goto next_particle; 20025 /* 20026 * NOTE that we will assign the model group definition 20027 * itself to the "term" of the particle. This will ease 20028 * the check for circular model group definitions. After 20029 * that the "term" will be assigned the model group of the 20030 * model group definition. 20031 */ 20032 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type == 20033 XML_SCHEMA_TYPE_ALL) { 20034 /* 20035 * SPEC cos-all-limited (1) 20036 * SPEC cos-all-limited (1.2) 20037 * "It appears only as the value of one or both of the 20038 * following properties:" 20039 * (1.1) "the {model group} property of a model group 20040 * definition." 20041 * (1.2) "the {term} property of a particle [... of] the " 20042 * {content type} of a complex type definition." 20043 */ 20044 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20045 /* TODO: error code */ 20046 XML_SCHEMAP_COS_ALL_LIMITED, 20047 WXS_ITEM_NODE(particle), NULL, 20048 "A model group definition is referenced, but " 20049 "it contains an 'all' model group, which " 20050 "cannot be contained by model groups", 20051 NULL, NULL); 20052 /* TODO: remove the particle. */ 20053 goto next_particle; 20054 } 20055 particle->children = (xmlSchemaTreeItemPtr) refItem; 20056 } else { 20057 /* 20058 * TODO: Are referenced element declarations the only 20059 * other components we expect here? 20060 */ 20061 particle->children = (xmlSchemaTreeItemPtr) refItem; 20062 } 20063 next_particle: 20064 particle = WXS_PTC_CAST particle->next; 20065 } 20066 } 20067 20068 static int 20069 xmlSchemaAreValuesEqual(xmlSchemaValPtr x, 20070 xmlSchemaValPtr y) 20071 { 20072 xmlSchemaTypePtr tx, ty, ptx, pty; 20073 int ret; 20074 20075 while (x != NULL) { 20076 /* Same types. */ 20077 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x)); 20078 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y)); 20079 ptx = xmlSchemaGetPrimitiveType(tx); 20080 pty = xmlSchemaGetPrimitiveType(ty); 20081 /* 20082 * (1) if a datatype T' is �derived� by �restriction� from an 20083 * atomic datatype T then the �value space� of T' is a subset of 20084 * the �value space� of T. */ 20085 /* 20086 * (2) if datatypes T' and T'' are �derived� by �restriction� 20087 * from a common atomic ancestor T then the �value space�s of T' 20088 * and T'' may overlap. 20089 */ 20090 if (ptx != pty) 20091 return(0); 20092 /* 20093 * We assume computed values to be normalized, so do a fast 20094 * string comparison for string based types. 20095 */ 20096 if ((ptx->builtInType == XML_SCHEMAS_STRING) || 20097 WXS_IS_ANY_SIMPLE_TYPE(ptx)) { 20098 if (! xmlStrEqual( 20099 xmlSchemaValueGetAsString(x), 20100 xmlSchemaValueGetAsString(y))) 20101 return (0); 20102 } else { 20103 ret = xmlSchemaCompareValuesWhtsp( 20104 x, XML_SCHEMA_WHITESPACE_PRESERVE, 20105 y, XML_SCHEMA_WHITESPACE_PRESERVE); 20106 if (ret == -2) 20107 return(-1); 20108 if (ret != 0) 20109 return(0); 20110 } 20111 /* 20112 * Lists. 20113 */ 20114 x = xmlSchemaValueGetNext(x); 20115 if (x != NULL) { 20116 y = xmlSchemaValueGetNext(y); 20117 if (y == NULL) 20118 return (0); 20119 } else if (xmlSchemaValueGetNext(y) != NULL) 20120 return (0); 20121 else 20122 return (1); 20123 } 20124 return (0); 20125 } 20126 20134 static int 20135 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause, 20136 xmlSchemaParserCtxtPtr ctxt) 20137 { 20138 if ((ctxt == NULL) || (ause == NULL)) 20139 return(-1); 20140 if ((ause->attrDecl == NULL) || 20141 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF)) 20142 return(0); 20143 20144 { 20145 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl; 20146 20147 /* 20148 * TODO: Evaluate, what errors could occur if the declaration is not 20149 * found. 20150 */ 20151 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema, 20152 ref->name, ref->targetNamespace); 20153 if (ause->attrDecl == NULL) { 20154 xmlSchemaPResCompAttrErr(ctxt, 20155 XML_SCHEMAP_SRC_RESOLVE, 20156 WXS_BASIC_CAST ause, ause->node, 20157 "ref", ref->name, ref->targetNamespace, 20158 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20159 return(ctxt->err);; 20160 } 20161 } 20162 return(0); 20163 } 20164 20174 static int 20175 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt, 20176 xmlSchemaAttributeUsePtr use) 20177 { 20178 if ((ctxt == NULL) || (use == NULL)) 20179 return(-1); 20180 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) || 20181 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE)) 20182 return(0); 20183 20184 /* 20185 * SPEC au-props-correct (1) 20186 * "The values of the properties of an attribute use must be as 20187 * described in the property tableau in The Attribute Use Schema 20188 * Component (�3.5.1), modulo the impact of Missing 20189 * Sub-components (�5.3)." 20190 */ 20191 20192 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) && 20193 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) && 20194 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20195 { 20196 xmlSchemaPCustomErr(ctxt, 20197 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20198 WXS_BASIC_CAST use, NULL, 20199 "The attribute declaration has a 'fixed' value constraint " 20200 ", thus the attribute use must also have a 'fixed' value " 20201 "constraint", 20202 NULL); 20203 return(ctxt->err); 20204 } 20205 /* 20206 * Compute and check the value constraint's value. 20207 */ 20208 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) { 20209 int ret; 20210 /* 20211 * TODO: The spec seems to be missing a check of the 20212 * value constraint of the attribute use. We will do it here. 20213 */ 20214 /* 20215 * SPEC a-props-correct (3) 20216 */ 20217 if (xmlSchemaIsDerivedFromBuiltInType( 20218 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 20219 { 20220 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20221 XML_SCHEMAP_AU_PROPS_CORRECT, 20222 NULL, WXS_BASIC_CAST use, 20223 "Value constraints are not allowed if the type definition " 20224 "is or is derived from xs:ID", 20225 NULL, NULL); 20226 return(ctxt->err); 20227 } 20228 20229 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt, 20230 use->node, WXS_ATTRUSE_TYPEDEF(use), 20231 use->defValue, &(use->defVal), 20232 1, 1, 0); 20233 if (ret != 0) { 20234 if (ret < 0) { 20235 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect", 20236 "calling xmlSchemaVCheckCVCSimpleType()"); 20237 return(-1); 20238 } 20239 xmlSchemaCustomErr(ACTXT_CAST ctxt, 20240 XML_SCHEMAP_AU_PROPS_CORRECT, 20241 NULL, WXS_BASIC_CAST use, 20242 "The value of the value constraint is not valid", 20243 NULL, NULL); 20244 return(ctxt->err); 20245 } 20246 } 20247 /* 20248 * SPEC au-props-correct (2) 20249 * "If the {attribute declaration} has a fixed 20250 * {value constraint}, then if the attribute use itself has a 20251 * {value constraint}, it must also be fixed and its value must match 20252 * that of the {attribute declaration}'s {value constraint}." 20253 */ 20254 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) && 20255 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0)) 20256 { 20257 if (! xmlSchemaAreValuesEqual(use->defVal, 20258 (WXS_ATTRUSE_DECL(use))->defVal)) 20259 { 20260 xmlSchemaPCustomErr(ctxt, 20261 XML_SCHEMAP_AU_PROPS_CORRECT_2, 20262 WXS_BASIC_CAST use, NULL, 20263 "The 'fixed' value constraint of the attribute use " 20264 "must match the attribute declaration's value " 20265 "constraint '%s'", 20266 (WXS_ATTRUSE_DECL(use))->defValue); 20267 } 20268 return(ctxt->err); 20269 } 20270 return(0); 20271 } 20272 20273 20274 20275 20283 static int 20284 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item, 20285 xmlSchemaParserCtxtPtr ctxt) 20286 { 20287 /* 20288 * The simple type definition corresponding to the <simpleType> element 20289 * information item in the [children], if present, otherwise the simple 20290 * type definition �resolved� to by the �actual value� of the type 20291 * [attribute], if present, otherwise the �simple ur-type definition�. 20292 */ 20293 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED) 20294 return(0); 20295 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED; 20296 if (item->subtypes != NULL) 20297 return(0); 20298 if (item->typeName != NULL) { 20299 xmlSchemaTypePtr type; 20300 20301 type = xmlSchemaGetType(ctxt->schema, item->typeName, 20302 item->typeNs); 20303 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) { 20304 xmlSchemaPResCompAttrErr(ctxt, 20305 XML_SCHEMAP_SRC_RESOLVE, 20306 WXS_BASIC_CAST item, item->node, 20307 "type", item->typeName, item->typeNs, 20308 XML_SCHEMA_TYPE_SIMPLE, NULL); 20309 return(ctxt->err); 20310 } else 20311 item->subtypes = type; 20312 20313 } else { 20314 /* 20315 * The type defaults to the xs:anySimpleType. 20316 */ 20317 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 20318 } 20319 return(0); 20320 } 20321 20332 static int 20333 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc, 20334 xmlSchemaParserCtxtPtr pctxt) 20335 { 20336 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) 20337 return(0); 20338 if (idc->ref->name != NULL) { 20339 idc->ref->item = (xmlSchemaBasicItemPtr) 20340 xmlSchemaGetIDC(pctxt->schema, idc->ref->name, 20341 idc->ref->targetNamespace); 20342 if (idc->ref->item == NULL) { 20343 /* 20344 * TODO: It is actually not an error to fail to resolve 20345 * at this stage. BUT we need to be that strict! 20346 */ 20347 xmlSchemaPResCompAttrErr(pctxt, 20348 XML_SCHEMAP_SRC_RESOLVE, 20349 WXS_BASIC_CAST idc, idc->node, 20350 "refer", idc->ref->name, 20351 idc->ref->targetNamespace, 20352 XML_SCHEMA_TYPE_IDC_KEY, NULL); 20353 return(pctxt->err); 20354 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 20355 /* 20356 * SPEC c-props-correct (1) 20357 */ 20358 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20359 XML_SCHEMAP_C_PROPS_CORRECT, 20360 NULL, WXS_BASIC_CAST idc, 20361 "The keyref references a keyref", 20362 NULL, NULL); 20363 idc->ref->item = NULL; 20364 return(pctxt->err); 20365 } else { 20366 if (idc->nbFields != 20367 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) { 20368 xmlChar *str = NULL; 20369 xmlSchemaIDCPtr refer; 20370 20371 refer = (xmlSchemaIDCPtr) idc->ref->item; 20372 /* 20373 * SPEC c-props-correct(2) 20374 * "If the {identity-constraint category} is keyref, 20375 * the cardinality of the {fields} must equal that of 20376 * the {fields} of the {referenced key}. 20377 */ 20378 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20379 XML_SCHEMAP_C_PROPS_CORRECT, 20380 NULL, WXS_BASIC_CAST idc, 20381 "The cardinality of the keyref differs from the " 20382 "cardinality of the referenced key/unique '%s'", 20383 xmlSchemaFormatQName(&str, refer->targetNamespace, 20384 refer->name), 20385 NULL); 20386 FREE_AND_NULL(str) 20387 return(pctxt->err); 20388 } 20389 } 20390 } 20391 return(0); 20392 } 20393 20394 static int 20395 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib, 20396 xmlSchemaParserCtxtPtr pctxt) 20397 { 20398 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name, 20399 prohib->targetNamespace) == NULL) { 20400 20401 xmlSchemaPResCompAttrErr(pctxt, 20402 XML_SCHEMAP_SRC_RESOLVE, 20403 NULL, prohib->node, 20404 "ref", prohib->name, prohib->targetNamespace, 20405 XML_SCHEMA_TYPE_ATTRIBUTE, NULL); 20406 return(XML_SCHEMAP_SRC_RESOLVE); 20407 } 20408 return(0); 20409 } 20410 20411 #define WXS_REDEFINED_TYPE(c) \ 20412 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED) 20413 20414 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \ 20415 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20416 20417 #define WXS_REDEFINED_ATTR_GROUP(c) \ 20418 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED) 20419 20420 static int 20421 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt) 20422 { 20423 int err = 0; 20424 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20425 xmlSchemaBasicItemPtr prev, item; 20426 int wasRedefined; 20427 20428 if (redef == NULL) 20429 return(0); 20430 20431 do { 20432 item = redef->item; 20433 /* 20434 * First try to locate the redefined component in the 20435 * schema graph starting with the redefined schema. 20436 * NOTE: According to this schema bug entry: 20437 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html 20438 * it's not clear if the referenced component needs to originate 20439 * from the <redefine>d schema _document_ or the schema; the latter 20440 * would include all imported and included sub-schemas of the 20441 * <redefine>d schema. Currenlty we latter approach is used. 20442 * SUPPLEMENT: It seems that the WG moves towards the latter 20443 * approach, so we are doing it right. 20444 * 20445 */ 20446 prev = xmlSchemaFindRedefCompInGraph( 20447 redef->targetBucket, item->type, 20448 redef->refName, redef->refTargetNs); 20449 if (prev == NULL) { 20450 xmlChar *str = NULL; 20451 xmlNodePtr node; 20452 20453 /* 20454 * SPEC src-redefine: 20455 * (6.2.1) "The �actual value� of its own name attribute plus 20456 * target namespace must successfully �resolve� to a model 20457 * group definition in I." 20458 * (7.2.1) "The �actual value� of its own name attribute plus 20459 * target namespace must successfully �resolve� to an attribute 20460 * group definition in I." 20461 20462 * 20463 * Note that, if we are redefining with the use of references 20464 * to components, the spec assumes the src-resolve to be used; 20465 * but this won't assure that we search only *inside* the 20466 * redefined schema. 20467 */ 20468 if (redef->reference) 20469 node = WXS_ITEM_NODE(redef->reference); 20470 else 20471 node = WXS_ITEM_NODE(item); 20472 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20473 /* 20474 * TODO: error code. 20475 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the 20476 * reference kind. 20477 */ 20478 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 20479 "The %s '%s' to be redefined could not be found in " 20480 "the redefined schema", 20481 WXS_ITEM_TYPE_NAME(item), 20482 xmlSchemaFormatQName(&str, redef->refTargetNs, 20483 redef->refName)); 20484 FREE_AND_NULL(str); 20485 err = pctxt->err; 20486 redef = redef->next; 20487 continue; 20488 } 20489 /* 20490 * TODO: Obtaining and setting the redefinition state is really 20491 * clumsy. 20492 */ 20493 wasRedefined = 0; 20494 switch (item->type) { 20495 case XML_SCHEMA_TYPE_COMPLEX: 20496 case XML_SCHEMA_TYPE_SIMPLE: 20497 if ((WXS_TYPE_CAST prev)->flags & 20498 XML_SCHEMAS_TYPE_REDEFINED) 20499 { 20500 wasRedefined = 1; 20501 break; 20502 } 20503 /* Mark it as redefined. */ 20504 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED; 20505 /* 20506 * Assign the redefined type to the 20507 * base type of the redefining type. 20508 * TODO: How 20509 */ 20510 ((xmlSchemaTypePtr) item)->baseType = 20511 (xmlSchemaTypePtr) prev; 20512 break; 20513 case XML_SCHEMA_TYPE_GROUP: 20514 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags & 20515 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED) 20516 { 20517 wasRedefined = 1; 20518 break; 20519 } 20520 /* Mark it as redefined. */ 20521 (WXS_MODEL_GROUPDEF_CAST prev)->flags |= 20522 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED; 20523 if (redef->reference != NULL) { 20524 /* 20525 * Overwrite the QName-reference with the 20526 * referenced model group def. 20527 */ 20528 (WXS_PTC_CAST redef->reference)->children = 20529 WXS_TREE_CAST prev; 20530 } 20531 redef->target = prev; 20532 break; 20533 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20534 if ((WXS_ATTR_GROUP_CAST prev)->flags & 20535 XML_SCHEMAS_ATTRGROUP_REDEFINED) 20536 { 20537 wasRedefined = 1; 20538 break; 20539 } 20540 (WXS_ATTR_GROUP_CAST prev)->flags |= 20541 XML_SCHEMAS_ATTRGROUP_REDEFINED; 20542 if (redef->reference != NULL) { 20543 /* 20544 * Assign the redefined attribute group to the 20545 * QName-reference component. 20546 * This is the easy case, since we will just 20547 * expand the redefined group. 20548 */ 20549 (WXS_QNAME_CAST redef->reference)->item = prev; 20550 redef->target = NULL; 20551 } else { 20552 /* 20553 * This is the complicated case: we need 20554 * to apply src-redefine (7.2.2) at a later 20555 * stage, i.e. when attribute group references 20556 * have beed expanded and simple types have 20557 * beed fixed. 20558 */ 20559 redef->target = prev; 20560 } 20561 break; 20562 default: 20563 PERROR_INT("xmlSchemaResolveRedefReferences", 20564 "Unexpected redefined component type"); 20565 return(-1); 20566 } 20567 if (wasRedefined) { 20568 xmlChar *str = NULL; 20569 xmlNodePtr node; 20570 20571 if (redef->reference) 20572 node = WXS_ITEM_NODE(redef->reference); 20573 else 20574 node = WXS_ITEM_NODE(redef->item); 20575 20576 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20577 /* TODO: error code. */ 20578 XML_SCHEMAP_SRC_REDEFINE, 20579 node, NULL, 20580 "The referenced %s was already redefined. Multiple " 20581 "redefinition of the same component is not supported", 20582 xmlSchemaGetComponentDesignation(&str, prev), 20583 NULL); 20584 FREE_AND_NULL(str) 20585 err = pctxt->err; 20586 redef = redef->next; 20587 continue; 20588 } 20589 redef = redef->next; 20590 } while (redef != NULL); 20591 20592 return(err); 20593 } 20594 20595 static int 20596 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt) 20597 { 20598 int err = 0; 20599 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs; 20600 xmlSchemaBasicItemPtr item; 20601 20602 if (redef == NULL) 20603 return(0); 20604 20605 do { 20606 if (redef->target == NULL) { 20607 redef = redef->next; 20608 continue; 20609 } 20610 item = redef->item; 20611 20612 switch (item->type) { 20613 case XML_SCHEMA_TYPE_SIMPLE: 20614 case XML_SCHEMA_TYPE_COMPLEX: 20615 /* 20616 * Since the spec wants the {name} of the redefined 20617 * type to be 'absent', we'll NULL it. 20618 */ 20619 (WXS_TYPE_CAST redef->target)->name = NULL; 20620 20621 /* 20622 * TODO: Seems like there's nothing more to do. The normal 20623 * inheritance mechanism is used. But not 100% sure. 20624 */ 20625 break; 20626 case XML_SCHEMA_TYPE_GROUP: 20627 /* 20628 * URGENT TODO: 20629 * SPEC src-redefine: 20630 * (6.2.2) "The {model group} of the model group definition 20631 * which corresponds to it per XML Representation of Model 20632 * Group Definition Schema Components (�3.7.2) must be a 20633 * �valid restriction� of the {model group} of that model 20634 * group definition in I, as defined in Particle Valid 20635 * (Restriction) (�3.9.6)." 20636 */ 20637 break; 20638 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20639 /* 20640 * SPEC src-redefine: 20641 * (7.2.2) "The {attribute uses} and {attribute wildcard} of 20642 * the attribute group definition which corresponds to it 20643 * per XML Representation of Attribute Group Definition Schema 20644 * Components (�3.6.2) must be �valid restrictions� of the 20645 * {attribute uses} and {attribute wildcard} of that attribute 20646 * group definition in I, as defined in clause 2, clause 3 and 20647 * clause 4 of Derivation Valid (Restriction, Complex) 20648 * (�3.4.6) (where references to the base type definition are 20649 * understood as references to the attribute group definition 20650 * in I)." 20651 */ 20652 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt, 20653 XML_SCHEMA_ACTION_REDEFINE, 20654 item, redef->target, 20655 (WXS_ATTR_GROUP_CAST item)->attrUses, 20656 (WXS_ATTR_GROUP_CAST redef->target)->attrUses, 20657 (WXS_ATTR_GROUP_CAST item)->attributeWildcard, 20658 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard); 20659 if (err == -1) 20660 return(-1); 20661 break; 20662 default: 20663 break; 20664 } 20665 redef = redef->next; 20666 } while (redef != NULL); 20667 return(0); 20668 } 20669 20670 20671 static int 20672 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt, 20673 xmlSchemaBucketPtr bucket) 20674 { 20675 xmlSchemaBasicItemPtr item; 20676 int err; 20677 xmlHashTablePtr *table; 20678 const xmlChar *name; 20679 int i; 20680 20681 #define WXS_GET_GLOBAL_HASH(c, slot) { \ 20682 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \ 20683 table = &(WXS_IMPBUCKET((c))->schema->slot); \ 20684 else \ 20685 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); } 20686 20687 /* 20688 * Add global components to the schema's hash tables. 20689 * This is the place where duplicate components will be 20690 * detected. 20691 * TODO: I think normally we should support imports of the 20692 * same namespace from multiple locations. We don't do currently, 20693 * but if we do then according to: 20694 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224 20695 * we would need, if imported directly, to import redefined 20696 * components as well to be able to catch clashing components. 20697 * (I hope I'll still know what this means after some months :-() 20698 */ 20699 if (bucket == NULL) 20700 return(-1); 20701 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) 20702 return(0); 20703 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED; 20704 20705 for (i = 0; i < bucket->globals->nbItems; i++) { 20706 item = bucket->globals->items[i]; 20707 table = NULL; 20708 switch (item->type) { 20709 case XML_SCHEMA_TYPE_COMPLEX: 20710 case XML_SCHEMA_TYPE_SIMPLE: 20711 if (WXS_REDEFINED_TYPE(item)) 20712 continue; 20713 name = (WXS_TYPE_CAST item)->name; 20714 WXS_GET_GLOBAL_HASH(bucket, typeDecl) 20715 break; 20716 case XML_SCHEMA_TYPE_ELEMENT: 20717 name = (WXS_ELEM_CAST item)->name; 20718 WXS_GET_GLOBAL_HASH(bucket, elemDecl) 20719 break; 20720 case XML_SCHEMA_TYPE_ATTRIBUTE: 20721 name = (WXS_ATTR_CAST item)->name; 20722 WXS_GET_GLOBAL_HASH(bucket, attrDecl) 20723 break; 20724 case XML_SCHEMA_TYPE_GROUP: 20725 if (WXS_REDEFINED_MODEL_GROUP_DEF(item)) 20726 continue; 20727 name = (WXS_MODEL_GROUPDEF_CAST item)->name; 20728 WXS_GET_GLOBAL_HASH(bucket, groupDecl) 20729 break; 20730 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20731 if (WXS_REDEFINED_ATTR_GROUP(item)) 20732 continue; 20733 name = (WXS_ATTR_GROUP_CAST item)->name; 20734 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl) 20735 break; 20736 case XML_SCHEMA_TYPE_IDC_KEY: 20737 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20738 case XML_SCHEMA_TYPE_IDC_KEYREF: 20739 name = (WXS_IDC_CAST item)->name; 20740 WXS_GET_GLOBAL_HASH(bucket, idcDef) 20741 break; 20742 case XML_SCHEMA_TYPE_NOTATION: 20743 name = ((xmlSchemaNotationPtr) item)->name; 20744 WXS_GET_GLOBAL_HASH(bucket, notaDecl) 20745 break; 20746 default: 20747 PERROR_INT("xmlSchemaAddComponents", 20748 "Unexpected global component type"); 20749 continue; 20750 } 20751 if (*table == NULL) { 20752 *table = xmlHashCreateDict(10, pctxt->dict); 20753 if (*table == NULL) { 20754 PERROR_INT("xmlSchemaAddComponents", 20755 "failed to create a component hash table"); 20756 return(-1); 20757 } 20758 } 20759 err = xmlHashAddEntry(*table, name, item); 20760 if (err != 0) { 20761 xmlChar *str = NULL; 20762 20763 xmlSchemaCustomErr(ACTXT_CAST pctxt, 20764 XML_SCHEMAP_REDEFINED_TYPE, 20765 WXS_ITEM_NODE(item), 20766 WXS_BASIC_CAST item, 20767 "A global %s '%s' does already exist", 20768 WXS_ITEM_TYPE_NAME(item), 20769 xmlSchemaGetComponentQName(&str, item)); 20770 FREE_AND_NULL(str); 20771 } 20772 } 20773 /* 20774 * Process imported/included schemas. 20775 */ 20776 if (bucket->relations != NULL) { 20777 xmlSchemaSchemaRelationPtr rel = bucket->relations; 20778 do { 20779 if ((rel->bucket != NULL) && 20780 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) { 20781 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1) 20782 return(-1); 20783 } 20784 rel = rel->next; 20785 } while (rel != NULL); 20786 } 20787 return(0); 20788 } 20789 20790 static int 20791 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt, 20792 xmlSchemaBucketPtr rootBucket) 20793 { 20794 xmlSchemaConstructionCtxtPtr con = pctxt->constructor; 20795 xmlSchemaTreeItemPtr item, *items; 20796 int nbItems, i, ret = 0; 20797 xmlSchemaBucketPtr oldbucket = con->bucket; 20798 xmlSchemaElementPtr elemDecl; 20799 20800 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure; 20801 20802 if ((con->pending == NULL) || 20803 (con->pending->nbItems == 0)) 20804 return(0); 20805 20806 /* 20807 * Since xmlSchemaFixupComplexType() will create new particles 20808 * (local components), and those particle components need a bucket 20809 * on the constructor, we'll assure here that the constructor has 20810 * a bucket. 20811 * TODO: Think about storing locals _only_ on the main bucket. 20812 */ 20813 if (con->bucket == NULL) 20814 con->bucket = rootBucket; 20815 20816 /* TODO: 20817 * SPEC (src-redefine): 20818 * (6.2) "If it has no such self-reference, then all of the 20819 * following must be true:" 20820 20821 * (6.2.2) The {model group} of the model group definition which 20822 * corresponds to it per XML Representation of Model Group 20823 * Definition Schema Components (�3.7.2) must be a �valid 20824 * restriction� of the {model group} of that model group definition 20825 * in I, as defined in Particle Valid (Restriction) (�3.9.6)." 20826 */ 20827 xmlSchemaCheckSRCRedefineFirst(pctxt); 20828 20829 /* 20830 * Add global components to the schemata's hash tables. 20831 */ 20832 xmlSchemaAddComponents(pctxt, rootBucket); 20833 20834 pctxt->ctxtType = NULL; 20835 items = (xmlSchemaTreeItemPtr *) con->pending->items; 20836 nbItems = con->pending->nbItems; 20837 /* 20838 * Now that we have parsed *all* the schema document(s) and converted 20839 * them to schema components, we can resolve references, apply component 20840 * constraints, create the FSA from the content model, etc. 20841 */ 20842 /* 20843 * Resolve references of.. 20844 * 20845 * 1. element declarations: 20846 * - the type definition 20847 * - the substitution group affiliation 20848 * 2. simple/complex types: 20849 * - the base type definition 20850 * - the memberTypes of union types 20851 * - the itemType of list types 20852 * 3. attributes declarations and attribute uses: 20853 * - the type definition 20854 * - if an attribute use, then the attribute declaration 20855 * 4. attribute group references: 20856 * - the attribute group definition 20857 * 5. particles: 20858 * - the term of the particle (e.g. a model group) 20859 * 6. IDC key-references: 20860 * - the referenced IDC 'key' or 'unique' definition 20861 * 7. Attribute prohibitions which had a "ref" attribute. 20862 */ 20863 for (i = 0; i < nbItems; i++) { 20864 item = items[i]; 20865 switch (item->type) { 20866 case XML_SCHEMA_TYPE_ELEMENT: 20867 xmlSchemaResolveElementReferences( 20868 (xmlSchemaElementPtr) item, pctxt); 20869 FIXHFAILURE; 20870 break; 20871 case XML_SCHEMA_TYPE_COMPLEX: 20872 case XML_SCHEMA_TYPE_SIMPLE: 20873 xmlSchemaResolveTypeReferences( 20874 (xmlSchemaTypePtr) item, pctxt); 20875 FIXHFAILURE; 20876 break; 20877 case XML_SCHEMA_TYPE_ATTRIBUTE: 20878 xmlSchemaResolveAttrTypeReferences( 20879 (xmlSchemaAttributePtr) item, pctxt); 20880 FIXHFAILURE; 20881 break; 20882 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 20883 xmlSchemaResolveAttrUseReferences( 20884 (xmlSchemaAttributeUsePtr) item, pctxt); 20885 FIXHFAILURE; 20886 break; 20887 case XML_SCHEMA_EXTRA_QNAMEREF: 20888 if ((WXS_QNAME_CAST item)->itemType == 20889 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) 20890 { 20891 xmlSchemaResolveAttrGroupReferences( 20892 WXS_QNAME_CAST item, pctxt); 20893 } 20894 FIXHFAILURE; 20895 break; 20896 case XML_SCHEMA_TYPE_SEQUENCE: 20897 case XML_SCHEMA_TYPE_CHOICE: 20898 case XML_SCHEMA_TYPE_ALL: 20899 xmlSchemaResolveModelGroupParticleReferences(pctxt, 20900 WXS_MODEL_GROUP_CAST item); 20901 FIXHFAILURE; 20902 break; 20903 case XML_SCHEMA_TYPE_IDC_KEY: 20904 case XML_SCHEMA_TYPE_IDC_UNIQUE: 20905 case XML_SCHEMA_TYPE_IDC_KEYREF: 20906 xmlSchemaResolveIDCKeyReferences( 20907 (xmlSchemaIDCPtr) item, pctxt); 20908 FIXHFAILURE; 20909 break; 20910 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 20911 /* 20912 * Handle attribue prohibition which had a 20913 * "ref" attribute. 20914 */ 20915 xmlSchemaResolveAttrUseProhibReferences( 20916 WXS_ATTR_PROHIB_CAST item, pctxt); 20917 FIXHFAILURE; 20918 break; 20919 default: 20920 break; 20921 } 20922 } 20923 if (pctxt->nberrors != 0) 20924 goto exit_error; 20925 20926 /* 20927 * Now that all references are resolved we 20928 * can check for circularity of... 20929 * 1. the base axis of type definitions 20930 * 2. nested model group definitions 20931 * 3. nested attribute group definitions 20932 * TODO: check for circual substitution groups. 20933 */ 20934 for (i = 0; i < nbItems; i++) { 20935 item = items[i]; 20936 /* 20937 * Let's better stop on the first error here. 20938 */ 20939 switch (item->type) { 20940 case XML_SCHEMA_TYPE_COMPLEX: 20941 case XML_SCHEMA_TYPE_SIMPLE: 20942 xmlSchemaCheckTypeDefCircular( 20943 (xmlSchemaTypePtr) item, pctxt); 20944 FIXHFAILURE; 20945 if (pctxt->nberrors != 0) 20946 goto exit_error; 20947 break; 20948 case XML_SCHEMA_TYPE_GROUP: 20949 xmlSchemaCheckGroupDefCircular( 20950 (xmlSchemaModelGroupDefPtr) item, pctxt); 20951 FIXHFAILURE; 20952 if (pctxt->nberrors != 0) 20953 goto exit_error; 20954 break; 20955 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20956 xmlSchemaCheckAttrGroupCircular( 20957 (xmlSchemaAttributeGroupPtr) item, pctxt); 20958 FIXHFAILURE; 20959 if (pctxt->nberrors != 0) 20960 goto exit_error; 20961 break; 20962 default: 20963 break; 20964 } 20965 } 20966 if (pctxt->nberrors != 0) 20967 goto exit_error; 20968 /* 20969 * Model group definition references: 20970 * Such a reference is reflected by a particle at the component 20971 * level. Until now the 'term' of such particles pointed 20972 * to the model group definition; this was done, in order to 20973 * ease circularity checks. Now we need to set the 'term' of 20974 * such particles to the model group of the model group definition. 20975 */ 20976 for (i = 0; i < nbItems; i++) { 20977 item = items[i]; 20978 switch (item->type) { 20979 case XML_SCHEMA_TYPE_SEQUENCE: 20980 case XML_SCHEMA_TYPE_CHOICE: 20981 xmlSchemaModelGroupToModelGroupDefFixup(pctxt, 20982 WXS_MODEL_GROUP_CAST item); 20983 break; 20984 default: 20985 break; 20986 } 20987 } 20988 if (pctxt->nberrors != 0) 20989 goto exit_error; 20990 /* 20991 * Expand attribute group references of attribute group definitions. 20992 */ 20993 for (i = 0; i < nbItems; i++) { 20994 item = items[i]; 20995 switch (item->type) { 20996 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 20997 if ((! WXS_ATTR_GROUP_EXPANDED(item)) && 20998 WXS_ATTR_GROUP_HAS_REFS(item)) 20999 { 21000 xmlSchemaAttributeGroupExpandRefs(pctxt, 21001 WXS_ATTR_GROUP_CAST item); 21002 FIXHFAILURE; 21003 } 21004 break; 21005 default: 21006 break; 21007 } 21008 } 21009 if (pctxt->nberrors != 0) 21010 goto exit_error; 21011 /* 21012 * First compute the variety of simple types. This is needed as 21013 * a seperate step, since otherwise we won't be able to detect 21014 * circular union types in all cases. 21015 */ 21016 for (i = 0; i < nbItems; i++) { 21017 item = items[i]; 21018 switch (item->type) { 21019 case XML_SCHEMA_TYPE_SIMPLE: 21020 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) { 21021 xmlSchemaFixupSimpleTypeStageOne(pctxt, 21022 (xmlSchemaTypePtr) item); 21023 FIXHFAILURE; 21024 } 21025 break; 21026 default: 21027 break; 21028 } 21029 } 21030 if (pctxt->nberrors != 0) 21031 goto exit_error; 21032 /* 21033 * Detect circular union types. Note that this needs the variety to 21034 * be already computed. 21035 */ 21036 for (i = 0; i < nbItems; i++) { 21037 item = items[i]; 21038 switch (item->type) { 21039 case XML_SCHEMA_TYPE_SIMPLE: 21040 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) { 21041 xmlSchemaCheckUnionTypeDefCircular(pctxt, 21042 (xmlSchemaTypePtr) item); 21043 FIXHFAILURE; 21044 } 21045 break; 21046 default: 21047 break; 21048 } 21049 } 21050 if (pctxt->nberrors != 0) 21051 goto exit_error; 21052 21053 /* 21054 * Do the complete type fixup for simple types. 21055 */ 21056 for (i = 0; i < nbItems; i++) { 21057 item = items[i]; 21058 switch (item->type) { 21059 case XML_SCHEMA_TYPE_SIMPLE: 21060 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21061 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item); 21062 FIXHFAILURE; 21063 } 21064 break; 21065 default: 21066 break; 21067 } 21068 } 21069 if (pctxt->nberrors != 0) 21070 goto exit_error; 21071 /* 21072 * At this point we need build and check all simple types. 21073 */ 21074 /* 21075 * Apply contraints for attribute declarations. 21076 */ 21077 for (i = 0; i < nbItems; i++) { 21078 item = items[i]; 21079 switch (item->type) { 21080 case XML_SCHEMA_TYPE_ATTRIBUTE: 21081 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item); 21082 FIXHFAILURE; 21083 break; 21084 default: 21085 break; 21086 } 21087 } 21088 if (pctxt->nberrors != 0) 21089 goto exit_error; 21090 /* 21091 * Apply constraints for attribute uses. 21092 */ 21093 for (i = 0; i < nbItems; i++) { 21094 item = items[i]; 21095 switch (item->type) { 21096 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 21097 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) { 21098 xmlSchemaCheckAttrUsePropsCorrect(pctxt, 21099 WXS_ATTR_USE_CAST item); 21100 FIXHFAILURE; 21101 } 21102 break; 21103 default: 21104 break; 21105 } 21106 } 21107 if (pctxt->nberrors != 0) 21108 goto exit_error; 21109 21110 /* 21111 * Apply constraints for attribute group definitions. 21112 */ 21113 for (i = 0; i < nbItems; i++) { 21114 item = items[i]; 21115 switch (item->type) { 21116 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 21117 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) && 21118 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1)) 21119 { 21120 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item); 21121 FIXHFAILURE; 21122 } 21123 break; 21124 default: 21125 break; 21126 } 21127 } 21128 if (pctxt->nberrors != 0) 21129 goto exit_error; 21130 21131 /* 21132 * Apply constraints for redefinitions. 21133 */ 21134 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL) 21135 xmlSchemaCheckSRCRedefineSecond(pctxt); 21136 if (pctxt->nberrors != 0) 21137 goto exit_error; 21138 21139 /* 21140 * Complex types are builded and checked. 21141 */ 21142 for (i = 0; i < nbItems; i++) { 21143 item = con->pending->items[i]; 21144 switch (item->type) { 21145 case XML_SCHEMA_TYPE_COMPLEX: 21146 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) { 21147 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item); 21148 FIXHFAILURE; 21149 } 21150 break; 21151 default: 21152 break; 21153 } 21154 } 21155 if (pctxt->nberrors != 0) 21156 goto exit_error; 21157 21158 /* 21159 * The list could have changed, since xmlSchemaFixupComplexType() 21160 * will create particles and model groups in some cases. 21161 */ 21162 items = (xmlSchemaTreeItemPtr *) con->pending->items; 21163 nbItems = con->pending->nbItems; 21164 21165 /* 21166 * Apply some constraints for element declarations. 21167 */ 21168 for (i = 0; i < nbItems; i++) { 21169 item = items[i]; 21170 switch (item->type) { 21171 case XML_SCHEMA_TYPE_ELEMENT: 21172 elemDecl = (xmlSchemaElementPtr) item; 21173 21174 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0) 21175 { 21176 xmlSchemaCheckElementDeclComponent( 21177 (xmlSchemaElementPtr) elemDecl, pctxt); 21178 FIXHFAILURE; 21179 } 21180 21181 #ifdef WXS_ELEM_DECL_CONS_ENABLED 21182 /* 21183 * Schema Component Constraint: Element Declarations Consistent 21184 * Apply this constraint to local types of element declarations. 21185 */ 21186 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) && 21187 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) && 21188 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl)))) 21189 { 21190 xmlSchemaCheckElementDeclConsistent(pctxt, 21191 WXS_BASIC_CAST elemDecl, 21192 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)), 21193 NULL, NULL, 0); 21194 } 21195 #endif 21196 break; 21197 default: 21198 break; 21199 } 21200 } 21201 if (pctxt->nberrors != 0) 21202 goto exit_error; 21203 21204 /* 21205 * Finally we can build the automaton from the content model of 21206 * complex types. 21207 */ 21208 21209 for (i = 0; i < nbItems; i++) { 21210 item = items[i]; 21211 switch (item->type) { 21212 case XML_SCHEMA_TYPE_COMPLEX: 21213 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt); 21214 /* FIXHFAILURE; */ 21215 break; 21216 default: 21217 break; 21218 } 21219 } 21220 if (pctxt->nberrors != 0) 21221 goto exit_error; 21222 /* 21223 * URGENT TODO: cos-element-consistent 21224 */ 21225 goto exit; 21226 21227 exit_error: 21228 ret = pctxt->err; 21229 goto exit; 21230 21231 exit_failure: 21232 ret = -1; 21233 21234 exit: 21235 /* 21236 * Reset the constructor. This is needed for XSI acquisition, since 21237 * those items will be processed over and over again for every XSI 21238 * if not cleared here. 21239 */ 21240 con->bucket = oldbucket; 21241 con->pending->nbItems = 0; 21242 if (con->substGroups != NULL) { 21243 xmlHashFree(con->substGroups, 21244 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 21245 con->substGroups = NULL; 21246 } 21247 if (con->redefs != NULL) { 21248 xmlSchemaRedefListFree(con->redefs); 21249 con->redefs = NULL; 21250 } 21251 return(ret); 21252 } 21263 xmlSchemaPtr 21264 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt) 21265 { 21266 xmlSchemaPtr mainSchema = NULL; 21267 xmlSchemaBucketPtr bucket = NULL; 21268 int res; 21269 21270 /* 21271 * This one is used if the schema to be parsed was specified via 21272 * the API; i.e. not automatically by the validated instance document. 21273 */ 21274 21275 xmlSchemaInitTypes(); 21276 21277 if (ctxt == NULL) 21278 return (NULL); 21279 21280 /* TODO: Init the context. Is this all we need?*/ 21281 ctxt->nberrors = 0; 21282 ctxt->err = 0; 21283 ctxt->counter = 0; 21284 21285 /* Create the *main* schema. */ 21286 mainSchema = xmlSchemaNewSchema(ctxt); 21287 if (mainSchema == NULL) 21288 goto exit_failure; 21289 /* 21290 * Create the schema constructor. 21291 */ 21292 if (ctxt->constructor == NULL) { 21293 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict); 21294 if (ctxt->constructor == NULL) 21295 return(NULL); 21296 /* Take ownership of the constructor to be able to free it. */ 21297 ctxt->ownsConstructor = 1; 21298 } 21299 ctxt->constructor->mainSchema = mainSchema; 21300 /* 21301 * Locate and add the schema document. 21302 */ 21303 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN, 21304 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL, 21305 NULL, NULL, &bucket); 21306 if (res == -1) 21307 goto exit_failure; 21308 if (res != 0) 21309 goto exit; 21310 21311 if (bucket == NULL) { 21312 /* TODO: Error code, actually we failed to *locate* the schema. */ 21313 if (ctxt->URL) 21314 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21315 NULL, NULL, 21316 "Failed to locate the main schema resource at '%s'", 21317 ctxt->URL, NULL); 21318 else 21319 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD, 21320 NULL, NULL, 21321 "Failed to locate the main schema resource", 21322 NULL, NULL); 21323 goto exit; 21324 } 21325 /* Then do the parsing for good. */ 21326 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1) 21327 goto exit_failure; 21328 if (ctxt->nberrors != 0) 21329 goto exit; 21330 21331 mainSchema->doc = bucket->doc; 21332 mainSchema->preserve = ctxt->preserve; 21333 21334 ctxt->schema = mainSchema; 21335 21336 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1) 21337 goto exit_failure; 21338 21339 /* 21340 * TODO: This is not nice, since we cannot distinguish from the 21341 * result if there was an internal error or not. 21342 */ 21343 exit: 21344 if (ctxt->nberrors != 0) { 21345 if (mainSchema) { 21346 xmlSchemaFree(mainSchema); 21347 mainSchema = NULL; 21348 } 21349 if (ctxt->constructor) { 21350 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21351 ctxt->constructor = NULL; 21352 ctxt->ownsConstructor = 0; 21353 } 21354 } 21355 ctxt->schema = NULL; 21356 return(mainSchema); 21357 exit_failure: 21358 /* 21359 * Quite verbose, but should catch internal errors, which were 21360 * not communitated. 21361 */ 21362 if (mainSchema) { 21363 xmlSchemaFree(mainSchema); 21364 mainSchema = NULL; 21365 } 21366 if (ctxt->constructor) { 21367 xmlSchemaConstructionCtxtFree(ctxt->constructor); 21368 ctxt->constructor = NULL; 21369 ctxt->ownsConstructor = 0; 21370 } 21371 PERROR_INT2("xmlSchemaParse", 21372 "An internal error occured"); 21373 ctxt->schema = NULL; 21374 return(NULL); 21375 } 21376 21386 void 21387 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21388 xmlSchemaValidityErrorFunc err, 21389 xmlSchemaValidityWarningFunc warn, void *ctx) 21390 { 21391 if (ctxt == NULL) 21392 return; 21393 ctxt->error = err; 21394 ctxt->warning = warn; 21395 ctxt->errCtxt = ctx; 21396 if (ctxt->vctxt != NULL) 21397 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx); 21398 } 21399 21408 void 21409 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt, 21410 xmlStructuredErrorFunc serror, 21411 void *ctx) 21412 { 21413 if (ctxt == NULL) 21414 return; 21415 ctxt->serror = serror; 21416 ctxt->errCtxt = ctx; 21417 if (ctxt->vctxt != NULL) 21418 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx); 21419 } 21420 21432 int 21433 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt, 21434 xmlSchemaValidityErrorFunc * err, 21435 xmlSchemaValidityWarningFunc * warn, void **ctx) 21436 { 21437 if (ctxt == NULL) 21438 return(-1); 21439 if (err != NULL) 21440 *err = ctxt->error; 21441 if (warn != NULL) 21442 *warn = ctxt->warning; 21443 if (ctx != NULL) 21444 *ctx = ctxt->errCtxt; 21445 return(0); 21446 } 21447 21457 static const xmlChar * 21458 xmlSchemaFacetTypeToString(xmlSchemaTypeType type) 21459 { 21460 switch (type) { 21461 case XML_SCHEMA_FACET_PATTERN: 21462 return (BAD_CAST "pattern"); 21463 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 21464 return (BAD_CAST "maxExclusive"); 21465 case XML_SCHEMA_FACET_MAXINCLUSIVE: 21466 return (BAD_CAST "maxInclusive"); 21467 case XML_SCHEMA_FACET_MINEXCLUSIVE: 21468 return (BAD_CAST "minExclusive"); 21469 case XML_SCHEMA_FACET_MININCLUSIVE: 21470 return (BAD_CAST "minInclusive"); 21471 case XML_SCHEMA_FACET_WHITESPACE: 21472 return (BAD_CAST "whiteSpace"); 21473 case XML_SCHEMA_FACET_ENUMERATION: 21474 return (BAD_CAST "enumeration"); 21475 case XML_SCHEMA_FACET_LENGTH: 21476 return (BAD_CAST "length"); 21477 case XML_SCHEMA_FACET_MAXLENGTH: 21478 return (BAD_CAST "maxLength"); 21479 case XML_SCHEMA_FACET_MINLENGTH: 21480 return (BAD_CAST "minLength"); 21481 case XML_SCHEMA_FACET_TOTALDIGITS: 21482 return (BAD_CAST "totalDigits"); 21483 case XML_SCHEMA_FACET_FRACTIONDIGITS: 21484 return (BAD_CAST "fractionDigits"); 21485 default: 21486 break; 21487 } 21488 return (BAD_CAST "Internal Error"); 21489 } 21490 21491 static xmlSchemaWhitespaceValueType 21492 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) 21493 { 21494 /* 21495 * The normalization type can be changed only for types which are derived 21496 * from xsd:string. 21497 */ 21498 if (type->type == XML_SCHEMA_TYPE_BASIC) { 21499 /* 21500 * Note that we assume a whitespace of preserve for anySimpleType. 21501 */ 21502 if ((type->builtInType == XML_SCHEMAS_STRING) || 21503 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 21504 return(XML_SCHEMA_WHITESPACE_PRESERVE); 21505 else if (type->builtInType == XML_SCHEMAS_NORMSTRING) 21506 return(XML_SCHEMA_WHITESPACE_REPLACE); 21507 else { 21508 /* 21509 * For all �atomic� datatypes other than string (and types �derived� 21510 * by �restriction� from it) the value of whiteSpace is fixed to 21511 * collapse 21512 * Note that this includes built-in list datatypes. 21513 */ 21514 return(XML_SCHEMA_WHITESPACE_COLLAPSE); 21515 } 21516 } else if (WXS_IS_LIST(type)) { 21517 /* 21518 * For list types the facet "whiteSpace" is fixed to "collapse". 21519 */ 21520 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21521 } else if (WXS_IS_UNION(type)) { 21522 return (XML_SCHEMA_WHITESPACE_UNKNOWN); 21523 } else if (WXS_IS_ATOMIC(type)) { 21524 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE) 21525 return (XML_SCHEMA_WHITESPACE_PRESERVE); 21526 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE) 21527 return (XML_SCHEMA_WHITESPACE_REPLACE); 21528 else 21529 return (XML_SCHEMA_WHITESPACE_COLLAPSE); 21530 } 21531 return (-1); 21532 } 21533 21534 /************************************************************************ 21535 * * 21536 * Simple type validation * 21537 * * 21538 ************************************************************************/ 21539 21540 21541 /************************************************************************ 21542 * * 21543 * DOM Validation code * 21544 * * 21545 ************************************************************************/ 21546 21561 static int 21562 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt, 21563 xmlSchemaPtr schema, 21564 xmlNodePtr node, 21565 const xmlChar *nsName, 21566 const xmlChar *location) 21567 { 21568 int ret = 0; 21569 xmlSchemaParserCtxtPtr pctxt; 21570 xmlSchemaBucketPtr bucket = NULL; 21571 21572 if ((vctxt == NULL) || (schema == NULL)) 21573 return (-1); 21574 21575 if (vctxt->pctxt == NULL) { 21576 VERROR_INT("xmlSchemaAssembleByLocation", 21577 "no parser context available"); 21578 return(-1); 21579 } 21580 pctxt = vctxt->pctxt; 21581 if (pctxt->constructor == NULL) { 21582 PERROR_INT("xmlSchemaAssembleByLocation", 21583 "no constructor"); 21584 return(-1); 21585 } 21586 /* 21587 * Acquire the schema document. 21588 */ 21589 location = xmlSchemaBuildAbsoluteURI(pctxt->dict, 21590 location, node); 21591 /* 21592 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here; 21593 * the process will automatically change this to 21594 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document. 21595 */ 21596 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 21597 location, NULL, NULL, 0, node, NULL, nsName, 21598 &bucket); 21599 if (ret != 0) 21600 return(ret); 21601 if (bucket == NULL) { 21602 /* 21603 * Generate a warning that the document could not be located. 21604 */ 21605 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21606 node, NULL, 21607 "The document at location '%s' could not be acquired", 21608 location, NULL, NULL); 21609 return(ret); 21610 } 21611 /* 21612 * The first located schema will be handled as if all other 21613 * schemas imported by XSI were imported by this first schema. 21614 */ 21615 if ((bucket != NULL) && 21616 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL)) 21617 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 21618 /* 21619 * TODO: Is this handled like an import? I.e. is it not an error 21620 * if the schema cannot be located? 21621 */ 21622 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket))) 21623 return(0); 21624 /* 21625 * We will reuse the parser context for every schema imported 21626 * directly via XSI. So reset the context. 21627 */ 21628 pctxt->nberrors = 0; 21629 pctxt->err = 0; 21630 pctxt->doc = bucket->doc; 21631 21632 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket); 21633 if (ret == -1) { 21634 pctxt->doc = NULL; 21635 goto exit_failure; 21636 } 21637 /* Paranoid error channelling. */ 21638 if ((ret == 0) && (pctxt->nberrors != 0)) 21639 ret = pctxt->err; 21640 if (pctxt->nberrors == 0) { 21641 /* 21642 * Only bother to fixup pending components, if there was 21643 * no error yet. 21644 * For every XSI acquired schema (and its sub-schemata) we will 21645 * fixup the components. 21646 */ 21647 xmlSchemaFixupComponents(pctxt, bucket); 21648 ret = pctxt->err; 21649 /* 21650 * Not nice, but we need somehow to channel the schema parser 21651 * error to the validation context. 21652 */ 21653 if ((ret != 0) && (vctxt->err == 0)) 21654 vctxt->err = ret; 21655 vctxt->nberrors += pctxt->nberrors; 21656 } else { 21657 /* Add to validation error sum. */ 21658 vctxt->nberrors += pctxt->nberrors; 21659 } 21660 pctxt->doc = NULL; 21661 return(ret); 21662 exit_failure: 21663 pctxt->doc = NULL; 21664 return (-1); 21665 } 21666 21667 static xmlSchemaAttrInfoPtr 21668 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt, 21669 int metaType) 21670 { 21671 if (vctxt->nbAttrInfos == 0) 21672 return (NULL); 21673 { 21674 int i; 21675 xmlSchemaAttrInfoPtr iattr; 21676 21677 for (i = 0; i < vctxt->nbAttrInfos; i++) { 21678 iattr = vctxt->attrInfos[i]; 21679 if (iattr->metaType == metaType) 21680 return (iattr); 21681 } 21682 21683 } 21684 return (NULL); 21685 } 21686 21699 static int 21700 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt) 21701 { 21702 const xmlChar *cur, *end; 21703 const xmlChar *nsname = NULL, *location; 21704 int count = 0; 21705 int ret = 0; 21706 xmlSchemaAttrInfoPtr iattr; 21707 21708 /* 21709 * Parse the value; we will assume an even number of values 21710 * to be given (this is how Xerces and XSV work). 21711 * 21712 * URGENT TODO: !! This needs to work for both 21713 * @noNamespaceSchemaLocation AND @schemaLocation on the same 21714 * element !! 21715 */ 21716 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21717 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC); 21718 if (iattr == NULL) 21719 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 21720 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC); 21721 if (iattr == NULL) 21722 return (0); 21723 cur = iattr->value; 21724 do { 21725 /* 21726 * TODO: Move the string parsing mechanism away from here. 21727 */ 21728 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) { 21729 /* 21730 * Get the namespace name. 21731 */ 21732 while (IS_BLANK_CH(*cur)) 21733 cur++; 21734 end = cur; 21735 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21736 end++; 21737 if (end == cur) 21738 break; 21739 count++; /* TODO: Don't use the schema's dict. */ 21740 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21741 cur = end; 21742 } 21743 /* 21744 * Get the URI. 21745 */ 21746 while (IS_BLANK_CH(*cur)) 21747 cur++; 21748 end = cur; 21749 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 21750 end++; 21751 if (end == cur) { 21752 if (iattr->metaType == 21753 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) 21754 { 21755 /* 21756 * If using @schemaLocation then tuples are expected. 21757 * I.e. the namespace name *and* the document's URI. 21758 */ 21759 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC, 21760 iattr->node, NULL, 21761 "The value must consist of tuples: the target namespace " 21762 "name and the document's URI", NULL, NULL, NULL); 21763 } 21764 break; 21765 } 21766 count++; /* TODO: Don't use the schema's dict. */ 21767 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur); 21768 cur = end; 21769 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema, 21770 iattr->node, nsname, location); 21771 if (ret == -1) { 21772 VERROR_INT("xmlSchemaAssembleByXSI", 21773 "assembling schemata"); 21774 return (-1); 21775 } 21776 } while (*cur != 0); 21777 return (ret); 21778 } 21779 21780 static const xmlChar * 21781 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt, 21782 const xmlChar *prefix) 21783 { 21784 if (vctxt->sax != NULL) { 21785 int i, j; 21786 xmlSchemaNodeInfoPtr inode; 21787 21788 for (i = vctxt->depth; i >= 0; i--) { 21789 if (vctxt->elemInfos[i]->nbNsBindings != 0) { 21790 inode = vctxt->elemInfos[i]; 21791 for (j = 0; j < inode->nbNsBindings * 2; j += 2) { 21792 if (((prefix == NULL) && 21793 (inode->nsBindings[j] == NULL)) || 21794 ((prefix != NULL) && xmlStrEqual(prefix, 21795 inode->nsBindings[j]))) { 21796 21797 /* 21798 * Note that the namespace bindings are already 21799 * in a string dict. 21800 */ 21801 return (inode->nsBindings[j+1]); 21802 } 21803 } 21804 } 21805 } 21806 return (NULL); 21807 #ifdef LIBXML_READER_ENABLED 21808 } else if (vctxt->reader != NULL) { 21809 xmlChar *nsName; 21810 21811 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix); 21812 if (nsName != NULL) { 21813 const xmlChar *ret; 21814 21815 ret = xmlDictLookup(vctxt->dict, nsName, -1); 21816 xmlFree(nsName); 21817 return (ret); 21818 } else 21819 return (NULL); 21820 #endif 21821 } else { 21822 xmlNsPtr ns; 21823 21824 if ((vctxt->inode->node == NULL) || 21825 (vctxt->inode->node->doc == NULL)) { 21826 VERROR_INT("xmlSchemaLookupNamespace", 21827 "no node or node's doc avaliable"); 21828 return (NULL); 21829 } 21830 ns = xmlSearchNs(vctxt->inode->node->doc, 21831 vctxt->inode->node, prefix); 21832 if (ns != NULL) 21833 return (ns->href); 21834 return (NULL); 21835 } 21836 } 21837 21838 /* 21839 * This one works on the schema of the validation context. 21840 */ 21841 static int 21842 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt, 21843 xmlSchemaPtr schema, 21844 xmlNodePtr node, 21845 const xmlChar *value, 21846 xmlSchemaValPtr *val, 21847 int valNeeded) 21848 { 21849 int ret; 21850 21851 if (vctxt && (vctxt->schema == NULL)) { 21852 VERROR_INT("xmlSchemaValidateNotation", 21853 "a schema is needed on the validation context"); 21854 return (-1); 21855 } 21856 ret = xmlValidateQName(value, 1); 21857 if (ret != 0) 21858 return (ret); 21859 { 21860 xmlChar *localName = NULL; 21861 xmlChar *prefix = NULL; 21862 21863 localName = xmlSplitQName2(value, &prefix); 21864 if (prefix != NULL) { 21865 const xmlChar *nsName = NULL; 21866 21867 if (vctxt != NULL) 21868 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix); 21869 else if (node != NULL) { 21870 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix); 21871 if (ns != NULL) 21872 nsName = ns->href; 21873 } else { 21874 xmlFree(prefix); 21875 xmlFree(localName); 21876 return (1); 21877 } 21878 if (nsName == NULL) { 21879 xmlFree(prefix); 21880 xmlFree(localName); 21881 return (1); 21882 } 21883 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) { 21884 if ((valNeeded) && (val != NULL)) { 21885 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName), 21886 xmlStrdup(nsName)); 21887 if (*val == NULL) 21888 ret = -1; 21889 } 21890 } else 21891 ret = 1; 21892 xmlFree(prefix); 21893 xmlFree(localName); 21894 } else { 21895 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) { 21896 if (valNeeded && (val != NULL)) { 21897 (*val) = xmlSchemaNewNOTATIONValue( 21898 BAD_CAST xmlStrdup(value), NULL); 21899 if (*val == NULL) 21900 ret = -1; 21901 } 21902 } else 21903 return (1); 21904 } 21905 } 21906 return (ret); 21907 } 21908 21909 static int 21910 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, 21911 const xmlChar* lname, 21912 const xmlChar* nsname) 21913 { 21914 int i; 21915 21916 lname = xmlDictLookup(vctxt->dict, lname, -1); 21917 if (lname == NULL) 21918 return(-1); 21919 if (nsname != NULL) { 21920 nsname = xmlDictLookup(vctxt->dict, nsname, -1); 21921 if (nsname == NULL) 21922 return(-1); 21923 } 21924 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) { 21925 if ((vctxt->nodeQNames->items [i] == lname) && 21926 (vctxt->nodeQNames->items[i +1] == nsname)) 21927 /* Already there */ 21928 return(i); 21929 } 21930 /* Add new entry. */ 21931 i = vctxt->nodeQNames->nbItems; 21932 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname); 21933 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname); 21934 return(i); 21935 } 21936 21937 /************************************************************************ 21938 * * 21939 * Validation of identity-constraints (IDC) * 21940 * * 21941 ************************************************************************/ 21942 21951 static void 21952 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, 21953 xmlSchemaValidCtxtPtr vctxt) 21954 { 21955 xmlSchemaIDCAugPtr aidc; 21956 21957 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); 21958 if (aidc == NULL) { 21959 xmlSchemaVErrMemory(vctxt, 21960 "xmlSchemaAugmentIDC: allocating an augmented IDC definition", 21961 NULL); 21962 return; 21963 } 21964 aidc->keyrefDepth = -1; 21965 aidc->def = idcDef; 21966 aidc->next = NULL; 21967 if (vctxt->aidcs == NULL) 21968 vctxt->aidcs = aidc; 21969 else { 21970 aidc->next = vctxt->aidcs; 21971 vctxt->aidcs = aidc; 21972 } 21973 /* 21974 * Save if we have keyrefs at all. 21975 */ 21976 if ((vctxt->hasKeyrefs == 0) && 21977 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF)) 21978 vctxt->hasKeyrefs = 1; 21979 } 21980 21987 static void 21988 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) { 21989 if (imported->schema->idcDef != NULL) { 21990 xmlHashScan(imported->schema->idcDef , 21991 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt); 21992 } 21993 } 21994 22003 static xmlSchemaPSVIIDCBindingPtr 22004 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef) 22005 { 22006 xmlSchemaPSVIIDCBindingPtr ret; 22007 22008 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc( 22009 sizeof(xmlSchemaPSVIIDCBinding)); 22010 if (ret == NULL) { 22011 xmlSchemaVErrMemory(NULL, 22012 "allocating a PSVI IDC binding item", NULL); 22013 return (NULL); 22014 } 22015 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding)); 22016 ret->definition = idcDef; 22017 return (ret); 22018 } 22019 22031 static int 22032 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt, 22033 xmlSchemaPSVIIDCNodePtr item) 22034 { 22035 /* 22036 * Add to gobal list. 22037 */ 22038 if (vctxt->idcNodes == NULL) { 22039 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22040 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22041 if (vctxt->idcNodes == NULL) { 22042 xmlSchemaVErrMemory(vctxt, 22043 "allocating the IDC node table item list", NULL); 22044 return (-1); 22045 } 22046 vctxt->sizeIdcNodes = 20; 22047 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) { 22048 vctxt->sizeIdcNodes *= 2; 22049 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *) 22050 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes * 22051 sizeof(xmlSchemaPSVIIDCNodePtr)); 22052 if (vctxt->idcNodes == NULL) { 22053 xmlSchemaVErrMemory(vctxt, 22054 "re-allocating the IDC node table item list", NULL); 22055 return (-1); 22056 } 22057 } 22058 vctxt->idcNodes[vctxt->nbIdcNodes++] = item; 22059 22060 return (0); 22061 } 22062 22072 static int 22073 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt, 22074 xmlSchemaPSVIIDCKeyPtr key) 22075 { 22076 /* 22077 * Add to gobal list. 22078 */ 22079 if (vctxt->idcKeys == NULL) { 22080 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22081 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr)); 22082 if (vctxt->idcKeys == NULL) { 22083 xmlSchemaVErrMemory(vctxt, 22084 "allocating the IDC key storage list", NULL); 22085 return (-1); 22086 } 22087 vctxt->sizeIdcKeys = 40; 22088 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) { 22089 vctxt->sizeIdcKeys *= 2; 22090 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *) 22091 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys * 22092 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22093 if (vctxt->idcKeys == NULL) { 22094 xmlSchemaVErrMemory(vctxt, 22095 "re-allocating the IDC key storage list", NULL); 22096 return (-1); 22097 } 22098 } 22099 vctxt->idcKeys[vctxt->nbIdcKeys++] = key; 22100 22101 return (0); 22102 } 22103 22113 static int 22114 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind, 22115 xmlSchemaPSVIIDCNodePtr ntItem) 22116 { 22117 if (bind->nodeTable == NULL) { 22118 bind->sizeNodes = 10; 22119 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22120 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 22121 if (bind->nodeTable == NULL) { 22122 xmlSchemaVErrMemory(NULL, 22123 "allocating an array of IDC node-table items", NULL); 22124 return(-1); 22125 } 22126 } else if (bind->sizeNodes <= bind->nbNodes) { 22127 bind->sizeNodes *= 2; 22128 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 22129 xmlRealloc(bind->nodeTable, bind->sizeNodes * 22130 sizeof(xmlSchemaPSVIIDCNodePtr)); 22131 if (bind->nodeTable == NULL) { 22132 xmlSchemaVErrMemory(NULL, 22133 "re-allocating an array of IDC node-table items", NULL); 22134 return(-1); 22135 } 22136 } 22137 bind->nodeTable[bind->nbNodes++] = ntItem; 22138 return(0); 22139 } 22140 22152 static xmlSchemaPSVIIDCBindingPtr 22153 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt, 22154 xmlSchemaIDCMatcherPtr matcher) 22155 { 22156 xmlSchemaNodeInfoPtr ielem; 22157 22158 ielem = vctxt->elemInfos[matcher->depth]; 22159 22160 if (ielem->idcTable == NULL) { 22161 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def); 22162 if (ielem->idcTable == NULL) 22163 return (NULL); 22164 return(ielem->idcTable); 22165 } else { 22166 xmlSchemaPSVIIDCBindingPtr bind = NULL; 22167 22168 bind = ielem->idcTable; 22169 do { 22170 if (bind->definition == matcher->aidc->def) 22171 return(bind); 22172 if (bind->next == NULL) { 22173 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def); 22174 if (bind->next == NULL) 22175 return (NULL); 22176 return(bind->next); 22177 } 22178 bind = bind->next; 22179 } while (bind != NULL); 22180 } 22181 return (NULL); 22182 } 22183 22184 static xmlSchemaItemListPtr 22185 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 22186 xmlSchemaIDCMatcherPtr matcher) 22187 { 22188 if (matcher->targets == NULL) 22189 matcher->targets = xmlSchemaItemListCreate(); 22190 return(matcher->targets); 22191 } 22192 22199 static void 22200 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key) 22201 { 22202 if (key->val != NULL) 22203 xmlSchemaFreeValue(key->val); 22204 xmlFree(key); 22205 } 22206 22213 static void 22214 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind) 22215 { 22216 if (bind->nodeTable != NULL) 22217 xmlFree(bind->nodeTable); 22218 if (bind->dupls != NULL) 22219 xmlSchemaItemListFree(bind->dupls); 22220 xmlFree(bind); 22221 } 22222 22229 static void 22230 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind) 22231 { 22232 xmlSchemaPSVIIDCBindingPtr prev; 22233 22234 while (bind != NULL) { 22235 prev = bind; 22236 bind = bind->next; 22237 xmlSchemaIDCFreeBinding(prev); 22238 } 22239 } 22240 22247 static void 22248 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher) 22249 { 22250 xmlSchemaIDCMatcherPtr next; 22251 22252 while (matcher != NULL) { 22253 next = matcher->next; 22254 if (matcher->keySeqs != NULL) { 22255 int i; 22256 for (i = 0; i < matcher->sizeKeySeqs; i++) 22257 if (matcher->keySeqs[i] != NULL) 22258 xmlFree(matcher->keySeqs[i]); 22259 xmlFree(matcher->keySeqs); 22260 } 22261 if (matcher->targets != NULL) { 22262 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22263 int i; 22264 xmlSchemaPSVIIDCNodePtr idcNode; 22265 /* 22266 * Node-table items for keyrefs are not stored globally 22267 * to the validation context, since they are not bubbled. 22268 * We need to free them here. 22269 */ 22270 for (i = 0; i < matcher->targets->nbItems; i++) { 22271 idcNode = 22272 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22273 xmlFree(idcNode->keys); 22274 xmlFree(idcNode); 22275 } 22276 } 22277 xmlSchemaItemListFree(matcher->targets); 22278 } 22279 xmlFree(matcher); 22280 matcher = next; 22281 } 22282 } 22283 22291 static void 22292 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt, 22293 xmlSchemaIDCMatcherPtr matcher) 22294 { 22295 xmlSchemaIDCMatcherPtr next; 22296 22297 while (matcher != NULL) { 22298 next = matcher->next; 22299 if (matcher->keySeqs != NULL) { 22300 int i; 22301 /* 22302 * Don't free the array, but only the content. 22303 */ 22304 for (i = 0; i < matcher->sizeKeySeqs; i++) 22305 if (matcher->keySeqs[i] != NULL) { 22306 xmlFree(matcher->keySeqs[i]); 22307 matcher->keySeqs[i] = NULL; 22308 } 22309 } 22310 if (matcher->targets) { 22311 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) { 22312 int i; 22313 xmlSchemaPSVIIDCNodePtr idcNode; 22314 /* 22315 * Node-table items for keyrefs are not stored globally 22316 * to the validation context, since they are not bubbled. 22317 * We need to free them here. 22318 */ 22319 for (i = 0; i < matcher->targets->nbItems; i++) { 22320 idcNode = 22321 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i]; 22322 xmlFree(idcNode->keys); 22323 xmlFree(idcNode); 22324 } 22325 } 22326 xmlSchemaItemListFree(matcher->targets); 22327 matcher->targets = NULL; 22328 } 22329 matcher->next = NULL; 22330 /* 22331 * Cache the matcher. 22332 */ 22333 if (vctxt->idcMatcherCache != NULL) 22334 matcher->nextCached = vctxt->idcMatcherCache; 22335 vctxt->idcMatcherCache = matcher; 22336 22337 matcher = next; 22338 } 22339 } 22340 22355 static int 22356 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt, 22357 xmlSchemaIDCMatcherPtr matcher, 22358 xmlSchemaIDCSelectPtr sel, 22359 int type) 22360 { 22361 xmlSchemaIDCStateObjPtr sto; 22362 22363 /* 22364 * Reuse the state objects from the pool. 22365 */ 22366 if (vctxt->xpathStatePool != NULL) { 22367 sto = vctxt->xpathStatePool; 22368 vctxt->xpathStatePool = sto->next; 22369 sto->next = NULL; 22370 } else { 22371 /* 22372 * Create a new state object. 22373 */ 22374 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj)); 22375 if (sto == NULL) { 22376 xmlSchemaVErrMemory(NULL, 22377 "allocating an IDC state object", NULL); 22378 return (-1); 22379 } 22380 memset(sto, 0, sizeof(xmlSchemaIDCStateObj)); 22381 } 22382 /* 22383 * Add to global list. 22384 */ 22385 if (vctxt->xpathStates != NULL) 22386 sto->next = vctxt->xpathStates; 22387 vctxt->xpathStates = sto; 22388 22389 /* 22390 * Free the old xpath validation context. 22391 */ 22392 if (sto->xpathCtxt != NULL) 22393 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 22394 22395 /* 22396 * Create a new XPath (pattern) validation context. 22397 */ 22398 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt( 22399 (xmlPatternPtr) sel->xpathComp); 22400 if (sto->xpathCtxt == NULL) { 22401 VERROR_INT("xmlSchemaIDCAddStateObject", 22402 "failed to create an XPath validation context"); 22403 return (-1); 22404 } 22405 sto->type = type; 22406 sto->depth = vctxt->depth; 22407 sto->matcher = matcher; 22408 sto->sel = sel; 22409 sto->nbHistory = 0; 22410 22411 #ifdef DEBUG_IDC 22412 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n", 22413 sto->sel->xpath); 22414 #endif 22415 return (0); 22416 } 22417 22428 static int 22429 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt, 22430 xmlElementType nodeType) 22431 { 22432 xmlSchemaIDCStateObjPtr sto, head = NULL, first; 22433 int res, resolved = 0, depth = vctxt->depth; 22434 22435 if (vctxt->xpathStates == NULL) 22436 return (0); 22437 22438 if (nodeType == XML_ATTRIBUTE_NODE) 22439 depth++; 22440 #ifdef DEBUG_IDC 22441 { 22442 xmlChar *str = NULL; 22443 xmlGenericError(xmlGenericErrorContext, 22444 "IDC: EVAL on %s, depth %d, type %d\n", 22445 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22446 vctxt->inode->localName), depth, nodeType); 22447 FREE_AND_NULL(str) 22448 } 22449 #endif 22450 /* 22451 * Process all active XPath state objects. 22452 */ 22453 first = vctxt->xpathStates; 22454 sto = first; 22455 while (sto != head) { 22456 #ifdef DEBUG_IDC 22457 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) 22458 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n", 22459 sto->matcher->aidc->def->name, sto->sel->xpath); 22460 else 22461 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n", 22462 sto->matcher->aidc->def->name, sto->sel->xpath); 22463 #endif 22464 if (nodeType == XML_ELEMENT_NODE) 22465 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt, 22466 vctxt->inode->localName, vctxt->inode->nsName); 22467 else 22468 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt, 22469 vctxt->inode->localName, vctxt->inode->nsName); 22470 22471 if (res == -1) { 22472 VERROR_INT("xmlSchemaXPathEvaluate", 22473 "calling xmlStreamPush()"); 22474 return (-1); 22475 } 22476 if (res == 0) 22477 goto next_sto; 22478 /* 22479 * Full match. 22480 */ 22481 #ifdef DEBUG_IDC 22482 xmlGenericError(xmlGenericErrorContext, "IDC: " 22483 "MATCH\n"); 22484 #endif 22485 /* 22486 * Register a match in the state object history. 22487 */ 22488 if (sto->history == NULL) { 22489 sto->history = (int *) xmlMalloc(5 * sizeof(int)); 22490 if (sto->history == NULL) { 22491 xmlSchemaVErrMemory(NULL, 22492 "allocating the state object history", NULL); 22493 return(-1); 22494 } 22495 sto->sizeHistory = 5; 22496 } else if (sto->sizeHistory <= sto->nbHistory) { 22497 sto->sizeHistory *= 2; 22498 sto->history = (int *) xmlRealloc(sto->history, 22499 sto->sizeHistory * sizeof(int)); 22500 if (sto->history == NULL) { 22501 xmlSchemaVErrMemory(NULL, 22502 "re-allocating the state object history", NULL); 22503 return(-1); 22504 } 22505 } 22506 sto->history[sto->nbHistory++] = depth; 22507 22508 #ifdef DEBUG_IDC 22509 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n", 22510 vctxt->depth); 22511 #endif 22512 22513 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22514 xmlSchemaIDCSelectPtr sel; 22515 /* 22516 * Activate state objects for the IDC fields of 22517 * the IDC selector. 22518 */ 22519 #ifdef DEBUG_IDC 22520 xmlGenericError(xmlGenericErrorContext, "IDC: " 22521 "activating field states\n"); 22522 #endif 22523 sel = sto->matcher->aidc->def->fields; 22524 while (sel != NULL) { 22525 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher, 22526 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1) 22527 return (-1); 22528 sel = sel->next; 22529 } 22530 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22531 /* 22532 * An IDC key node was found by the IDC field. 22533 */ 22534 #ifdef DEBUG_IDC 22535 xmlGenericError(xmlGenericErrorContext, 22536 "IDC: key found\n"); 22537 #endif 22538 /* 22539 * Notify that the character value of this node is 22540 * needed. 22541 */ 22542 if (resolved == 0) { 22543 if ((vctxt->inode->flags & 22544 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0) 22545 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 22546 } 22547 resolved++; 22548 } 22549 next_sto: 22550 if (sto->next == NULL) { 22551 /* 22552 * Evaluate field state objects created on this node as well. 22553 */ 22554 head = first; 22555 sto = vctxt->xpathStates; 22556 } else 22557 sto = sto->next; 22558 } 22559 return (resolved); 22560 } 22561 22562 static const xmlChar * 22563 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt, 22564 xmlChar **buf, 22565 xmlSchemaPSVIIDCKeyPtr *seq, 22566 int count) 22567 { 22568 int i, res; 22569 xmlChar *value = NULL; 22570 22571 *buf = xmlStrdup(BAD_CAST "["); 22572 for (i = 0; i < count; i++) { 22573 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22574 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val, 22575 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type), 22576 &value); 22577 if (res == 0) 22578 *buf = xmlStrcat(*buf, BAD_CAST value); 22579 else { 22580 VERROR_INT("xmlSchemaFormatIDCKeySequence", 22581 "failed to compute a canonical value"); 22582 *buf = xmlStrcat(*buf, BAD_CAST "???"); 22583 } 22584 if (i < count -1) 22585 *buf = xmlStrcat(*buf, BAD_CAST "', "); 22586 else 22587 *buf = xmlStrcat(*buf, BAD_CAST "'"); 22588 if (value != NULL) { 22589 xmlFree(value); 22590 value = NULL; 22591 } 22592 } 22593 *buf = xmlStrcat(*buf, BAD_CAST "]"); 22594 22595 return (BAD_CAST *buf); 22596 } 22597 22606 static int 22607 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt) 22608 { 22609 xmlSchemaIDCStateObjPtr sto; 22610 int res; 22611 22612 if (vctxt->xpathStates == NULL) 22613 return(0); 22614 sto = vctxt->xpathStates; 22615 do { 22616 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22617 if (res == -1) 22618 return (-1); 22619 sto = sto->next; 22620 } while (sto != NULL); 22621 return(0); 22622 } 22623 22635 static int 22636 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt, 22637 int depth) 22638 { 22639 xmlSchemaIDCStateObjPtr sto, nextsto; 22640 int res, matchDepth; 22641 xmlSchemaPSVIIDCKeyPtr key = NULL; 22642 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL; 22643 22644 if (vctxt->xpathStates == NULL) 22645 return (0); 22646 sto = vctxt->xpathStates; 22647 22648 #ifdef DEBUG_IDC 22649 { 22650 xmlChar *str = NULL; 22651 xmlGenericError(xmlGenericErrorContext, 22652 "IDC: BACK on %s, depth %d\n", 22653 xmlSchemaFormatQName(&str, vctxt->inode->nsName, 22654 vctxt->inode->localName), vctxt->depth); 22655 FREE_AND_NULL(str) 22656 } 22657 #endif 22658 /* 22659 * Evaluate the state objects. 22660 */ 22661 while (sto != NULL) { 22662 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt); 22663 if (res == -1) { 22664 VERROR_INT("xmlSchemaXPathProcessHistory", 22665 "calling xmlStreamPop()"); 22666 return (-1); 22667 } 22668 #ifdef DEBUG_IDC 22669 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n", 22670 sto->sel->xpath); 22671 #endif 22672 if (sto->nbHistory == 0) 22673 goto deregister_check; 22674 22675 matchDepth = sto->history[sto->nbHistory -1]; 22676 22677 /* 22678 * Only matches at the current depth are of interest. 22679 */ 22680 if (matchDepth != depth) { 22681 sto = sto->next; 22682 continue; 22683 } 22684 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) { 22685 /* 22686 * NOTE: According to 22687 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198 22688 * ... the simple-content of complex types is also allowed. 22689 */ 22690 22691 if (WXS_IS_COMPLEX(type)) { 22692 if (WXS_HAS_SIMPLE_CONTENT(type)) { 22693 /* 22694 * Sanity check for complex types with simple content. 22695 */ 22696 simpleType = type->contentTypeDef; 22697 if (simpleType == NULL) { 22698 VERROR_INT("xmlSchemaXPathProcessHistory", 22699 "field resolves to a CT with simple content " 22700 "but the CT is missing the ST definition"); 22701 return (-1); 22702 } 22703 } else 22704 simpleType = NULL; 22705 } else 22706 simpleType = type; 22707 if (simpleType == NULL) { 22708 xmlChar *str = NULL; 22709 22710 /* 22711 * Not qualified if the field resolves to a node of non 22712 * simple type. 22713 */ 22714 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22715 XML_SCHEMAV_CVC_IDC, NULL, 22716 WXS_BASIC_CAST sto->matcher->aidc->def, 22717 "The XPath '%s' of a field of %s does evaluate to a node of " 22718 "non-simple type", 22719 sto->sel->xpath, 22720 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def)); 22721 FREE_AND_NULL(str); 22722 sto->nbHistory--; 22723 goto deregister_check; 22724 } 22725 22726 if ((key == NULL) && (vctxt->inode->val == NULL)) { 22727 /* 22728 * Failed to provide the normalized value; maybe 22729 * the value was invalid. 22730 */ 22731 VERROR(XML_SCHEMAV_CVC_IDC, 22732 WXS_BASIC_CAST sto->matcher->aidc->def, 22733 "Warning: No precomputed value available, the value " 22734 "was either invalid or something strange happend"); 22735 sto->nbHistory--; 22736 goto deregister_check; 22737 } else { 22738 xmlSchemaIDCMatcherPtr matcher = sto->matcher; 22739 xmlSchemaPSVIIDCKeyPtr *keySeq; 22740 int pos, idx; 22741 22742 /* 22743 * The key will be anchored on the matcher's list of 22744 * key-sequences. The position in this list is determined 22745 * by the target node's depth relative to the matcher's 22746 * depth of creation (i.e. the depth of the scope element). 22747 * 22748 * Element Depth Pos List-entries 22749 * <scope> 0 NULL 22750 * <bar> 1 NULL 22751 * <target/> 2 2 target 22752 * <bar> 22753 * </scope> 22754 * 22755 * The size of the list is only dependant on the depth of 22756 * the tree. 22757 * An entry will be NULLed in selector_leave, i.e. when 22758 * we hit the target's 22759 */ 22760 pos = sto->depth - matcher->depth; 22761 idx = sto->sel->index; 22762 22763 /* 22764 * Create/grow the array of key-sequences. 22765 */ 22766 if (matcher->keySeqs == NULL) { 22767 if (pos > 9) 22768 matcher->sizeKeySeqs = pos * 2; 22769 else 22770 matcher->sizeKeySeqs = 10; 22771 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22772 xmlMalloc(matcher->sizeKeySeqs * 22773 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22774 if (matcher->keySeqs == NULL) { 22775 xmlSchemaVErrMemory(NULL, 22776 "allocating an array of key-sequences", 22777 NULL); 22778 return(-1); 22779 } 22780 memset(matcher->keySeqs, 0, 22781 matcher->sizeKeySeqs * 22782 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22783 } else if (pos >= matcher->sizeKeySeqs) { 22784 int i = matcher->sizeKeySeqs; 22785 22786 matcher->sizeKeySeqs *= 2; 22787 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) 22788 xmlRealloc(matcher->keySeqs, 22789 matcher->sizeKeySeqs * 22790 sizeof(xmlSchemaPSVIIDCKeyPtr *)); 22791 if (matcher->keySeqs == NULL) { 22792 xmlSchemaVErrMemory(NULL, 22793 "reallocating an array of key-sequences", 22794 NULL); 22795 return (-1); 22796 } 22797 /* 22798 * The array needs to be NULLed. 22799 * TODO: Use memset? 22800 */ 22801 for (; i < matcher->sizeKeySeqs; i++) 22802 matcher->keySeqs[i] = NULL; 22803 } 22804 22805 /* 22806 * Get/create the key-sequence. 22807 */ 22808 keySeq = matcher->keySeqs[pos]; 22809 if (keySeq == NULL) { 22810 goto create_sequence; 22811 } else if (keySeq[idx] != NULL) { 22812 xmlChar *str = NULL; 22813 /* 22814 * cvc-identity-constraint: 22815 * 3 For each node in the �target node set� all 22816 * of the {fields}, with that node as the context 22817 * node, evaluate to either an empty node-set or 22818 * a node-set with exactly one member, which must 22819 * have a simple type. 22820 * 22821 * The key was already set; report an error. 22822 */ 22823 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22824 XML_SCHEMAV_CVC_IDC, NULL, 22825 WXS_BASIC_CAST matcher->aidc->def, 22826 "The XPath '%s' of a field of %s evaluates to a " 22827 "node-set with more than one member", 22828 sto->sel->xpath, 22829 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def)); 22830 FREE_AND_NULL(str); 22831 sto->nbHistory--; 22832 goto deregister_check; 22833 } else 22834 goto create_key; 22835 22836 create_sequence: 22837 /* 22838 * Create a key-sequence. 22839 */ 22840 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc( 22841 matcher->aidc->def->nbFields * 22842 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22843 if (keySeq == NULL) { 22844 xmlSchemaVErrMemory(NULL, 22845 "allocating an IDC key-sequence", NULL); 22846 return(-1); 22847 } 22848 memset(keySeq, 0, matcher->aidc->def->nbFields * 22849 sizeof(xmlSchemaPSVIIDCKeyPtr)); 22850 matcher->keySeqs[pos] = keySeq; 22851 create_key: 22852 /* 22853 * Create a key once per node only. 22854 */ 22855 if (key == NULL) { 22856 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc( 22857 sizeof(xmlSchemaPSVIIDCKey)); 22858 if (key == NULL) { 22859 xmlSchemaVErrMemory(NULL, 22860 "allocating a IDC key", NULL); 22861 xmlFree(keySeq); 22862 matcher->keySeqs[pos] = NULL; 22863 return(-1); 22864 } 22865 /* 22866 * Consume the compiled value. 22867 */ 22868 key->type = simpleType; 22869 key->val = vctxt->inode->val; 22870 vctxt->inode->val = NULL; 22871 /* 22872 * Store the key in a global list. 22873 */ 22874 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) { 22875 xmlSchemaIDCFreeKey(key); 22876 return (-1); 22877 } 22878 } 22879 keySeq[idx] = key; 22880 } 22881 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) { 22882 22883 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL; 22884 /* xmlSchemaPSVIIDCBindingPtr bind; */ 22885 xmlSchemaPSVIIDCNodePtr ntItem; 22886 xmlSchemaIDCMatcherPtr matcher; 22887 xmlSchemaIDCPtr idc; 22888 xmlSchemaItemListPtr targets; 22889 int pos, i, j, nbKeys; 22890 /* 22891 * Here we have the following scenario: 22892 * An IDC 'selector' state object resolved to a target node, 22893 * during the time this target node was in the 22894 * ancestor-or-self axis, the 'field' state object(s) looked 22895 * out for matching nodes to create a key-sequence for this 22896 * target node. Now we are back to this target node and need 22897 * to put the key-sequence, together with the target node 22898 * itself, into the node-table of the corresponding IDC 22899 * binding. 22900 */ 22901 matcher = sto->matcher; 22902 idc = matcher->aidc->def; 22903 nbKeys = idc->nbFields; 22904 pos = depth - matcher->depth; 22905 /* 22906 * Check if the matcher has any key-sequences at all, plus 22907 * if it has a key-sequence for the current target node. 22908 */ 22909 if ((matcher->keySeqs == NULL) || 22910 (matcher->sizeKeySeqs <= pos)) { 22911 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22912 goto selector_key_error; 22913 else 22914 goto selector_leave; 22915 } 22916 22917 keySeq = &(matcher->keySeqs[pos]); 22918 if (*keySeq == NULL) { 22919 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) 22920 goto selector_key_error; 22921 else 22922 goto selector_leave; 22923 } 22924 22925 for (i = 0; i < nbKeys; i++) { 22926 if ((*keySeq)[i] == NULL) { 22927 /* 22928 * Not qualified, if not all fields did resolve. 22929 */ 22930 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) { 22931 /* 22932 * All fields of a "key" IDC must resolve. 22933 */ 22934 goto selector_key_error; 22935 } 22936 goto selector_leave; 22937 } 22938 } 22939 /* 22940 * All fields did resolve. 22941 */ 22942 22943 /* 22944 * 4.1 If the {identity-constraint category} is unique(/key), 22945 * then no two members of the �qualified node set� have 22946 * �key-sequences� whose members are pairwise equal, as 22947 * defined by Equal in [XML Schemas: Datatypes]. 22948 * 22949 * Get the IDC binding from the matcher and check for 22950 * duplicate key-sequences. 22951 */ 22952 #if 0 22953 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 22954 #endif 22955 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher); 22956 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) && 22957 (targets->nbItems != 0)) { 22958 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq; 22959 22960 i = 0; 22961 res = 0; 22962 /* 22963 * Compare the key-sequences, key by key. 22964 */ 22965 do { 22966 bkeySeq = 22967 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys; 22968 for (j = 0; j < nbKeys; j++) { 22969 ckey = (*keySeq)[j]; 22970 bkey = bkeySeq[j]; 22971 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val); 22972 if (res == -1) { 22973 return (-1); 22974 } else if (res == 0) { 22975 /* 22976 * One of the keys differs, so the key-sequence 22977 * won't be equal; get out. 22978 */ 22979 break; 22980 } 22981 } 22982 if (res == 1) { 22983 /* 22984 * Duplicate key-sequence found. 22985 */ 22986 break; 22987 } 22988 i++; 22989 } while (i < targets->nbItems); 22990 if (i != targets->nbItems) { 22991 xmlChar *str = NULL, *strB = NULL; 22992 /* 22993 * TODO: Try to report the key-sequence. 22994 */ 22995 xmlSchemaCustomErr(ACTXT_CAST vctxt, 22996 XML_SCHEMAV_CVC_IDC, NULL, 22997 WXS_BASIC_CAST idc, 22998 "Duplicate key-sequence %s in %s", 22999 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23000 (*keySeq), nbKeys), 23001 xmlSchemaGetIDCDesignation(&strB, idc)); 23002 FREE_AND_NULL(str); 23003 FREE_AND_NULL(strB); 23004 goto selector_leave; 23005 } 23006 } 23007 /* 23008 * Add a node-table item to the IDC binding. 23009 */ 23010 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc( 23011 sizeof(xmlSchemaPSVIIDCNode)); 23012 if (ntItem == NULL) { 23013 xmlSchemaVErrMemory(NULL, 23014 "allocating an IDC node-table item", NULL); 23015 xmlFree(*keySeq); 23016 *keySeq = NULL; 23017 return(-1); 23018 } 23019 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode)); 23020 23021 /* 23022 * Store the node-table item in a global list. 23023 */ 23024 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) { 23025 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) { 23026 xmlFree(ntItem); 23027 xmlFree(*keySeq); 23028 *keySeq = NULL; 23029 return (-1); 23030 } 23031 ntItem->nodeQNameID = -1; 23032 } else { 23033 /* 23034 * Save a cached QName for this node on the IDC node, to be 23035 * able to report it, even if the node is not saved. 23036 */ 23037 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt, 23038 vctxt->inode->localName, vctxt->inode->nsName); 23039 if (ntItem->nodeQNameID == -1) { 23040 xmlFree(ntItem); 23041 xmlFree(*keySeq); 23042 *keySeq = NULL; 23043 return (-1); 23044 } 23045 } 23046 /* 23047 * Init the node-table item: Save the node, position and 23048 * consume the key-sequence. 23049 */ 23050 ntItem->node = vctxt->node; 23051 ntItem->nodeLine = vctxt->inode->nodeLine; 23052 ntItem->keys = *keySeq; 23053 *keySeq = NULL; 23054 #if 0 23055 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) 23056 #endif 23057 if (xmlSchemaItemListAdd(targets, ntItem) == -1) { 23058 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23059 /* 23060 * Free the item, since keyref items won't be 23061 * put on a global list. 23062 */ 23063 xmlFree(ntItem->keys); 23064 xmlFree(ntItem); 23065 } 23066 return (-1); 23067 } 23068 23069 goto selector_leave; 23070 selector_key_error: 23071 { 23072 xmlChar *str = NULL; 23073 /* 23074 * 4.2.1 (KEY) The �target node set� and the 23075 * �qualified node set� are equal, that is, every 23076 * member of the �target node set� is also a member 23077 * of the �qualified node set� and vice versa. 23078 */ 23079 xmlSchemaCustomErr(ACTXT_CAST vctxt, 23080 XML_SCHEMAV_CVC_IDC, NULL, 23081 WXS_BASIC_CAST idc, 23082 "Not all fields of %s evaluate to a node", 23083 xmlSchemaGetIDCDesignation(&str, idc), NULL); 23084 FREE_AND_NULL(str); 23085 } 23086 selector_leave: 23087 /* 23088 * Free the key-sequence if not added to the IDC table. 23089 */ 23090 if ((keySeq != NULL) && (*keySeq != NULL)) { 23091 xmlFree(*keySeq); 23092 *keySeq = NULL; 23093 } 23094 } /* if selector */ 23095 23096 sto->nbHistory--; 23097 23098 deregister_check: 23099 /* 23100 * Deregister state objects if they reach the depth of creation. 23101 */ 23102 if ((sto->nbHistory == 0) && (sto->depth == depth)) { 23103 #ifdef DEBUG_IDC 23104 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n", 23105 sto->sel->xpath); 23106 #endif 23107 if (vctxt->xpathStates != sto) { 23108 VERROR_INT("xmlSchemaXPathProcessHistory", 23109 "The state object to be removed is not the first " 23110 "in the list"); 23111 } 23112 nextsto = sto->next; 23113 /* 23114 * Unlink from the list of active XPath state objects. 23115 */ 23116 vctxt->xpathStates = sto->next; 23117 sto->next = vctxt->xpathStatePool; 23118 /* 23119 * Link it to the pool of reusable state objects. 23120 */ 23121 vctxt->xpathStatePool = sto; 23122 sto = nextsto; 23123 } else 23124 sto = sto->next; 23125 } /* while (sto != NULL) */ 23126 return (0); 23127 } 23128 23139 static int 23140 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt, 23141 xmlSchemaElementPtr elemDecl) 23142 { 23143 xmlSchemaIDCMatcherPtr matcher, last = NULL; 23144 xmlSchemaIDCPtr idc, refIdc; 23145 xmlSchemaIDCAugPtr aidc; 23146 23147 idc = (xmlSchemaIDCPtr) elemDecl->idcs; 23148 if (idc == NULL) 23149 return (0); 23150 23151 #ifdef DEBUG_IDC 23152 { 23153 xmlChar *str = NULL; 23154 xmlGenericError(xmlGenericErrorContext, 23155 "IDC: REGISTER on %s, depth %d\n", 23156 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName, 23157 vctxt->inode->localName), vctxt->depth); 23158 FREE_AND_NULL(str) 23159 } 23160 #endif 23161 if (vctxt->inode->idcMatchers != NULL) { 23162 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23163 "The chain of IDC matchers is expected to be empty"); 23164 return (-1); 23165 } 23166 do { 23167 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) { 23168 /* 23169 * Since IDCs bubbles are expensive we need to know the 23170 * depth at which the bubbles should stop; this will be 23171 * the depth of the top-most keyref IDC. If no keyref 23172 * references a key/unique IDC, the keyrefDepth will 23173 * be -1, indicating that no bubbles are needed. 23174 */ 23175 refIdc = (xmlSchemaIDCPtr) idc->ref->item; 23176 if (refIdc != NULL) { 23177 /* 23178 * Remember that we have keyrefs on this node. 23179 */ 23180 vctxt->inode->hasKeyrefs = 1; 23181 /* 23182 * Lookup the referenced augmented IDC info. 23183 */ 23184 aidc = vctxt->aidcs; 23185 while (aidc != NULL) { 23186 if (aidc->def == refIdc) 23187 break; 23188 aidc = aidc->next; 23189 } 23190 if (aidc == NULL) { 23191 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23192 "Could not find an augmented IDC item for an IDC " 23193 "definition"); 23194 return (-1); 23195 } 23196 if ((aidc->keyrefDepth == -1) || 23197 (vctxt->depth < aidc->keyrefDepth)) 23198 aidc->keyrefDepth = vctxt->depth; 23199 } 23200 } 23201 /* 23202 * Lookup the augmented IDC item for the IDC definition. 23203 */ 23204 aidc = vctxt->aidcs; 23205 while (aidc != NULL) { 23206 if (aidc->def == idc) 23207 break; 23208 aidc = aidc->next; 23209 } 23210 if (aidc == NULL) { 23211 VERROR_INT("xmlSchemaIDCRegisterMatchers", 23212 "Could not find an augmented IDC item for an IDC definition"); 23213 return (-1); 23214 } 23215 /* 23216 * Create an IDC matcher for every IDC definition. 23217 */ 23218 if (vctxt->idcMatcherCache != NULL) { 23219 /* 23220 * Reuse a cached matcher. 23221 */ 23222 matcher = vctxt->idcMatcherCache; 23223 vctxt->idcMatcherCache = matcher->nextCached; 23224 matcher->nextCached = NULL; 23225 } else { 23226 matcher = (xmlSchemaIDCMatcherPtr) 23227 xmlMalloc(sizeof(xmlSchemaIDCMatcher)); 23228 if (matcher == NULL) { 23229 xmlSchemaVErrMemory(vctxt, 23230 "allocating an IDC matcher", NULL); 23231 return (-1); 23232 } 23233 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher)); 23234 } 23235 if (last == NULL) 23236 vctxt->inode->idcMatchers = matcher; 23237 else 23238 last->next = matcher; 23239 last = matcher; 23240 23241 matcher->type = IDC_MATCHER; 23242 matcher->depth = vctxt->depth; 23243 matcher->aidc = aidc; 23244 matcher->idcType = aidc->def->type; 23245 #ifdef DEBUG_IDC 23246 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n"); 23247 #endif 23248 /* 23249 * Init the automaton state object. 23250 */ 23251 if (xmlSchemaIDCAddStateObject(vctxt, matcher, 23252 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1) 23253 return (-1); 23254 23255 idc = idc->next; 23256 } while (idc != NULL); 23257 return (0); 23258 } 23259 23260 static int 23261 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt, 23262 xmlSchemaNodeInfoPtr ielem) 23263 { 23264 xmlSchemaPSVIIDCBindingPtr bind; 23265 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable; 23266 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys; 23267 xmlSchemaPSVIIDCNodePtr *targets, *dupls; 23268 23269 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers; 23270 /* vctxt->createIDCNodeTables */ 23271 while (matcher != NULL) { 23272 /* 23273 * Skip keyref IDCs and empty IDC target-lists. 23274 */ 23275 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) || 23276 WXS_ILIST_IS_EMPTY(matcher->targets)) 23277 { 23278 matcher = matcher->next; 23279 continue; 23280 } 23281 /* 23282 * If we _want_ the IDC node-table to be created in any case 23283 * then do so. Otherwise create them only if keyrefs need them. 23284 */ 23285 if ((! vctxt->createIDCNodeTables) && 23286 ((matcher->aidc->keyrefDepth == -1) || 23287 (matcher->aidc->keyrefDepth > vctxt->depth))) 23288 { 23289 matcher = matcher->next; 23290 continue; 23291 } 23292 /* 23293 * Get/create the IDC binding on this element for the IDC definition. 23294 */ 23295 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher); 23296 23297 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) { 23298 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items; 23299 nbDupls = bind->dupls->nbItems; 23300 } else { 23301 dupls = NULL; 23302 nbDupls = 0; 23303 } 23304 if (bind->nodeTable != NULL) { 23305 nbNodeTable = bind->nbNodes; 23306 } else { 23307 nbNodeTable = 0; 23308 } 23309 23310 if ((nbNodeTable == 0) && (nbDupls == 0)) { 23311 /* 23312 * Transfer all IDC target-nodes to the IDC node-table. 23313 */ 23314 bind->nodeTable = 23315 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23316 bind->sizeNodes = matcher->targets->sizeItems; 23317 bind->nbNodes = matcher->targets->nbItems; 23318 23319 matcher->targets->items = NULL; 23320 matcher->targets->sizeItems = 0; 23321 matcher->targets->nbItems = 0; 23322 } else { 23323 /* 23324 * Compare the key-sequences and add to the IDC node-table. 23325 */ 23326 nbTargets = matcher->targets->nbItems; 23327 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items; 23328 nbFields = matcher->aidc->def->nbFields; 23329 i = 0; 23330 do { 23331 keys = targets[i]->keys; 23332 if (nbDupls) { 23333 /* 23334 * Search in already found duplicates first. 23335 */ 23336 j = 0; 23337 do { 23338 if (nbFields == 1) { 23339 res = xmlSchemaAreValuesEqual(keys[0]->val, 23340 dupls[j]->keys[0]->val); 23341 if (res == -1) 23342 goto internal_error; 23343 if (res == 1) { 23344 /* 23345 * Equal key-sequence. 23346 */ 23347 goto next_target; 23348 } 23349 } else { 23350 res = 0; 23351 ntkeys = dupls[j]->keys; 23352 for (k = 0; k < nbFields; k++) { 23353 res = xmlSchemaAreValuesEqual(keys[k]->val, 23354 ntkeys[k]->val); 23355 if (res == -1) 23356 goto internal_error; 23357 if (res == 0) { 23358 /* 23359 * One of the keys differs. 23360 */ 23361 break; 23362 } 23363 } 23364 if (res == 1) { 23365 /* 23366 * Equal key-sequence found. 23367 */ 23368 goto next_target; 23369 } 23370 } 23371 j++; 23372 } while (j < nbDupls); 23373 } 23374 if (nbNodeTable) { 23375 j = 0; 23376 do { 23377 if (nbFields == 1) { 23378 res = xmlSchemaAreValuesEqual(keys[0]->val, 23379 bind->nodeTable[j]->keys[0]->val); 23380 if (res == -1) 23381 goto internal_error; 23382 if (res == 0) { 23383 /* 23384 * The key-sequence differs. 23385 */ 23386 goto next_node_table_entry; 23387 } 23388 } else { 23389 res = 0; 23390 ntkeys = bind->nodeTable[j]->keys; 23391 for (k = 0; k < nbFields; k++) { 23392 res = xmlSchemaAreValuesEqual(keys[k]->val, 23393 ntkeys[k]->val); 23394 if (res == -1) 23395 goto internal_error; 23396 if (res == 0) { 23397 /* 23398 * One of the keys differs. 23399 */ 23400 goto next_node_table_entry; 23401 } 23402 } 23403 } 23404 /* 23405 * Add the duplicate to the list of duplicates. 23406 */ 23407 if (bind->dupls == NULL) { 23408 bind->dupls = xmlSchemaItemListCreate(); 23409 if (bind->dupls == NULL) 23410 goto internal_error; 23411 } 23412 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1) 23413 goto internal_error; 23414 /* 23415 * Remove the duplicate entry from the IDC node-table. 23416 */ 23417 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1]; 23418 bind->nbNodes--; 23419 23420 goto next_target; 23421 23422 next_node_table_entry: 23423 j++; 23424 } while (j < nbNodeTable); 23425 } 23426 /* 23427 * If everything is fine, then add the IDC target-node to 23428 * the IDC node-table. 23429 */ 23430 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1) 23431 goto internal_error; 23432 23433 next_target: 23434 i++; 23435 } while (i < nbTargets); 23436 } 23437 matcher = matcher->next; 23438 } 23439 return(0); 23440 23441 internal_error: 23442 return(-1); 23443 } 23444 23456 static int 23457 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt) 23458 { 23459 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */ 23460 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */ 23461 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */ 23462 xmlSchemaIDCAugPtr aidc; 23463 int i, j, k, ret = 0, nbFields, oldNum, oldDupls; 23464 23465 bind = vctxt->inode->idcTable; 23466 if (bind == NULL) { 23467 /* Fine, no table, no bubbles. */ 23468 return (0); 23469 } 23470 23471 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable); 23472 /* 23473 * Walk all bindings; create new or add to existing bindings. 23474 * Remove duplicate key-sequences. 23475 */ 23476 while (bind != NULL) { 23477 23478 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls)) 23479 goto next_binding; 23480 /* 23481 * Check if the key/unique IDC table needs to be bubbled. 23482 */ 23483 if (! vctxt->createIDCNodeTables) { 23484 aidc = vctxt->aidcs; 23485 do { 23486 if (aidc->def == bind->definition) { 23487 if ((aidc->keyrefDepth == -1) || 23488 (aidc->keyrefDepth >= vctxt->depth)) { 23489 goto next_binding; 23490 } 23491 break; 23492 } 23493 aidc = aidc->next; 23494 } while (aidc != NULL); 23495 } 23496 23497 if (parTable != NULL) 23498 parBind = *parTable; 23499 /* 23500 * Search a matching parent binding for the 23501 * IDC definition. 23502 */ 23503 while (parBind != NULL) { 23504 if (parBind->definition == bind->definition) 23505 break; 23506 parBind = parBind->next; 23507 } 23508 23509 if (parBind != NULL) { 23510 /* 23511 * Compare every node-table entry of the child node, 23512 * i.e. the key-sequence within, ... 23513 */ 23514 oldNum = parBind->nbNodes; /* Skip newly added items. */ 23515 23516 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) { 23517 oldDupls = parBind->dupls->nbItems; 23518 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items; 23519 } else { 23520 dupls = NULL; 23521 oldDupls = 0; 23522 } 23523 23524 parNodes = parBind->nodeTable; 23525 nbFields = bind->definition->nbFields; 23526 23527 for (i = 0; i < bind->nbNodes; i++) { 23528 node = bind->nodeTable[i]; 23529 if (node == NULL) 23530 continue; 23531 /* 23532 * ...with every key-sequence of the parent node, already 23533 * evaluated to be a duplicate key-sequence. 23534 */ 23535 if (oldDupls) { 23536 j = 0; 23537 while (j < oldDupls) { 23538 if (nbFields == 1) { 23539 ret = xmlSchemaAreValuesEqual( 23540 node->keys[0]->val, 23541 dupls[j]->keys[0]->val); 23542 if (ret == -1) 23543 goto internal_error; 23544 if (ret == 0) { 23545 j++; 23546 continue; 23547 } 23548 } else { 23549 parNode = dupls[j]; 23550 for (k = 0; k < nbFields; k++) { 23551 ret = xmlSchemaAreValuesEqual( 23552 node->keys[k]->val, 23553 parNode->keys[k]->val); 23554 if (ret == -1) 23555 goto internal_error; 23556 if (ret == 0) 23557 break; 23558 } 23559 } 23560 if (ret == 1) 23561 /* Duplicate found. */ 23562 break; 23563 j++; 23564 } 23565 if (j != oldDupls) { 23566 /* Duplicate found. Skip this entry. */ 23567 continue; 23568 } 23569 } 23570 /* 23571 * ... and with every key-sequence of the parent node. 23572 */ 23573 if (oldNum) { 23574 j = 0; 23575 while (j < oldNum) { 23576 parNode = parNodes[j]; 23577 if (nbFields == 1) { 23578 ret = xmlSchemaAreValuesEqual( 23579 node->keys[0]->val, 23580 parNode->keys[0]->val); 23581 if (ret == -1) 23582 goto internal_error; 23583 if (ret == 0) { 23584 j++; 23585 continue; 23586 } 23587 } else { 23588 for (k = 0; k < nbFields; k++) { 23589 ret = xmlSchemaAreValuesEqual( 23590 node->keys[k]->val, 23591 parNode->keys[k]->val); 23592 if (ret == -1) 23593 goto internal_error; 23594 if (ret == 0) 23595 break; 23596 } 23597 } 23598 if (ret == 1) 23599 /* Duplicate found. */ 23600 break; 23601 j++; 23602 } 23603 if (j != oldNum) { 23604 /* 23605 * Handle duplicates. Move the duplicate in 23606 * the parent's node-table to the list of 23607 * duplicates. 23608 */ 23609 oldNum--; 23610 parBind->nbNodes--; 23611 /* 23612 * Move last old item to pos of duplicate. 23613 */ 23614 parNodes[j] = parNodes[oldNum]; 23615 23616 if (parBind->nbNodes != oldNum) { 23617 /* 23618 * If new items exist, move last new item to 23619 * last of old items. 23620 */ 23621 parNodes[oldNum] = 23622 parNodes[parBind->nbNodes]; 23623 } 23624 if (parBind->dupls == NULL) { 23625 parBind->dupls = xmlSchemaItemListCreate(); 23626 if (parBind->dupls == NULL) 23627 goto internal_error; 23628 } 23629 xmlSchemaItemListAdd(parBind->dupls, parNode); 23630 } else { 23631 /* 23632 * Add the node-table entry (node and key-sequence) of 23633 * the child node to the node table of the parent node. 23634 */ 23635 if (parBind->nodeTable == NULL) { 23636 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23637 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr)); 23638 if (parBind->nodeTable == NULL) { 23639 xmlSchemaVErrMemory(NULL, 23640 "allocating IDC list of node-table items", NULL); 23641 goto internal_error; 23642 } 23643 parBind->sizeNodes = 1; 23644 } else if (parBind->nbNodes >= parBind->sizeNodes) { 23645 parBind->sizeNodes *= 2; 23646 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23647 xmlRealloc(parBind->nodeTable, parBind->sizeNodes * 23648 sizeof(xmlSchemaPSVIIDCNodePtr)); 23649 if (parBind->nodeTable == NULL) { 23650 xmlSchemaVErrMemory(NULL, 23651 "re-allocating IDC list of node-table items", NULL); 23652 goto internal_error; 23653 } 23654 } 23655 parNodes = parBind->nodeTable; 23656 /* 23657 * Append the new node-table entry to the 'new node-table 23658 * entries' section. 23659 */ 23660 parNodes[parBind->nbNodes++] = node; 23661 } 23662 23663 } 23664 23665 } 23666 } else { 23667 /* 23668 * No binding for the IDC was found: create a new one and 23669 * copy all node-tables. 23670 */ 23671 parBind = xmlSchemaIDCNewBinding(bind->definition); 23672 if (parBind == NULL) 23673 goto internal_error; 23674 23675 /* 23676 * TODO: Hmm, how to optimize the initial number of 23677 * allocated entries? 23678 */ 23679 if (bind->nbNodes != 0) { 23680 /* 23681 * Add all IDC node-table entries. 23682 */ 23683 if (! vctxt->psviExposeIDCNodeTables) { 23684 /* 23685 * Just move the entries. 23686 * NOTE: this is quite save here, since 23687 * all the keyref lookups have already been 23688 * performed. 23689 */ 23690 parBind->nodeTable = bind->nodeTable; 23691 bind->nodeTable = NULL; 23692 parBind->sizeNodes = bind->sizeNodes; 23693 bind->sizeNodes = 0; 23694 parBind->nbNodes = bind->nbNodes; 23695 bind->nbNodes = 0; 23696 } else { 23697 /* 23698 * Copy the entries. 23699 */ 23700 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *) 23701 xmlMalloc(bind->nbNodes * 23702 sizeof(xmlSchemaPSVIIDCNodePtr)); 23703 if (parBind->nodeTable == NULL) { 23704 xmlSchemaVErrMemory(NULL, 23705 "allocating an array of IDC node-table " 23706 "items", NULL); 23707 xmlSchemaIDCFreeBinding(parBind); 23708 goto internal_error; 23709 } 23710 parBind->sizeNodes = bind->nbNodes; 23711 parBind->nbNodes = bind->nbNodes; 23712 memcpy(parBind->nodeTable, bind->nodeTable, 23713 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr)); 23714 } 23715 } 23716 if (bind->dupls) { 23717 /* 23718 * Move the duplicates. 23719 */ 23720 if (parBind->dupls != NULL) 23721 xmlSchemaItemListFree(parBind->dupls); 23722 parBind->dupls = bind->dupls; 23723 bind->dupls = NULL; 23724 } 23725 if (parTable != NULL) { 23726 if (*parTable == NULL) 23727 *parTable = parBind; 23728 else { 23729 parBind->next = *parTable; 23730 *parTable = parBind; 23731 } 23732 } 23733 } 23734 23735 next_binding: 23736 bind = bind->next; 23737 } 23738 return (0); 23739 23740 internal_error: 23741 return(-1); 23742 } 23743 23751 static int 23752 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt) 23753 { 23754 xmlSchemaIDCMatcherPtr matcher; 23755 xmlSchemaPSVIIDCBindingPtr bind; 23756 23757 matcher = vctxt->inode->idcMatchers; 23758 /* 23759 * Find a keyref. 23760 */ 23761 while (matcher != NULL) { 23762 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) && 23763 matcher->targets && 23764 matcher->targets->nbItems) 23765 { 23766 int i, j, k, res, nbFields, hasDupls; 23767 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys; 23768 xmlSchemaPSVIIDCNodePtr refNode = NULL; 23769 23770 nbFields = matcher->aidc->def->nbFields; 23771 23772 /* 23773 * Find the IDC node-table for the referenced IDC key/unique. 23774 */ 23775 bind = vctxt->inode->idcTable; 23776 while (bind != NULL) { 23777 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item == 23778 bind->definition) 23779 break; 23780 bind = bind->next; 23781 } 23782 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0; 23783 /* 23784 * Search for a matching key-sequences. 23785 */ 23786 for (i = 0; i < matcher->targets->nbItems; i++) { 23787 res = 0; 23788 refNode = matcher->targets->items[i]; 23789 if (bind != NULL) { 23790 refKeys = refNode->keys; 23791 for (j = 0; j < bind->nbNodes; j++) { 23792 keys = bind->nodeTable[j]->keys; 23793 for (k = 0; k < nbFields; k++) { 23794 res = xmlSchemaAreValuesEqual(keys[k]->val, 23795 refKeys[k]->val); 23796 if (res == 0) 23797 break; 23798 else if (res == -1) { 23799 return (-1); 23800 } 23801 } 23802 if (res == 1) { 23803 /* 23804 * Match found. 23805 */ 23806 break; 23807 } 23808 } 23809 if ((res == 0) && hasDupls) { 23810 /* 23811 * Search in duplicates 23812 */ 23813 for (j = 0; j < bind->dupls->nbItems; j++) { 23814 keys = ((xmlSchemaPSVIIDCNodePtr) 23815 bind->dupls->items[j])->keys; 23816 for (k = 0; k < nbFields; k++) { 23817 res = xmlSchemaAreValuesEqual(keys[k]->val, 23818 refKeys[k]->val); 23819 if (res == 0) 23820 break; 23821 else if (res == -1) { 23822 return (-1); 23823 } 23824 } 23825 if (res == 1) { 23826 /* 23827 * Match in duplicates found. 23828 */ 23829 xmlChar *str = NULL, *strB = NULL; 23830 xmlSchemaKeyrefErr(vctxt, 23831 XML_SCHEMAV_CVC_IDC, refNode, 23832 (xmlSchemaTypePtr) matcher->aidc->def, 23833 "More than one match found for " 23834 "key-sequence %s of keyref '%s'", 23835 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23836 refNode->keys, nbFields), 23837 xmlSchemaGetComponentQName(&strB, 23838 matcher->aidc->def)); 23839 FREE_AND_NULL(str); 23840 FREE_AND_NULL(strB); 23841 break; 23842 } 23843 } 23844 } 23845 } 23846 23847 if (res == 0) { 23848 xmlChar *str = NULL, *strB = NULL; 23849 xmlSchemaKeyrefErr(vctxt, 23850 XML_SCHEMAV_CVC_IDC, refNode, 23851 (xmlSchemaTypePtr) matcher->aidc->def, 23852 "No match found for key-sequence %s of keyref '%s'", 23853 xmlSchemaFormatIDCKeySequence(vctxt, &str, 23854 refNode->keys, nbFields), 23855 xmlSchemaGetComponentQName(&strB, matcher->aidc->def)); 23856 FREE_AND_NULL(str); 23857 FREE_AND_NULL(strB); 23858 } 23859 } 23860 } 23861 matcher = matcher->next; 23862 } 23863 /* TODO: Return an error if any error encountered. */ 23864 return (0); 23865 } 23866 23867 /************************************************************************ 23868 * * 23869 * XML Reader validation code * 23870 * * 23871 ************************************************************************/ 23872 23873 static xmlSchemaAttrInfoPtr 23874 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt) 23875 { 23876 xmlSchemaAttrInfoPtr iattr; 23877 /* 23878 * Grow/create list of attribute infos. 23879 */ 23880 if (vctxt->attrInfos == NULL) { 23881 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23882 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr)); 23883 vctxt->sizeAttrInfos = 1; 23884 if (vctxt->attrInfos == NULL) { 23885 xmlSchemaVErrMemory(vctxt, 23886 "allocating attribute info list", NULL); 23887 return (NULL); 23888 } 23889 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) { 23890 vctxt->sizeAttrInfos++; 23891 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *) 23892 xmlRealloc(vctxt->attrInfos, 23893 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr)); 23894 if (vctxt->attrInfos == NULL) { 23895 xmlSchemaVErrMemory(vctxt, 23896 "re-allocating attribute info list", NULL); 23897 return (NULL); 23898 } 23899 } else { 23900 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++]; 23901 if (iattr->localName != NULL) { 23902 VERROR_INT("xmlSchemaGetFreshAttrInfo", 23903 "attr info not cleared"); 23904 return (NULL); 23905 } 23906 iattr->nodeType = XML_ATTRIBUTE_NODE; 23907 return (iattr); 23908 } 23909 /* 23910 * Create an attribute info. 23911 */ 23912 iattr = (xmlSchemaAttrInfoPtr) 23913 xmlMalloc(sizeof(xmlSchemaAttrInfo)); 23914 if (iattr == NULL) { 23915 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL); 23916 return (NULL); 23917 } 23918 memset(iattr, 0, sizeof(xmlSchemaAttrInfo)); 23919 iattr->nodeType = XML_ATTRIBUTE_NODE; 23920 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr; 23921 23922 return (iattr); 23923 } 23924 23925 static int 23926 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt, 23927 xmlNodePtr attrNode, 23928 int nodeLine, 23929 const xmlChar *localName, 23930 const xmlChar *nsName, 23931 int ownedNames, 23932 xmlChar *value, 23933 int ownedValue) 23934 { 23935 xmlSchemaAttrInfoPtr attr; 23936 23937 attr = xmlSchemaGetFreshAttrInfo(vctxt); 23938 if (attr == NULL) { 23939 VERROR_INT("xmlSchemaPushAttribute", 23940 "calling xmlSchemaGetFreshAttrInfo()"); 23941 return (-1); 23942 } 23943 attr->node = attrNode; 23944 attr->nodeLine = nodeLine; 23945 attr->state = XML_SCHEMAS_ATTR_UNKNOWN; 23946 attr->localName = localName; 23947 attr->nsName = nsName; 23948 if (ownedNames) 23949 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 23950 /* 23951 * Evaluate if it's an XSI attribute. 23952 */ 23953 if (nsName != NULL) { 23954 if (xmlStrEqual(localName, BAD_CAST "nil")) { 23955 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23956 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL; 23957 } 23958 } else if (xmlStrEqual(localName, BAD_CAST "type")) { 23959 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23960 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE; 23961 } 23962 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) { 23963 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23964 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC; 23965 } 23966 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) { 23967 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) { 23968 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC; 23969 } 23970 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) { 23971 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS; 23972 } 23973 } 23974 attr->value = value; 23975 if (ownedValue) 23976 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 23977 if (attr->metaType != 0) 23978 attr->state = XML_SCHEMAS_ATTR_META; 23979 return (0); 23980 } 23981 23987 static void 23988 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt, 23989 xmlSchemaNodeInfoPtr ielem) 23990 { 23991 ielem->hasKeyrefs = 0; 23992 ielem->appliedXPath = 0; 23993 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 23994 FREE_AND_NULL(ielem->localName); 23995 FREE_AND_NULL(ielem->nsName); 23996 } else { 23997 ielem->localName = NULL; 23998 ielem->nsName = NULL; 23999 } 24000 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 24001 FREE_AND_NULL(ielem->value); 24002 } else { 24003 ielem->value = NULL; 24004 } 24005 if (ielem->val != NULL) { 24006 /* 24007 * PSVI TODO: Be careful not to free it when the value is 24008 * exposed via PSVI. 24009 */ 24010 xmlSchemaFreeValue(ielem->val); 24011 ielem->val = NULL; 24012 } 24013 if (ielem->idcMatchers != NULL) { 24014 /* 24015 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers. 24016 * Does it work? 24017 */ 24018 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers); 24019 #if 0 24020 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers); 24021 #endif 24022 ielem->idcMatchers = NULL; 24023 } 24024 if (ielem->idcTable != NULL) { 24025 /* 24026 * OPTIMIZE TODO: Use a pool of IDC tables??. 24027 */ 24028 xmlSchemaIDCFreeIDCTable(ielem->idcTable); 24029 ielem->idcTable = NULL; 24030 } 24031 if (ielem->regexCtxt != NULL) { 24032 xmlRegFreeExecCtxt(ielem->regexCtxt); 24033 ielem->regexCtxt = NULL; 24034 } 24035 if (ielem->nsBindings != NULL) { 24036 xmlFree((xmlChar **)ielem->nsBindings); 24037 ielem->nsBindings = NULL; 24038 ielem->nbNsBindings = 0; 24039 ielem->sizeNsBindings = 0; 24040 } 24041 } 24042 24052 static xmlSchemaNodeInfoPtr 24053 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt) 24054 { 24055 xmlSchemaNodeInfoPtr info = NULL; 24056 24057 if (vctxt->depth > vctxt->sizeElemInfos) { 24058 VERROR_INT("xmlSchemaGetFreshElemInfo", 24059 "inconsistent depth encountered"); 24060 return (NULL); 24061 } 24062 if (vctxt->elemInfos == NULL) { 24063 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24064 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr)); 24065 if (vctxt->elemInfos == NULL) { 24066 xmlSchemaVErrMemory(vctxt, 24067 "allocating the element info array", NULL); 24068 return (NULL); 24069 } 24070 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr)); 24071 vctxt->sizeElemInfos = 10; 24072 } else if (vctxt->sizeElemInfos <= vctxt->depth) { 24073 int i = vctxt->sizeElemInfos; 24074 24075 vctxt->sizeElemInfos *= 2; 24076 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *) 24077 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos * 24078 sizeof(xmlSchemaNodeInfoPtr)); 24079 if (vctxt->elemInfos == NULL) { 24080 xmlSchemaVErrMemory(vctxt, 24081 "re-allocating the element info array", NULL); 24082 return (NULL); 24083 } 24084 /* 24085 * We need the new memory to be NULLed. 24086 * TODO: Use memset instead? 24087 */ 24088 for (; i < vctxt->sizeElemInfos; i++) 24089 vctxt->elemInfos[i] = NULL; 24090 } else 24091 info = vctxt->elemInfos[vctxt->depth]; 24092 24093 if (info == NULL) { 24094 info = (xmlSchemaNodeInfoPtr) 24095 xmlMalloc(sizeof(xmlSchemaNodeInfo)); 24096 if (info == NULL) { 24097 xmlSchemaVErrMemory(vctxt, 24098 "allocating an element info", NULL); 24099 return (NULL); 24100 } 24101 vctxt->elemInfos[vctxt->depth] = info; 24102 } else { 24103 if (info->localName != NULL) { 24104 VERROR_INT("xmlSchemaGetFreshElemInfo", 24105 "elem info has not been cleared"); 24106 return (NULL); 24107 } 24108 } 24109 memset(info, 0, sizeof(xmlSchemaNodeInfo)); 24110 info->nodeType = XML_ELEMENT_NODE; 24111 info->depth = vctxt->depth; 24112 24113 return (info); 24114 } 24115 24116 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item; 24117 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth]; 24118 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1]; 24119 24120 static int 24121 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt, 24122 xmlNodePtr node, 24123 xmlSchemaTypePtr type, 24124 xmlSchemaValType valType, 24125 const xmlChar * value, 24126 xmlSchemaValPtr val, 24127 unsigned long length, 24128 int fireErrors) 24129 { 24130 int ret, error = 0; 24131 24132 xmlSchemaTypePtr tmpType; 24133 xmlSchemaFacetLinkPtr facetLink; 24134 xmlSchemaFacetPtr facet; 24135 unsigned long len = 0; 24136 xmlSchemaWhitespaceValueType ws; 24137 24138 /* 24139 * In Libxml2, derived built-in types have currently no explicit facets. 24140 */ 24141 if (type->type == XML_SCHEMA_TYPE_BASIC) 24142 return (0); 24143 24144 /* 24145 * NOTE: Do not jump away, if the facetSet of the given type is 24146 * empty: until now, "pattern" and "enumeration" facets of the 24147 * *base types* need to be checked as well. 24148 */ 24149 if (type->facetSet == NULL) 24150 goto pattern_and_enum; 24151 24152 if (! WXS_IS_ATOMIC(type)) { 24153 if (WXS_IS_LIST(type)) 24154 goto WXS_IS_LIST; 24155 else 24156 goto pattern_and_enum; 24157 } 24158 /* 24159 * Whitespace handling is only of importance for string-based 24160 * types. 24161 */ 24162 tmpType = xmlSchemaGetPrimitiveType(type); 24163 if ((tmpType->builtInType == XML_SCHEMAS_STRING) || 24164 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) { 24165 ws = xmlSchemaGetWhiteSpaceFacetValue(type); 24166 } else 24167 ws = XML_SCHEMA_WHITESPACE_COLLAPSE; 24168 /* 24169 * If the value was not computed (for string or 24170 * anySimpleType based types), then use the provided 24171 * type. 24172 */ 24173 if (val == NULL) 24174 valType = valType; 24175 else 24176 valType = xmlSchemaGetValType(val); 24177 24178 ret = 0; 24179 for (facetLink = type->facetSet; facetLink != NULL; 24180 facetLink = facetLink->next) { 24181 /* 24182 * Skip the pattern "whiteSpace": it is used to 24183 * format the character content beforehand. 24184 */ 24185 switch (facetLink->facet->type) { 24186 case XML_SCHEMA_FACET_WHITESPACE: 24187 case XML_SCHEMA_FACET_PATTERN: 24188 case XML_SCHEMA_FACET_ENUMERATION: 24189 continue; 24190 case XML_SCHEMA_FACET_LENGTH: 24191 case XML_SCHEMA_FACET_MINLENGTH: 24192 case XML_SCHEMA_FACET_MAXLENGTH: 24193 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet, 24194 valType, value, val, &len, ws); 24195 break; 24196 default: 24197 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws, 24198 valType, value, val, ws); 24199 break; 24200 } 24201 if (ret < 0) { 24202 AERROR_INT("xmlSchemaValidateFacets", 24203 "validating against a atomic type facet"); 24204 return (-1); 24205 } else if (ret > 0) { 24206 if (fireErrors) 24207 xmlSchemaFacetErr(actxt, ret, node, 24208 value, len, type, facetLink->facet, NULL, NULL, NULL); 24209 else 24210 return (ret); 24211 if (error == 0) 24212 error = ret; 24213 } 24214 ret = 0; 24215 } 24216 24217 WXS_IS_LIST: 24218 if (! WXS_IS_LIST(type)) 24219 goto pattern_and_enum; 24220 /* 24221 * "length", "minLength" and "maxLength" of list types. 24222 */ 24223 ret = 0; 24224 for (facetLink = type->facetSet; facetLink != NULL; 24225 facetLink = facetLink->next) { 24226 24227 switch (facetLink->facet->type) { 24228 case XML_SCHEMA_FACET_LENGTH: 24229 case XML_SCHEMA_FACET_MINLENGTH: 24230 case XML_SCHEMA_FACET_MAXLENGTH: 24231 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet, 24232 value, length, NULL); 24233 break; 24234 default: 24235 continue; 24236 } 24237 if (ret < 0) { 24238 AERROR_INT("xmlSchemaValidateFacets", 24239 "validating against a list type facet"); 24240 return (-1); 24241 } else if (ret > 0) { 24242 if (fireErrors) 24243 xmlSchemaFacetErr(actxt, ret, node, 24244 value, length, type, facetLink->facet, NULL, NULL, NULL); 24245 else 24246 return (ret); 24247 if (error == 0) 24248 error = ret; 24249 } 24250 ret = 0; 24251 } 24252 24253 pattern_and_enum: 24254 if (error >= 0) { 24255 int found = 0; 24256 /* 24257 * Process enumerations. Facet values are in the value space 24258 * of the defining type's base type. This seems to be a bug in the 24259 * XML Schema 1.0 spec. Use the whitespace type of the base type. 24260 * Only the first set of enumerations in the ancestor-or-self axis 24261 * is used for validation. 24262 */ 24263 ret = 0; 24264 tmpType = type; 24265 do { 24266 for (facet = tmpType->facets; facet != NULL; facet = facet->next) { 24267 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 24268 continue; 24269 found = 1; 24270 ret = xmlSchemaAreValuesEqual(facet->val, val); 24271 if (ret == 1) 24272 break; 24273 else if (ret < 0) { 24274 AERROR_INT("xmlSchemaValidateFacets", 24275 "validating against an enumeration facet"); 24276 return (-1); 24277 } 24278 } 24279 if (ret != 0) 24280 break; 24281 /* 24282 * Break on the first set of enumerations. Any additional 24283 * enumerations which might be existent on the ancestors 24284 * of the current type are restricted by this set; thus 24285 * *must* *not* be taken into account. 24286 */ 24287 if (found) 24288 break; 24289 tmpType = tmpType->baseType; 24290 } while ((tmpType != NULL) && 24291 (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24292 if (found && (ret == 0)) { 24293 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID; 24294 if (fireErrors) { 24295 xmlSchemaFacetErr(actxt, ret, node, 24296 value, 0, type, NULL, NULL, NULL, NULL); 24297 } else 24298 return (ret); 24299 if (error == 0) 24300 error = ret; 24301 } 24302 } 24303 24304 if (error >= 0) { 24305 int found; 24306 /* 24307 * Process patters. Pattern facets are ORed at type level 24308 * and ANDed if derived. Walk the base type axis. 24309 */ 24310 tmpType = type; 24311 facet = NULL; 24312 do { 24313 found = 0; 24314 for (facetLink = tmpType->facetSet; facetLink != NULL; 24315 facetLink = facetLink->next) { 24316 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN) 24317 continue; 24318 found = 1; 24319 /* 24320 * NOTE that for patterns, @value needs to be the 24321 * normalized vaule. 24322 */ 24323 ret = xmlRegexpExec(facetLink->facet->regexp, value); 24324 if (ret == 1) 24325 break; 24326 else if (ret < 0) { 24327 AERROR_INT("xmlSchemaValidateFacets", 24328 "validating against a pattern facet"); 24329 return (-1); 24330 } else { 24331 /* 24332 * Save the last non-validating facet. 24333 */ 24334 facet = facetLink->facet; 24335 } 24336 } 24337 if (found && (ret != 1)) { 24338 ret = XML_SCHEMAV_CVC_PATTERN_VALID; 24339 if (fireErrors) { 24340 xmlSchemaFacetErr(actxt, ret, node, 24341 value, 0, type, facet, NULL, NULL, NULL); 24342 } else 24343 return (ret); 24344 if (error == 0) 24345 error = ret; 24346 break; 24347 } 24348 tmpType = tmpType->baseType; 24349 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC)); 24350 } 24351 24352 return (error); 24353 } 24354 24355 static xmlChar * 24356 xmlSchemaNormalizeValue(xmlSchemaTypePtr type, 24357 const xmlChar *value) 24358 { 24359 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) { 24360 case XML_SCHEMA_WHITESPACE_COLLAPSE: 24361 return (xmlSchemaCollapseString(value)); 24362 case XML_SCHEMA_WHITESPACE_REPLACE: 24363 return (xmlSchemaWhiteSpaceReplace(value)); 24364 default: 24365 return (NULL); 24366 } 24367 } 24368 24369 static int 24370 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt, 24371 const xmlChar *value, 24372 xmlSchemaValPtr *val, 24373 int valNeeded) 24374 { 24375 int ret; 24376 const xmlChar *nsName; 24377 xmlChar *local, *prefix = NULL; 24378 24379 ret = xmlValidateQName(value, 1); 24380 if (ret != 0) { 24381 if (ret == -1) { 24382 VERROR_INT("xmlSchemaValidateQName", 24383 "calling xmlValidateQName()"); 24384 return (-1); 24385 } 24386 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1); 24387 } 24388 /* 24389 * NOTE: xmlSplitQName2 will always return a duplicated 24390 * strings. 24391 */ 24392 local = xmlSplitQName2(value, &prefix); 24393 if (local == NULL) 24394 local = xmlStrdup(value); 24395 /* 24396 * OPTIMIZE TODO: Use flags for: 24397 * - is there any namespace binding? 24398 * - is there a default namespace? 24399 */ 24400 nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24401 24402 if (prefix != NULL) { 24403 xmlFree(prefix); 24404 /* 24405 * A namespace must be found if the prefix is 24406 * NOT NULL. 24407 */ 24408 if (nsName == NULL) { 24409 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24410 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL, 24411 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24412 "The QName value '%s' has no " 24413 "corresponding namespace declaration in " 24414 "scope", value, NULL); 24415 if (local != NULL) 24416 xmlFree(local); 24417 return (ret); 24418 } 24419 } 24420 if (valNeeded && val) { 24421 if (nsName != NULL) 24422 *val = xmlSchemaNewQNameValue( 24423 BAD_CAST xmlStrdup(nsName), BAD_CAST local); 24424 else 24425 *val = xmlSchemaNewQNameValue(NULL, 24426 BAD_CAST local); 24427 } else 24428 xmlFree(local); 24429 return (0); 24430 } 24431 24432 /* 24433 * cvc-simple-type 24434 */ 24435 static int 24436 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 24437 xmlNodePtr node, 24438 xmlSchemaTypePtr type, 24439 const xmlChar *value, 24440 xmlSchemaValPtr *retVal, 24441 int fireErrors, 24442 int normalize, 24443 int isNormalized) 24444 { 24445 int ret = 0, valNeeded = (retVal) ? 1 : 0; 24446 xmlSchemaValPtr val = NULL; 24447 /* xmlSchemaWhitespaceValueType ws; */ 24448 xmlChar *normValue = NULL; 24449 24450 #define NORMALIZE(atype) \ 24451 if ((! isNormalized) && \ 24452 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \ 24453 normValue = xmlSchemaNormalizeValue(atype, value); \ 24454 if (normValue != NULL) \ 24455 value = normValue; \ 24456 isNormalized = 1; \ 24457 } 24458 24459 if ((retVal != NULL) && (*retVal != NULL)) { 24460 xmlSchemaFreeValue(*retVal); 24461 *retVal = NULL; 24462 } 24463 /* 24464 * 3.14.4 Simple Type Definition Validation Rules 24465 * Validation Rule: String Valid 24466 */ 24467 /* 24468 * 1 It is schema-valid with respect to that definition as defined 24469 * by Datatype Valid in [XML Schemas: Datatypes]. 24470 */ 24471 /* 24472 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given 24473 * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then 24474 * the string must be a �declared entity name�. 24475 */ 24476 /* 24477 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES 24478 * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), 24479 * then every whitespace-delimited substring of the string must be a �declared 24480 * entity name�. 24481 */ 24482 /* 24483 * 2.3 otherwise no further condition applies. 24484 */ 24485 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE)) 24486 valNeeded = 1; 24487 if (value == NULL) 24488 value = BAD_CAST ""; 24489 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) { 24490 xmlSchemaTypePtr biType; /* The built-in type. */ 24491 /* 24492 * SPEC (1.2.1) "if {variety} is �atomic� then the string must �match� 24493 * a literal in the �lexical space� of {base type definition}" 24494 */ 24495 /* 24496 * Whitespace-normalize. 24497 */ 24498 NORMALIZE(type); 24499 if (type->type != XML_SCHEMA_TYPE_BASIC) { 24500 /* 24501 * Get the built-in type. 24502 */ 24503 biType = type->baseType; 24504 while ((biType != NULL) && 24505 (biType->type != XML_SCHEMA_TYPE_BASIC)) 24506 biType = biType->baseType; 24507 24508 if (biType == NULL) { 24509 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24510 "could not get the built-in type"); 24511 goto internal_error; 24512 } 24513 } else 24514 biType = type; 24515 /* 24516 * NOTATIONs need to be processed here, since they need 24517 * to lookup in the hashtable of NOTATION declarations of the schema. 24518 */ 24519 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 24520 switch (biType->builtInType) { 24521 case XML_SCHEMAS_NOTATION: 24522 ret = xmlSchemaValidateNotation( 24523 (xmlSchemaValidCtxtPtr) actxt, 24524 ((xmlSchemaValidCtxtPtr) actxt)->schema, 24525 NULL, value, &val, valNeeded); 24526 break; 24527 case XML_SCHEMAS_QNAME: 24528 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt, 24529 value, &val, valNeeded); 24530 break; 24531 default: 24532 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24533 if (valNeeded) 24534 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24535 value, &val, node); 24536 else 24537 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24538 value, NULL, node); 24539 break; 24540 } 24541 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 24542 switch (biType->builtInType) { 24543 case XML_SCHEMAS_NOTATION: 24544 ret = xmlSchemaValidateNotation(NULL, 24545 ((xmlSchemaParserCtxtPtr) actxt)->schema, node, 24546 value, &val, valNeeded); 24547 break; 24548 default: 24549 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */ 24550 if (valNeeded) 24551 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24552 value, &val, node); 24553 else 24554 ret = xmlSchemaValPredefTypeNodeNoNorm(biType, 24555 value, NULL, node); 24556 break; 24557 } 24558 } else { 24559 /* 24560 * Validation via a public API is not implemented yet. 24561 */ 24562 TODO 24563 goto internal_error; 24564 } 24565 if (ret != 0) { 24566 if (ret < 0) { 24567 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24568 "validating against a built-in type"); 24569 goto internal_error; 24570 } 24571 if (WXS_IS_LIST(type)) 24572 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24573 else 24574 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24575 } 24576 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24577 /* 24578 * Check facets. 24579 */ 24580 ret = xmlSchemaValidateFacets(actxt, node, type, 24581 (xmlSchemaValType) biType->builtInType, value, val, 24582 0, fireErrors); 24583 if (ret != 0) { 24584 if (ret < 0) { 24585 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24586 "validating facets of atomic simple type"); 24587 goto internal_error; 24588 } 24589 if (WXS_IS_LIST(type)) 24590 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24591 else 24592 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 24593 } 24594 } 24595 if (fireErrors && (ret > 0)) 24596 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24597 } else if (WXS_IS_LIST(type)) { 24598 24599 xmlSchemaTypePtr itemType; 24600 const xmlChar *cur, *end; 24601 xmlChar *tmpValue = NULL; 24602 unsigned long len = 0; 24603 xmlSchemaValPtr prevVal = NULL, curVal = NULL; 24604 /* 1.2.2 if {variety} is �list� then the string must be a sequence 24605 * of white space separated tokens, each of which �match�es a literal 24606 * in the �lexical space� of {item type definition} 24607 */ 24608 /* 24609 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if 24610 * the list type has an enum or pattern facet. 24611 */ 24612 NORMALIZE(type); 24613 /* 24614 * VAL TODO: Optimize validation of empty values. 24615 * VAL TODO: We do not have computed values for lists. 24616 */ 24617 itemType = WXS_LIST_ITEMTYPE(type); 24618 cur = value; 24619 do { 24620 while (IS_BLANK_CH(*cur)) 24621 cur++; 24622 end = cur; 24623 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 24624 end++; 24625 if (end == cur) 24626 break; 24627 tmpValue = xmlStrndup(cur, end - cur); 24628 len++; 24629 24630 if (valNeeded) 24631 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24632 tmpValue, &curVal, fireErrors, 0, 1); 24633 else 24634 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType, 24635 tmpValue, NULL, fireErrors, 0, 1); 24636 FREE_AND_NULL(tmpValue); 24637 if (curVal != NULL) { 24638 /* 24639 * Add to list of computed values. 24640 */ 24641 if (val == NULL) 24642 val = curVal; 24643 else 24644 xmlSchemaValueAppend(prevVal, curVal); 24645 prevVal = curVal; 24646 curVal = NULL; 24647 } 24648 if (ret != 0) { 24649 if (ret < 0) { 24650 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24651 "validating an item of list simple type"); 24652 goto internal_error; 24653 } 24654 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24655 break; 24656 } 24657 cur = end; 24658 } while (*cur != 0); 24659 FREE_AND_NULL(tmpValue); 24660 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24661 /* 24662 * Apply facets (pattern, enumeration). 24663 */ 24664 ret = xmlSchemaValidateFacets(actxt, node, type, 24665 XML_SCHEMAS_UNKNOWN, value, val, 24666 len, fireErrors); 24667 if (ret != 0) { 24668 if (ret < 0) { 24669 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24670 "validating facets of list simple type"); 24671 goto internal_error; 24672 } 24673 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 24674 } 24675 } 24676 if (fireErrors && (ret > 0)) { 24677 /* 24678 * Report the normalized value. 24679 */ 24680 normalize = 1; 24681 NORMALIZE(type); 24682 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24683 } 24684 } else if (WXS_IS_UNION(type)) { 24685 xmlSchemaTypeLinkPtr memberLink; 24686 /* 24687 * TODO: For all datatypes �derived� by �union� whiteSpace does 24688 * not apply directly; however, the normalization behavior of �union� 24689 * types is controlled by the value of whiteSpace on that one of the 24690 * �memberTypes� against which the �union� is successfully validated. 24691 * 24692 * This means that the value is normalized by the first validating 24693 * member type, then the facets of the union type are applied. This 24694 * needs changing of the value! 24695 */ 24696 24697 /* 24698 * 1.2.3 if {variety} is �union� then the string must �match� a 24699 * literal in the �lexical space� of at least one member of 24700 * {member type definitions} 24701 */ 24702 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type); 24703 if (memberLink == NULL) { 24704 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24705 "union simple type has no member types"); 24706 goto internal_error; 24707 } 24708 /* 24709 * Always normalize union type values, since we currently 24710 * cannot store the whitespace information with the value 24711 * itself; otherwise a later value-comparison would be 24712 * not possible. 24713 */ 24714 while (memberLink != NULL) { 24715 if (valNeeded) 24716 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24717 memberLink->type, value, &val, 0, 1, 0); 24718 else 24719 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, 24720 memberLink->type, value, NULL, 0, 1, 0); 24721 if (ret <= 0) 24722 break; 24723 memberLink = memberLink->next; 24724 } 24725 if (ret != 0) { 24726 if (ret < 0) { 24727 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24728 "validating members of union simple type"); 24729 goto internal_error; 24730 } 24731 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24732 } 24733 /* 24734 * Apply facets (pattern, enumeration). 24735 */ 24736 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) { 24737 /* 24738 * The normalization behavior of �union� types is controlled by 24739 * the value of whiteSpace on that one of the �memberTypes� 24740 * against which the �union� is successfully validated. 24741 */ 24742 NORMALIZE(memberLink->type); 24743 ret = xmlSchemaValidateFacets(actxt, node, type, 24744 XML_SCHEMAS_UNKNOWN, value, val, 24745 0, fireErrors); 24746 if (ret != 0) { 24747 if (ret < 0) { 24748 AERROR_INT("xmlSchemaVCheckCVCSimpleType", 24749 "validating facets of union simple type"); 24750 goto internal_error; 24751 } 24752 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3; 24753 } 24754 } 24755 if (fireErrors && (ret > 0)) 24756 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1); 24757 } 24758 24759 if (normValue != NULL) 24760 xmlFree(normValue); 24761 if (ret == 0) { 24762 if (retVal != NULL) 24763 *retVal = val; 24764 else if (val != NULL) 24765 xmlSchemaFreeValue(val); 24766 } else if (val != NULL) 24767 xmlSchemaFreeValue(val); 24768 return (ret); 24769 internal_error: 24770 if (normValue != NULL) 24771 xmlFree(normValue); 24772 if (val != NULL) 24773 xmlSchemaFreeValue(val); 24774 return (-1); 24775 } 24776 24777 static int 24778 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt, 24779 const xmlChar *value, 24780 const xmlChar **nsName, 24781 const xmlChar **localName) 24782 { 24783 int ret = 0; 24784 24785 if ((nsName == NULL) || (localName == NULL)) 24786 return (-1); 24787 *nsName = NULL; 24788 *localName = NULL; 24789 24790 ret = xmlValidateQName(value, 1); 24791 if (ret == -1) 24792 return (-1); 24793 if (ret > 0) { 24794 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt, 24795 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24796 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1); 24797 return (1); 24798 } 24799 { 24800 xmlChar *local = NULL; 24801 xmlChar *prefix; 24802 24803 /* 24804 * NOTE: xmlSplitQName2 will return a duplicated 24805 * string. 24806 */ 24807 local = xmlSplitQName2(value, &prefix); 24808 if (local == NULL) 24809 *localName = xmlDictLookup(vctxt->dict, value, -1); 24810 else { 24811 *localName = xmlDictLookup(vctxt->dict, local, -1); 24812 xmlFree(local); 24813 } 24814 24815 *nsName = xmlSchemaLookupNamespace(vctxt, prefix); 24816 24817 if (prefix != NULL) { 24818 xmlFree(prefix); 24819 /* 24820 * A namespace must be found if the prefix is NOT NULL. 24821 */ 24822 if (*nsName == NULL) { 24823 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24824 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL, 24825 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24826 "The QName value '%s' has no " 24827 "corresponding namespace declaration in scope", 24828 value, NULL); 24829 return (2); 24830 } 24831 } 24832 } 24833 return (0); 24834 } 24835 24836 static int 24837 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt, 24838 xmlSchemaAttrInfoPtr iattr, 24839 xmlSchemaTypePtr *localType, 24840 xmlSchemaElementPtr elemDecl) 24841 { 24842 int ret = 0; 24843 /* 24844 * cvc-elt (3.3.4) : (4) 24845 * AND 24846 * Schema-Validity Assessment (Element) (cvc-assess-elt) 24847 * (1.2.1.2.1) - (1.2.1.2.4) 24848 * Handle 'xsi:type'. 24849 */ 24850 if (localType == NULL) 24851 return (-1); 24852 *localType = NULL; 24853 if (iattr == NULL) 24854 return (0); 24855 else { 24856 const xmlChar *nsName = NULL, *local = NULL; 24857 /* 24858 * TODO: We should report a *warning* that the type was overriden 24859 * by the instance. 24860 */ 24861 ACTIVATE_ATTRIBUTE(iattr); 24862 /* 24863 * (cvc-elt) (3.3.4) : (4.1) 24864 * (cvc-assess-elt) (1.2.1.2.2) 24865 */ 24866 ret = xmlSchemaVExpandQName(vctxt, iattr->value, 24867 &nsName, &local); 24868 if (ret != 0) { 24869 if (ret < 0) { 24870 VERROR_INT("xmlSchemaValidateElementByDeclaration", 24871 "calling xmlSchemaQNameExpand() to validate the " 24872 "attribute 'xsi:type'"); 24873 goto internal_error; 24874 } 24875 goto exit; 24876 } 24877 /* 24878 * (cvc-elt) (3.3.4) : (4.2) 24879 * (cvc-assess-elt) (1.2.1.2.3) 24880 */ 24881 *localType = xmlSchemaGetType(vctxt->schema, local, nsName); 24882 if (*localType == NULL) { 24883 xmlChar *str = NULL; 24884 24885 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24886 XML_SCHEMAV_CVC_ELT_4_2, NULL, 24887 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 24888 "The QName value '%s' of the xsi:type attribute does not " 24889 "resolve to a type definition", 24890 xmlSchemaFormatQName(&str, nsName, local), NULL); 24891 FREE_AND_NULL(str); 24892 ret = vctxt->err; 24893 goto exit; 24894 } 24895 if (elemDecl != NULL) { 24896 int set = 0; 24897 24898 /* 24899 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK) 24900 * "The �local type definition� must be validly 24901 * derived from the {type definition} given the union of 24902 * the {disallowed substitutions} and the {type definition}'s 24903 * {prohibited substitutions}, as defined in 24904 * Type Derivation OK (Complex) (�3.4.6) 24905 * (if it is a complex type definition), 24906 * or given {disallowed substitutions} as defined in Type 24907 * Derivation OK (Simple) (�3.14.6) (if it is a simple type 24908 * definition)." 24909 * 24910 * {disallowed substitutions}: the "block" on the element decl. 24911 * {prohibited substitutions}: the "block" on the type def. 24912 */ 24913 /* 24914 * OPTIMIZE TODO: We could map types already evaluated 24915 * to be validly derived from other types to avoid checking 24916 * this over and over for the same types. 24917 */ 24918 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) || 24919 (elemDecl->subtypes->flags & 24920 XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) 24921 set |= SUBSET_EXTENSION; 24922 24923 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) || 24924 (elemDecl->subtypes->flags & 24925 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)) 24926 set |= SUBSET_RESTRICTION; 24927 24928 /* 24929 * REMOVED and CHANGED since this produced a parser context 24930 * which adds to the string dict of the schema. So this would 24931 * change the schema and we don't want this. We don't need 24932 * the parser context anymore. 24933 * 24934 * if ((vctxt->pctxt == NULL) && 24935 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 24936 * return (-1); 24937 */ 24938 24939 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType, 24940 elemDecl->subtypes, set) != 0) { 24941 xmlChar *str = NULL; 24942 24943 xmlSchemaCustomErr(ACTXT_CAST vctxt, 24944 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL, 24945 "The type definition '%s', specified by xsi:type, is " 24946 "blocked or not validly derived from the type definition " 24947 "of the element declaration", 24948 xmlSchemaFormatQName(&str, 24949 (*localType)->targetNamespace, 24950 (*localType)->name), 24951 NULL); 24952 FREE_AND_NULL(str); 24953 ret = vctxt->err; 24954 *localType = NULL; 24955 } 24956 } 24957 } 24958 exit: 24959 ACTIVATE_ELEM; 24960 return (ret); 24961 internal_error: 24962 ACTIVATE_ELEM; 24963 return (-1); 24964 } 24965 24966 static int 24967 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt) 24968 { 24969 xmlSchemaElementPtr elemDecl = vctxt->inode->decl; 24970 xmlSchemaTypePtr actualType; 24971 24972 /* 24973 * cvc-elt (3.3.4) : 1 24974 */ 24975 if (elemDecl == NULL) { 24976 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, 24977 "No matching declaration available"); 24978 return (vctxt->err); 24979 } 24980 actualType = WXS_ELEM_TYPEDEF(elemDecl); 24981 /* 24982 * cvc-elt (3.3.4) : 2 24983 */ 24984 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) { 24985 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL, 24986 "The element declaration is abstract"); 24987 return (vctxt->err); 24988 } 24989 if (actualType == NULL) { 24990 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 24991 "The type definition is absent"); 24992 return (XML_SCHEMAV_CVC_TYPE_1); 24993 } 24994 if (vctxt->nbAttrInfos != 0) { 24995 int ret; 24996 xmlSchemaAttrInfoPtr iattr; 24997 /* 24998 * cvc-elt (3.3.4) : 3 24999 * Handle 'xsi:nil'. 25000 */ 25001 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25002 XML_SCHEMA_ATTR_INFO_META_XSI_NIL); 25003 if (iattr) { 25004 ACTIVATE_ATTRIBUTE(iattr); 25005 /* 25006 * Validate the value. 25007 */ 25008 ret = xmlSchemaVCheckCVCSimpleType( 25009 ACTXT_CAST vctxt, NULL, 25010 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 25011 iattr->value, &(iattr->val), 1, 0, 0); 25012 ACTIVATE_ELEM; 25013 if (ret < 0) { 25014 VERROR_INT("xmlSchemaValidateElemDecl", 25015 "calling xmlSchemaVCheckCVCSimpleType() to " 25016 "validate the attribute 'xsi:nil'"); 25017 return (-1); 25018 } 25019 if (ret == 0) { 25020 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) { 25021 /* 25022 * cvc-elt (3.3.4) : 3.1 25023 */ 25024 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL, 25025 "The element is not 'nillable'"); 25026 /* Does not return an error on purpose. */ 25027 } else { 25028 if (xmlSchemaValueGetAsBoolean(iattr->val)) { 25029 /* 25030 * cvc-elt (3.3.4) : 3.2.2 25031 */ 25032 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) && 25033 (elemDecl->value != NULL)) { 25034 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL, 25035 "The element cannot be 'nilled' because " 25036 "there is a fixed value constraint defined " 25037 "for it"); 25038 /* Does not return an error on purpose. */ 25039 } else 25040 vctxt->inode->flags |= 25041 XML_SCHEMA_ELEM_INFO_NILLED; 25042 } 25043 } 25044 } 25045 } 25046 /* 25047 * cvc-elt (3.3.4) : 4 25048 * Handle 'xsi:type'. 25049 */ 25050 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25051 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25052 if (iattr) { 25053 xmlSchemaTypePtr localType = NULL; 25054 25055 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType, 25056 elemDecl); 25057 if (ret != 0) { 25058 if (ret == -1) { 25059 VERROR_INT("xmlSchemaValidateElemDecl", 25060 "calling xmlSchemaProcessXSIType() to " 25061 "process the attribute 'xsi:type'"); 25062 return (-1); 25063 } 25064 /* Does not return an error on purpose. */ 25065 } 25066 if (localType != NULL) { 25067 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE; 25068 actualType = localType; 25069 } 25070 } 25071 } 25072 /* 25073 * IDC: Register identity-constraint XPath matchers. 25074 */ 25075 if ((elemDecl->idcs != NULL) && 25076 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1)) 25077 return (-1); 25078 /* 25079 * No actual type definition. 25080 */ 25081 if (actualType == NULL) { 25082 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL, 25083 "The type definition is absent"); 25084 return (XML_SCHEMAV_CVC_TYPE_1); 25085 } 25086 /* 25087 * Remember the actual type definition. 25088 */ 25089 vctxt->inode->typeDef = actualType; 25090 25091 return (0); 25092 } 25093 25094 static int 25095 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt) 25096 { 25097 xmlSchemaAttrInfoPtr iattr; 25098 int ret = 0, i; 25099 25100 /* 25101 * SPEC cvc-type (3.1.1) 25102 * "The attributes of must be empty, excepting those whose namespace 25103 * name is identical to http://www.w3.org/2001/XMLSchema-instance and 25104 * whose local name is one of type, nil, schemaLocation or 25105 * noNamespaceSchemaLocation." 25106 */ 25107 if (vctxt->nbAttrInfos == 0) 25108 return (0); 25109 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25110 iattr = vctxt->attrInfos[i]; 25111 if (! iattr->metaType) { 25112 ACTIVATE_ATTRIBUTE(iattr) 25113 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25114 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL); 25115 ret = XML_SCHEMAV_CVC_TYPE_3_1_1; 25116 } 25117 } 25118 ACTIVATE_ELEM 25119 return (ret); 25120 } 25121 25122 /* 25123 * Cleanup currently used attribute infos. 25124 */ 25125 static void 25126 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt) 25127 { 25128 int i; 25129 xmlSchemaAttrInfoPtr attr; 25130 25131 if (vctxt->nbAttrInfos == 0) 25132 return; 25133 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25134 attr = vctxt->attrInfos[i]; 25135 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) { 25136 if (attr->localName != NULL) 25137 xmlFree((xmlChar *) attr->localName); 25138 if (attr->nsName != NULL) 25139 xmlFree((xmlChar *) attr->nsName); 25140 } 25141 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 25142 if (attr->value != NULL) 25143 xmlFree((xmlChar *) attr->value); 25144 } 25145 if (attr->val != NULL) { 25146 xmlSchemaFreeValue(attr->val); 25147 attr->val = NULL; 25148 } 25149 memset(attr, 0, sizeof(xmlSchemaAttrInfo)); 25150 } 25151 vctxt->nbAttrInfos = 0; 25152 } 25153 25154 /* 25155 * 3.4.4 Complex Type Definition Validation Rules 25156 * Element Locally Valid (Complex Type) (cvc-complex-type) 25157 * 3.2.4 Attribute Declaration Validation Rules 25158 * Validation Rule: Attribute Locally Valid (cvc-attribute) 25159 * Attribute Locally Valid (Use) (cvc-au) 25160 * 25161 * Only "assessed" attribute information items will be visible to 25162 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes. 25163 */ 25164 static int 25165 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt) 25166 { 25167 xmlSchemaTypePtr type = vctxt->inode->typeDef; 25168 xmlSchemaItemListPtr attrUseList; 25169 xmlSchemaAttributeUsePtr attrUse = NULL; 25170 xmlSchemaAttributePtr attrDecl = NULL; 25171 xmlSchemaAttrInfoPtr iattr, tmpiattr; 25172 int i, j, found, nbAttrs, nbUses; 25173 int xpathRes = 0, res, wildIDs = 0, fixed; 25174 xmlNodePtr defAttrOwnerElem = NULL; 25175 25176 /* 25177 * SPEC (cvc-attribute) 25178 * (1) "The declaration must not be �absent� (see Missing 25179 * Sub-components (�5.3) for how this can fail to be 25180 * the case)." 25181 * (2) "Its {type definition} must not be absent." 25182 * 25183 * NOTE (1) + (2): This is not handled here, since we currently do not 25184 * allow validation against schemas which have missing sub-components. 25185 * 25186 * SPEC (cvc-complex-type) 25187 * (3) "For each attribute information item in the element information 25188 * item's [attributes] excepting those whose [namespace name] is 25189 * identical to http://www.w3.org/2001/XMLSchema-instance and whose 25190 * [local name] is one of type, nil, schemaLocation or 25191 * noNamespaceSchemaLocation, the appropriate case among the following 25192 * must be true: 25193 * 25194 */ 25195 attrUseList = (xmlSchemaItemListPtr) type->attrUses; 25196 /* 25197 * @nbAttrs is the number of attributes present in the instance. 25198 */ 25199 nbAttrs = vctxt->nbAttrInfos; 25200 if (attrUseList != NULL) 25201 nbUses = attrUseList->nbItems; 25202 else 25203 nbUses = 0; 25204 for (i = 0; i < nbUses; i++) { 25205 found = 0; 25206 attrUse = attrUseList->items[i]; 25207 attrDecl = WXS_ATTRUSE_DECL(attrUse); 25208 for (j = 0; j < nbAttrs; j++) { 25209 iattr = vctxt->attrInfos[j]; 25210 /* 25211 * SPEC (cvc-complex-type) (3) 25212 * Skip meta attributes. 25213 */ 25214 if (iattr->metaType) 25215 continue; 25216 if (iattr->localName[0] != attrDecl->name[0]) 25217 continue; 25218 if (!xmlStrEqual(iattr->localName, attrDecl->name)) 25219 continue; 25220 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace)) 25221 continue; 25222 found = 1; 25223 /* 25224 * SPEC (cvc-complex-type) 25225 * (3.1) "If there is among the {attribute uses} an attribute 25226 * use with an {attribute declaration} whose {name} matches 25227 * the attribute information item's [local name] and whose 25228 * {target namespace} is identical to the attribute information 25229 * item's [namespace name] (where an �absent� {target namespace} 25230 * is taken to be identical to a [namespace name] with no value), 25231 * then the attribute information must be �valid� with respect 25232 * to that attribute use as per Attribute Locally Valid (Use) 25233 * (�3.5.4). In this case the {attribute declaration} of that 25234 * attribute use is the �context-determined declaration� for the 25235 * attribute information item with respect to Schema-Validity 25236 * Assessment (Attribute) (�3.2.4) and 25237 * Assessment Outcome (Attribute) (�3.2.5). 25238 */ 25239 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25240 iattr->use = attrUse; 25241 /* 25242 * Context-determined declaration. 25243 */ 25244 iattr->decl = attrDecl; 25245 iattr->typeDef = attrDecl->subtypes; 25246 break; 25247 } 25248 25249 if (found) 25250 continue; 25251 25252 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) { 25253 /* 25254 * Handle non-existent, required attributes. 25255 * 25256 * SPEC (cvc-complex-type) 25257 * (4) "The {attribute declaration} of each attribute use in 25258 * the {attribute uses} whose {required} is true matches one 25259 * of the attribute information items in the element information 25260 * item's [attributes] as per clause 3.1 above." 25261 */ 25262 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25263 if (tmpiattr == NULL) { 25264 VERROR_INT( 25265 "xmlSchemaVAttributesComplex", 25266 "calling xmlSchemaGetFreshAttrInfo()"); 25267 return (-1); 25268 } 25269 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING; 25270 tmpiattr->use = attrUse; 25271 tmpiattr->decl = attrDecl; 25272 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 25273 ((attrUse->defValue != NULL) || 25274 (attrDecl->defValue != NULL))) { 25275 /* 25276 * Handle non-existent, optional, default/fixed attributes. 25277 */ 25278 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt); 25279 if (tmpiattr == NULL) { 25280 VERROR_INT( 25281 "xmlSchemaVAttributesComplex", 25282 "calling xmlSchemaGetFreshAttrInfo()"); 25283 return (-1); 25284 } 25285 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT; 25286 tmpiattr->use = attrUse; 25287 tmpiattr->decl = attrDecl; 25288 tmpiattr->typeDef = attrDecl->subtypes; 25289 tmpiattr->localName = attrDecl->name; 25290 tmpiattr->nsName = attrDecl->targetNamespace; 25291 } 25292 } 25293 25294 if (vctxt->nbAttrInfos == 0) 25295 return (0); 25296 /* 25297 * Validate against the wildcard. 25298 */ 25299 if (type->attributeWildcard != NULL) { 25300 /* 25301 * SPEC (cvc-complex-type) 25302 * (3.2.1) "There must be an {attribute wildcard}." 25303 */ 25304 for (i = 0; i < nbAttrs; i++) { 25305 iattr = vctxt->attrInfos[i]; 25306 /* 25307 * SPEC (cvc-complex-type) (3) 25308 * Skip meta attributes. 25309 */ 25310 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN) 25311 continue; 25312 /* 25313 * SPEC (cvc-complex-type) 25314 * (3.2.2) "The attribute information item must be �valid� with 25315 * respect to it as defined in Item Valid (Wildcard) (�3.10.4)." 25316 * 25317 * SPEC Item Valid (Wildcard) (cvc-wildcard) 25318 * "... its [namespace name] must be �valid� with respect to 25319 * the wildcard constraint, as defined in Wildcard allows 25320 * Namespace Name (�3.10.4)." 25321 */ 25322 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard, 25323 iattr->nsName) == 0) { 25324 /* 25325 * Handle processContents. 25326 * 25327 * SPEC (cvc-wildcard): 25328 * processContents | context-determined declaration: 25329 * "strict" "mustFind" 25330 * "lax" "none" 25331 * "skip" "skip" 25332 */ 25333 if (type->attributeWildcard->processContents == 25334 XML_SCHEMAS_ANY_SKIP) { 25335 /* 25336 * context-determined declaration = "skip" 25337 * 25338 * SPEC PSVI Assessment Outcome (Attribute) 25339 * [validity] = "notKnown" 25340 * [validation attempted] = "none" 25341 */ 25342 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP; 25343 continue; 25344 } 25345 /* 25346 * Find an attribute declaration. 25347 */ 25348 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema, 25349 iattr->localName, iattr->nsName); 25350 if (iattr->decl != NULL) { 25351 iattr->state = XML_SCHEMAS_ATTR_ASSESSED; 25352 /* 25353 * SPEC (cvc-complex-type) 25354 * (5) "Let [Definition:] the wild IDs be the set of 25355 * all attribute information item to which clause 3.2 25356 * applied and whose �validation� resulted in a 25357 * �context-determined declaration� of mustFind or no 25358 * �context-determined declaration� at all, and whose 25359 * [local name] and [namespace name] resolve (as 25360 * defined by QName resolution (Instance) (�3.15.4)) to 25361 * an attribute declaration whose {type definition} is 25362 * or is derived from ID. Then all of the following 25363 * must be true:" 25364 */ 25365 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl); 25366 if (xmlSchemaIsDerivedFromBuiltInType( 25367 iattr->typeDef, XML_SCHEMAS_ID)) { 25368 /* 25369 * SPEC (5.1) "There must be no more than one 25370 * item in �wild IDs�." 25371 */ 25372 if (wildIDs != 0) { 25373 /* VAL TODO */ 25374 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID; 25375 TODO 25376 continue; 25377 } 25378 wildIDs++; 25379 /* 25380 * SPEC (cvc-complex-type) 25381 * (5.2) "If �wild IDs� is non-empty, there must not 25382 * be any attribute uses among the {attribute uses} 25383 * whose {attribute declaration}'s {type definition} 25384 * is or is derived from ID." 25385 */ 25386 if (attrUseList != NULL) { 25387 for (j = 0; j < attrUseList->nbItems; j++) { 25388 if (xmlSchemaIsDerivedFromBuiltInType( 25389 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]), 25390 XML_SCHEMAS_ID)) { 25391 /* URGENT VAL TODO: implement */ 25392 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID; 25393 TODO 25394 break; 25395 } 25396 } 25397 } 25398 } 25399 } else if (type->attributeWildcard->processContents == 25400 XML_SCHEMAS_ANY_LAX) { 25401 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL; 25402 /* 25403 * SPEC PSVI Assessment Outcome (Attribute) 25404 * [validity] = "notKnown" 25405 * [validation attempted] = "none" 25406 */ 25407 } else { 25408 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL; 25409 } 25410 } 25411 } 25412 } 25413 25414 if (vctxt->nbAttrInfos == 0) 25415 return (0); 25416 25417 /* 25418 * Get the owner element; needed for creation of default attributes. 25419 * This fixes bug #341337, reported by David Grohmann. 25420 */ 25421 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) { 25422 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth]; 25423 if (ielem && ielem->node && ielem->node->doc) 25424 defAttrOwnerElem = ielem->node; 25425 } 25426 /* 25427 * Validate values, create default attributes, evaluate IDCs. 25428 */ 25429 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25430 iattr = vctxt->attrInfos[i]; 25431 /* 25432 * VAL TODO: Note that we won't try to resolve IDCs to 25433 * "lax" and "skip" validated attributes. Check what to 25434 * do in this case. 25435 */ 25436 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) && 25437 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT)) 25438 continue; 25439 /* 25440 * VAL TODO: What to do if the type definition is missing? 25441 */ 25442 if (iattr->typeDef == NULL) { 25443 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE; 25444 continue; 25445 } 25446 25447 ACTIVATE_ATTRIBUTE(iattr); 25448 fixed = 0; 25449 xpathRes = 0; 25450 25451 if (vctxt->xpathStates != NULL) { 25452 /* 25453 * Evaluate IDCs. 25454 */ 25455 xpathRes = xmlSchemaXPathEvaluate(vctxt, 25456 XML_ATTRIBUTE_NODE); 25457 if (xpathRes == -1) { 25458 VERROR_INT("xmlSchemaVAttributesComplex", 25459 "calling xmlSchemaXPathEvaluate()"); 25460 goto internal_error; 25461 } 25462 } 25463 25464 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) { 25465 /* 25466 * Default/fixed attributes. 25467 * We need the value only if we need to resolve IDCs or 25468 * will create default attributes. 25469 */ 25470 if ((xpathRes) || (defAttrOwnerElem)) { 25471 if (iattr->use->defValue != NULL) { 25472 iattr->value = (xmlChar *) iattr->use->defValue; 25473 iattr->val = iattr->use->defVal; 25474 } else { 25475 iattr->value = (xmlChar *) iattr->decl->defValue; 25476 iattr->val = iattr->decl->defVal; 25477 } 25478 /* 25479 * IDCs will consume the precomputed default value, 25480 * so we need to clone it. 25481 */ 25482 if (iattr->val == NULL) { 25483 VERROR_INT("xmlSchemaVAttributesComplex", 25484 "default/fixed value on an attribute use was " 25485 "not precomputed"); 25486 goto internal_error; 25487 } 25488 iattr->val = xmlSchemaCopyValue(iattr->val); 25489 if (iattr->val == NULL) { 25490 VERROR_INT("xmlSchemaVAttributesComplex", 25491 "calling xmlSchemaCopyValue()"); 25492 goto internal_error; 25493 } 25494 } 25495 /* 25496 * PSVI: Add the default attribute to the current element. 25497 * VAL TODO: Should we use the *normalized* value? This currently 25498 * uses the *initial* value. 25499 */ 25500 25501 if (defAttrOwnerElem) { 25502 xmlChar *normValue; 25503 const xmlChar *value; 25504 25505 value = iattr->value; 25506 /* 25507 * Normalize the value. 25508 */ 25509 normValue = xmlSchemaNormalizeValue(iattr->typeDef, 25510 iattr->value); 25511 if (normValue != NULL) 25512 value = BAD_CAST normValue; 25513 25514 if (iattr->nsName == NULL) { 25515 if (xmlNewProp(defAttrOwnerElem, 25516 iattr->localName, value) == NULL) { 25517 VERROR_INT("xmlSchemaVAttributesComplex", 25518 "callling xmlNewProp()"); 25519 if (normValue != NULL) 25520 xmlFree(normValue); 25521 goto internal_error; 25522 } 25523 } else { 25524 xmlNsPtr ns; 25525 25526 ns = xmlSearchNsByHref(defAttrOwnerElem->doc, 25527 defAttrOwnerElem, iattr->nsName); 25528 if (ns == NULL) { 25529 xmlChar prefix[12]; 25530 int counter = 0; 25531 25532 /* 25533 * Create a namespace declaration on the validation 25534 * root node if no namespace declaration is in scope. 25535 */ 25536 do { 25537 snprintf((char *) prefix, 12, "p%d", counter++); 25538 ns = xmlSearchNs(defAttrOwnerElem->doc, 25539 defAttrOwnerElem, BAD_CAST prefix); 25540 if (counter > 1000) { 25541 VERROR_INT( 25542 "xmlSchemaVAttributesComplex", 25543 "could not compute a ns prefix for a " 25544 "default/fixed attribute"); 25545 if (normValue != NULL) 25546 xmlFree(normValue); 25547 goto internal_error; 25548 } 25549 } while (ns != NULL); 25550 ns = xmlNewNs(vctxt->validationRoot, 25551 iattr->nsName, BAD_CAST prefix); 25552 } 25553 /* 25554 * TODO: 25555 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html 25556 * If we have QNames: do we need to ensure there's a 25557 * prefix defined for the QName? 25558 */ 25559 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value); 25560 } 25561 if (normValue != NULL) 25562 xmlFree(normValue); 25563 } 25564 /* 25565 * Go directly to IDC evaluation. 25566 */ 25567 goto eval_idcs; 25568 } 25569 /* 25570 * Validate the value. 25571 */ 25572 if (vctxt->value != NULL) { 25573 /* 25574 * Free last computed value; just for safety reasons. 25575 */ 25576 xmlSchemaFreeValue(vctxt->value); 25577 vctxt->value = NULL; 25578 } 25579 /* 25580 * Note that the attribute *use* can be unavailable, if 25581 * the attribute was a wild attribute. 25582 */ 25583 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) || 25584 ((iattr->use != NULL) && 25585 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED))) 25586 fixed = 1; 25587 else 25588 fixed = 0; 25589 /* 25590 * SPEC (cvc-attribute) 25591 * (3) "The item's �normalized value� must be locally �valid� 25592 * with respect to that {type definition} as per 25593 * String Valid (�3.14.4)." 25594 * 25595 * VAL TODO: Do we already have the 25596 * "normalized attribute value" here? 25597 */ 25598 if (xpathRes || fixed) { 25599 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED; 25600 /* 25601 * Request a computed value. 25602 */ 25603 res = xmlSchemaVCheckCVCSimpleType( 25604 ACTXT_CAST vctxt, 25605 iattr->node, iattr->typeDef, iattr->value, &(iattr->val), 25606 1, 1, 0); 25607 } else { 25608 res = xmlSchemaVCheckCVCSimpleType( 25609 ACTXT_CAST vctxt, 25610 iattr->node, iattr->typeDef, iattr->value, NULL, 25611 1, 0, 0); 25612 } 25613 25614 if (res != 0) { 25615 if (res == -1) { 25616 VERROR_INT("xmlSchemaVAttributesComplex", 25617 "calling xmlSchemaStreamValidateSimpleTypeValue()"); 25618 goto internal_error; 25619 } 25620 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE; 25621 /* 25622 * SPEC PSVI Assessment Outcome (Attribute) 25623 * [validity] = "invalid" 25624 */ 25625 goto eval_idcs; 25626 } 25627 25628 if (fixed) { 25629 /* 25630 * SPEC Attribute Locally Valid (Use) (cvc-au) 25631 * "For an attribute information item to be�valid� 25632 * with respect to an attribute use its *normalized* 25633 * value� must match the *canonical* lexical 25634 * representation of the attribute use's {value 25635 * constraint}value, if it is present and fixed." 25636 * 25637 * VAL TODO: The requirement for the *canonical* value 25638 * will be removed in XML Schema 1.1. 25639 */ 25640 /* 25641 * SPEC Attribute Locally Valid (cvc-attribute) 25642 * (4) "The item's *actual* value� must match the *value* of 25643 * the {value constraint}, if it is present and fixed." 25644 */ 25645 if (iattr->val == NULL) { 25646 /* VAL TODO: A value was not precomputed. */ 25647 TODO 25648 goto eval_idcs; 25649 } 25650 if ((iattr->use != NULL) && 25651 (iattr->use->defValue != NULL)) { 25652 if (iattr->use->defVal == NULL) { 25653 /* VAL TODO: A default value was not precomputed. */ 25654 TODO 25655 goto eval_idcs; 25656 } 25657 iattr->vcValue = iattr->use->defValue; 25658 /* 25659 if (xmlSchemaCompareValuesWhtsp(attr->val, 25660 (xmlSchemaWhitespaceValueType) ws, 25661 attr->use->defVal, 25662 (xmlSchemaWhitespaceValueType) ws) != 0) { 25663 */ 25664 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal)) 25665 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25666 } else { 25667 if (iattr->decl->defVal == NULL) { 25668 /* VAL TODO: A default value was not precomputed. */ 25669 TODO 25670 goto eval_idcs; 25671 } 25672 iattr->vcValue = iattr->decl->defValue; 25673 /* 25674 if (xmlSchemaCompareValuesWhtsp(attr->val, 25675 (xmlSchemaWhitespaceValueType) ws, 25676 attrDecl->defVal, 25677 (xmlSchemaWhitespaceValueType) ws) != 0) { 25678 */ 25679 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal)) 25680 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE; 25681 } 25682 /* 25683 * [validity] = "valid" 25684 */ 25685 } 25686 eval_idcs: 25687 /* 25688 * Evaluate IDCs. 25689 */ 25690 if (xpathRes) { 25691 if (xmlSchemaXPathProcessHistory(vctxt, 25692 vctxt->depth +1) == -1) { 25693 VERROR_INT("xmlSchemaVAttributesComplex", 25694 "calling xmlSchemaXPathEvaluate()"); 25695 goto internal_error; 25696 } 25697 } else if (vctxt->xpathStates != NULL) 25698 xmlSchemaXPathPop(vctxt); 25699 } 25700 25701 /* 25702 * Report errors. 25703 */ 25704 for (i = 0; i < vctxt->nbAttrInfos; i++) { 25705 iattr = vctxt->attrInfos[i]; 25706 if ((iattr->state == XML_SCHEMAS_ATTR_META) || 25707 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) || 25708 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) || 25709 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL)) 25710 continue; 25711 ACTIVATE_ATTRIBUTE(iattr); 25712 switch (iattr->state) { 25713 case XML_SCHEMAS_ATTR_ERR_MISSING: { 25714 xmlChar *str = NULL; 25715 ACTIVATE_ELEM; 25716 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25717 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL, 25718 "The attribute '%s' is required but missing", 25719 xmlSchemaFormatQName(&str, 25720 iattr->decl->targetNamespace, 25721 iattr->decl->name), 25722 NULL); 25723 FREE_AND_NULL(str) 25724 break; 25725 } 25726 case XML_SCHEMAS_ATTR_ERR_NO_TYPE: 25727 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL, 25728 "The type definition is absent"); 25729 break; 25730 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE: 25731 xmlSchemaCustomErr(ACTXT_CAST vctxt, 25732 XML_SCHEMAV_CVC_AU, NULL, NULL, 25733 "The value '%s' does not match the fixed " 25734 "value constraint '%s'", 25735 iattr->value, iattr->vcValue); 25736 break; 25737 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL: 25738 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL, 25739 "No matching global attribute declaration available, but " 25740 "demanded by the strict wildcard"); 25741 break; 25742 case XML_SCHEMAS_ATTR_UNKNOWN: 25743 if (iattr->metaType) 25744 break; 25745 /* 25746 * MAYBE VAL TODO: One might report different error messages 25747 * for the following errors. 25748 */ 25749 if (type->attributeWildcard == NULL) { 25750 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25751 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL); 25752 } else { 25753 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt, 25754 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL); 25755 } 25756 break; 25757 default: 25758 break; 25759 } 25760 } 25761 25762 ACTIVATE_ELEM; 25763 return (0); 25764 internal_error: 25765 ACTIVATE_ELEM; 25766 return (-1); 25767 } 25768 25769 static int 25770 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt, 25771 int *skip) 25772 { 25773 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl; 25774 /* 25775 * The namespace of the element was already identified to be 25776 * matching the wildcard. 25777 */ 25778 if ((skip == NULL) || (wild == NULL) || 25779 (wild->type != XML_SCHEMA_TYPE_ANY)) { 25780 VERROR_INT("xmlSchemaValidateElemWildcard", 25781 "bad arguments"); 25782 return (-1); 25783 } 25784 *skip = 0; 25785 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) { 25786 /* 25787 * URGENT VAL TODO: Either we need to position the stream to the 25788 * next sibling, or walk the whole subtree. 25789 */ 25790 *skip = 1; 25791 return (0); 25792 } 25793 { 25794 xmlSchemaElementPtr decl = NULL; 25795 25796 decl = xmlSchemaGetElem(vctxt->schema, 25797 vctxt->inode->localName, vctxt->inode->nsName); 25798 if (decl != NULL) { 25799 vctxt->inode->decl = decl; 25800 return (0); 25801 } 25802 } 25803 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) { 25804 /* VAL TODO: Change to proper error code. */ 25805 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */ 25806 "No matching global element declaration available, but " 25807 "demanded by the strict wildcard"); 25808 return (vctxt->err); 25809 } 25810 if (vctxt->nbAttrInfos != 0) { 25811 xmlSchemaAttrInfoPtr iattr; 25812 /* 25813 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25814 * (1.2.1.2.1) - (1.2.1.2.3 ) 25815 * 25816 * Use the xsi:type attribute for the type definition. 25817 */ 25818 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 25819 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 25820 if (iattr != NULL) { 25821 if (xmlSchemaProcessXSIType(vctxt, iattr, 25822 &(vctxt->inode->typeDef), NULL) == -1) { 25823 VERROR_INT("xmlSchemaValidateElemWildcard", 25824 "calling xmlSchemaProcessXSIType() to " 25825 "process the attribute 'xsi:nil'"); 25826 return (-1); 25827 } 25828 /* 25829 * Don't return an error on purpose. 25830 */ 25831 return (0); 25832 } 25833 } 25834 /* 25835 * SPEC Validation Rule: Schema-Validity Assessment (Element) 25836 * 25837 * Fallback to "anyType". 25838 */ 25839 vctxt->inode->typeDef = 25840 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 25841 return (0); 25842 } 25843 25844 /* 25845 * xmlSchemaCheckCOSValidDefault: 25846 * 25847 * This will be called if: not nilled, no content and a default/fixed 25848 * value is provided. 25849 */ 25850 25851 static int 25852 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, 25853 const xmlChar *value, 25854 xmlSchemaValPtr *val) 25855 { 25856 int ret = 0; 25857 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25858 25859 /* 25860 * cos-valid-default: 25861 * Schema Component Constraint: Element Default Valid (Immediate) 25862 * For a string to be a valid default with respect to a type 25863 * definition the appropriate case among the following must be true: 25864 */ 25865 if WXS_IS_COMPLEX(inode->typeDef) { 25866 /* 25867 * Complex type. 25868 * 25869 * SPEC (2.1) "its {content type} must be a simple type definition 25870 * or mixed." 25871 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 25872 * type}'s particle must be �emptiable� as defined by 25873 * Particle Emptiable (�3.9.6)." 25874 */ 25875 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) && 25876 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) || 25877 (! WXS_EMPTIABLE(inode->typeDef)))) { 25878 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1; 25879 /* NOTE that this covers (2.2.2) as well. */ 25880 VERROR(ret, NULL, 25881 "For a string to be a valid default, the type definition " 25882 "must be a simple type or a complex type with simple content " 25883 "or mixed content and a particle emptiable"); 25884 return(ret); 25885 } 25886 } 25887 /* 25888 * 1 If the type definition is a simple type definition, then the string 25889 * must be �valid� with respect to that definition as defined by String 25890 * Valid (�3.14.4). 25891 * 25892 * AND 25893 * 25894 * 2.2.1 If the {content type} is a simple type definition, then the 25895 * string must be �valid� with respect to that simple type definition 25896 * as defined by String Valid (�3.14.4). 25897 */ 25898 if (WXS_IS_SIMPLE(inode->typeDef)) { 25899 25900 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25901 NULL, inode->typeDef, value, val, 1, 1, 0); 25902 25903 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 25904 25905 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt, 25906 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0); 25907 } 25908 if (ret < 0) { 25909 VERROR_INT("xmlSchemaCheckCOSValidDefault", 25910 "calling xmlSchemaVCheckCVCSimpleType()"); 25911 } 25912 return (ret); 25913 } 25914 25915 static void 25916 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, 25917 const xmlChar * name ATTRIBUTE_UNUSED, 25918 xmlSchemaElementPtr item, 25919 xmlSchemaNodeInfoPtr inode) 25920 { 25921 inode->decl = item; 25922 #ifdef DEBUG_CONTENT 25923 { 25924 xmlChar *str = NULL; 25925 25926 if (item->type == XML_SCHEMA_TYPE_ELEMENT) { 25927 xmlGenericError(xmlGenericErrorContext, 25928 "AUTOMATON callback for '%s' [declaration]\n", 25929 xmlSchemaFormatQName(&str, 25930 inode->localName, inode->nsName)); 25931 } else { 25932 xmlGenericError(xmlGenericErrorContext, 25933 "AUTOMATON callback for '%s' [wildcard]\n", 25934 xmlSchemaFormatQName(&str, 25935 inode->localName, inode->nsName)); 25936 25937 } 25938 FREE_AND_NULL(str) 25939 } 25940 #endif 25941 } 25942 25943 static int 25944 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt) 25945 { 25946 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt); 25947 if (vctxt->inode == NULL) { 25948 VERROR_INT("xmlSchemaValidatorPushElem", 25949 "calling xmlSchemaGetFreshElemInfo()"); 25950 return (-1); 25951 } 25952 vctxt->nbAttrInfos = 0; 25953 return (0); 25954 } 25955 25956 static int 25957 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt, 25958 xmlSchemaNodeInfoPtr inode, 25959 xmlSchemaTypePtr type, 25960 const xmlChar *value) 25961 { 25962 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED) 25963 return (xmlSchemaVCheckCVCSimpleType( 25964 ACTXT_CAST vctxt, NULL, 25965 type, value, &(inode->val), 1, 1, 0)); 25966 else 25967 return (xmlSchemaVCheckCVCSimpleType( 25968 ACTXT_CAST vctxt, NULL, 25969 type, value, NULL, 1, 0, 0)); 25970 } 25971 25972 25973 25974 /* 25975 * Process END of element. 25976 */ 25977 static int 25978 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) 25979 { 25980 int ret = 0; 25981 xmlSchemaNodeInfoPtr inode = vctxt->inode; 25982 25983 if (vctxt->nbAttrInfos != 0) 25984 xmlSchemaClearAttrInfos(vctxt); 25985 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) { 25986 /* 25987 * This element was not expected; 25988 * we will not validate child elements of broken parents. 25989 * Skip validation of all content of the parent. 25990 */ 25991 vctxt->skipDepth = vctxt->depth -1; 25992 goto end_elem; 25993 } 25994 if ((inode->typeDef == NULL) || 25995 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) { 25996 /* 25997 * 1. the type definition might be missing if the element was 25998 * error prone 25999 * 2. it might be abstract. 26000 */ 26001 goto end_elem; 26002 } 26003 /* 26004 * Check the content model. 26005 */ 26006 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) || 26007 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) { 26008 26009 /* 26010 * Workaround for "anyType". 26011 */ 26012 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE) 26013 goto character_content; 26014 26015 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) { 26016 xmlChar *values[10]; 26017 int terminal, nbval = 10, nbneg; 26018 26019 if (inode->regexCtxt == NULL) { 26020 /* 26021 * Create the regex context. 26022 */ 26023 inode->regexCtxt = 26024 xmlRegNewExecCtxt(inode->typeDef->contModel, 26025 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26026 vctxt); 26027 if (inode->regexCtxt == NULL) { 26028 VERROR_INT("xmlSchemaValidatorPopElem", 26029 "failed to create a regex context"); 26030 goto internal_error; 26031 } 26032 #ifdef DEBUG_AUTOMATA 26033 xmlGenericError(xmlGenericErrorContext, 26034 "AUTOMATON create on '%s'\n", inode->localName); 26035 #endif 26036 } 26037 /* 26038 * Get hold of the still expected content, since a further 26039 * call to xmlRegExecPushString() will loose this information. 26040 */ 26041 xmlRegExecNextValues(inode->regexCtxt, 26042 &nbval, &nbneg, &values[0], &terminal); 26043 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL); 26044 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) { 26045 /* 26046 * Still missing something. 26047 */ 26048 ret = 1; 26049 inode->flags |= 26050 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26051 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26052 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL, 26053 "Missing child element(s)", 26054 nbval, nbneg, values); 26055 #ifdef DEBUG_AUTOMATA 26056 xmlGenericError(xmlGenericErrorContext, 26057 "AUTOMATON missing ERROR on '%s'\n", 26058 inode->localName); 26059 #endif 26060 } else { 26061 /* 26062 * Content model is satisfied. 26063 */ 26064 ret = 0; 26065 #ifdef DEBUG_AUTOMATA 26066 xmlGenericError(xmlGenericErrorContext, 26067 "AUTOMATON succeeded on '%s'\n", 26068 inode->localName); 26069 #endif 26070 } 26071 26072 } 26073 } 26074 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS) 26075 goto end_elem; 26076 26077 character_content: 26078 26079 if (vctxt->value != NULL) { 26080 xmlSchemaFreeValue(vctxt->value); 26081 vctxt->value = NULL; 26082 } 26083 /* 26084 * Check character content. 26085 */ 26086 if (inode->decl == NULL) { 26087 /* 26088 * Speedup if no declaration exists. 26089 */ 26090 if (WXS_IS_SIMPLE(inode->typeDef)) { 26091 ret = xmlSchemaVCheckINodeDataType(vctxt, 26092 inode, inode->typeDef, inode->value); 26093 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26094 ret = xmlSchemaVCheckINodeDataType(vctxt, 26095 inode, inode->typeDef->contentTypeDef, 26096 inode->value); 26097 } 26098 if (ret < 0) { 26099 VERROR_INT("xmlSchemaValidatorPopElem", 26100 "calling xmlSchemaVCheckCVCSimpleType()"); 26101 goto internal_error; 26102 } 26103 goto end_elem; 26104 } 26105 /* 26106 * cvc-elt (3.3.4) : 5 26107 * The appropriate case among the following must be true: 26108 */ 26109 /* 26110 * cvc-elt (3.3.4) : 5.1 26111 * If the declaration has a {value constraint}, 26112 * the item has neither element nor character [children] and 26113 * clause 3.2 has not applied, then all of the following must be true: 26114 */ 26115 if ((inode->decl->value != NULL) && 26116 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) && 26117 (! INODE_NILLED(inode))) { 26118 /* 26119 * cvc-elt (3.3.4) : 5.1.1 26120 * If the �actual type definition� is a �local type definition� 26121 * then the canonical lexical representation of the {value constraint} 26122 * value must be a valid default for the �actual type definition� as 26123 * defined in Element Default Valid (Immediate) (�3.3.6). 26124 */ 26125 /* 26126 * NOTE: 'local' above means types acquired by xsi:type. 26127 * NOTE: Although the *canonical* value is stated, it is not 26128 * relevant if canonical or not. Additionally XML Schema 1.1 26129 * will removed this requirement as well. 26130 */ 26131 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) { 26132 26133 ret = xmlSchemaCheckCOSValidDefault(vctxt, 26134 inode->decl->value, &(inode->val)); 26135 if (ret != 0) { 26136 if (ret < 0) { 26137 VERROR_INT("xmlSchemaValidatorPopElem", 26138 "calling xmlSchemaCheckCOSValidDefault()"); 26139 goto internal_error; 26140 } 26141 goto end_elem; 26142 } 26143 /* 26144 * Stop here, to avoid redundant validation of the value 26145 * (see following). 26146 */ 26147 goto default_psvi; 26148 } 26149 /* 26150 * cvc-elt (3.3.4) : 5.1.2 26151 * The element information item with the canonical lexical 26152 * representation of the {value constraint} value used as its 26153 * �normalized value� must be �valid� with respect to the 26154 * �actual type definition� as defined by Element Locally Valid (Type) 26155 * (�3.3.4). 26156 */ 26157 if (WXS_IS_SIMPLE(inode->typeDef)) { 26158 ret = xmlSchemaVCheckINodeDataType(vctxt, 26159 inode, inode->typeDef, inode->decl->value); 26160 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26161 ret = xmlSchemaVCheckINodeDataType(vctxt, 26162 inode, inode->typeDef->contentTypeDef, 26163 inode->decl->value); 26164 } 26165 if (ret != 0) { 26166 if (ret < 0) { 26167 VERROR_INT("xmlSchemaValidatorPopElem", 26168 "calling xmlSchemaVCheckCVCSimpleType()"); 26169 goto internal_error; 26170 } 26171 goto end_elem; 26172 } 26173 26174 default_psvi: 26175 /* 26176 * PSVI: Create a text node on the instance element. 26177 */ 26178 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) && 26179 (inode->node != NULL)) { 26180 xmlNodePtr textChild; 26181 xmlChar *normValue; 26182 /* 26183 * VAL TODO: Normalize the value. 26184 */ 26185 normValue = xmlSchemaNormalizeValue(inode->typeDef, 26186 inode->decl->value); 26187 if (normValue != NULL) { 26188 textChild = xmlNewText(BAD_CAST normValue); 26189 xmlFree(normValue); 26190 } else 26191 textChild = xmlNewText(inode->decl->value); 26192 if (textChild == NULL) { 26193 VERROR_INT("xmlSchemaValidatorPopElem", 26194 "calling xmlNewText()"); 26195 goto internal_error; 26196 } else 26197 xmlAddChild(inode->node, textChild); 26198 } 26199 26200 } else if (! INODE_NILLED(inode)) { 26201 /* 26202 * 5.2.1 The element information item must be �valid� with respect 26203 * to the �actual type definition� as defined by Element Locally 26204 * Valid (Type) (�3.3.4). 26205 */ 26206 if (WXS_IS_SIMPLE(inode->typeDef)) { 26207 /* 26208 * SPEC (cvc-type) (3.1) 26209 * "If the type definition is a simple type definition, ..." 26210 * (3.1.3) "If clause 3.2 of Element Locally Valid 26211 * (Element) (�3.3.4) did not apply, then the �normalized value� 26212 * must be �valid� with respect to the type definition as defined 26213 * by String Valid (�3.14.4). 26214 */ 26215 ret = xmlSchemaVCheckINodeDataType(vctxt, 26216 inode, inode->typeDef, inode->value); 26217 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26218 /* 26219 * SPEC (cvc-type) (3.2) "If the type definition is a complex type 26220 * definition, then the element information item must be 26221 * �valid� with respect to the type definition as per 26222 * Element Locally Valid (Complex Type) (�3.4.4);" 26223 * 26224 * SPEC (cvc-complex-type) (2.2) 26225 * "If the {content type} is a simple type definition, ... 26226 * the �normalized value� of the element information item is 26227 * �valid� with respect to that simple type definition as 26228 * defined by String Valid (�3.14.4)." 26229 */ 26230 ret = xmlSchemaVCheckINodeDataType(vctxt, 26231 inode, inode->typeDef->contentTypeDef, inode->value); 26232 } 26233 if (ret != 0) { 26234 if (ret < 0) { 26235 VERROR_INT("xmlSchemaValidatorPopElem", 26236 "calling xmlSchemaVCheckCVCSimpleType()"); 26237 goto internal_error; 26238 } 26239 goto end_elem; 26240 } 26241 /* 26242 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has 26243 * not applied, all of the following must be true: 26244 */ 26245 if ((inode->decl->value != NULL) && 26246 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) { 26247 26248 /* 26249 * TODO: We will need a computed value, when comparison is 26250 * done on computed values. 26251 */ 26252 /* 26253 * 5.2.2.1 The element information item must have no element 26254 * information item [children]. 26255 */ 26256 if (inode->flags & 26257 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) { 26258 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1; 26259 VERROR(ret, NULL, 26260 "The content must not containt element nodes since " 26261 "there is a fixed value constraint"); 26262 goto end_elem; 26263 } else { 26264 /* 26265 * 5.2.2.2 The appropriate case among the following must 26266 * be true: 26267 */ 26268 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) { 26269 /* 26270 * 5.2.2.2.1 If the {content type} of the �actual type 26271 * definition� is mixed, then the *initial value* of the 26272 * item must match the canonical lexical representation 26273 * of the {value constraint} value. 26274 * 26275 * ... the *initial value* of an element information 26276 * item is the string composed of, in order, the 26277 * [character code] of each character information item in 26278 * the [children] of that element information item. 26279 */ 26280 if (! xmlStrEqual(inode->value, inode->decl->value)){ 26281 /* 26282 * VAL TODO: Report invalid & expected values as well. 26283 * VAL TODO: Implement the canonical stuff. 26284 */ 26285 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1; 26286 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26287 ret, NULL, NULL, 26288 "The initial value '%s' does not match the fixed " 26289 "value constraint '%s'", 26290 inode->value, inode->decl->value); 26291 goto end_elem; 26292 } 26293 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) { 26294 /* 26295 * 5.2.2.2.2 If the {content type} of the �actual type 26296 * definition� is a simple type definition, then the 26297 * *actual value* of the item must match the canonical 26298 * lexical representation of the {value constraint} value. 26299 */ 26300 /* 26301 * VAL TODO: *actual value* is the normalized value, impl. 26302 * this. 26303 * VAL TODO: Report invalid & expected values as well. 26304 * VAL TODO: Implement a comparison with the computed values. 26305 */ 26306 if (! xmlStrEqual(inode->value, 26307 inode->decl->value)) { 26308 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2; 26309 xmlSchemaCustomErr(ACTXT_CAST vctxt, 26310 ret, NULL, NULL, 26311 "The actual value '%s' does not match the fixed " 26312 "value constraint '%s'", 26313 inode->value, 26314 inode->decl->value); 26315 goto end_elem; 26316 } 26317 } 26318 } 26319 } 26320 } 26321 26322 end_elem: 26323 if (vctxt->depth < 0) { 26324 /* TODO: raise error? */ 26325 return (0); 26326 } 26327 if (vctxt->depth == vctxt->skipDepth) 26328 vctxt->skipDepth = -1; 26329 /* 26330 * Evaluate the history of XPath state objects. 26331 */ 26332 if (inode->appliedXPath && 26333 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1)) 26334 goto internal_error; 26335 /* 26336 * MAYBE TODO: 26337 * SPEC (6) "The element information item must be �valid� with 26338 * respect to each of the {identity-constraint definitions} as per 26339 * Identity-constraint Satisfied (�3.11.4)." 26340 */ 26341 /* 26342 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables 26343 * need to be built in any case. 26344 * We will currently build IDC node-tables and bubble them only if 26345 * keyrefs do exist. 26346 */ 26347 26348 /* 26349 * Add the current IDC target-nodes to the IDC node-tables. 26350 */ 26351 if ((inode->idcMatchers != NULL) && 26352 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26353 { 26354 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1) 26355 goto internal_error; 26356 } 26357 /* 26358 * Validate IDC keyrefs. 26359 */ 26360 if (vctxt->inode->hasKeyrefs) 26361 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1) 26362 goto internal_error; 26363 /* 26364 * Merge/free the IDC table. 26365 */ 26366 if (inode->idcTable != NULL) { 26367 #ifdef DEBUG_IDC_NODE_TABLE 26368 xmlSchemaDebugDumpIDCTable(stdout, 26369 inode->nsName, 26370 inode->localName, 26371 inode->idcTable); 26372 #endif 26373 if ((vctxt->depth > 0) && 26374 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables)) 26375 { 26376 /* 26377 * Merge the IDC node table with the table of the parent node. 26378 */ 26379 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1) 26380 goto internal_error; 26381 } 26382 } 26383 /* 26384 * Clear the current ielem. 26385 * VAL TODO: Don't free the PSVI IDC tables if they are 26386 * requested for the PSVI. 26387 */ 26388 xmlSchemaClearElemInfo(vctxt, inode); 26389 /* 26390 * Skip further processing if we are on the validation root. 26391 */ 26392 if (vctxt->depth == 0) { 26393 vctxt->depth--; 26394 vctxt->inode = NULL; 26395 return (0); 26396 } 26397 /* 26398 * Reset the keyrefDepth if needed. 26399 */ 26400 if (vctxt->aidcs != NULL) { 26401 xmlSchemaIDCAugPtr aidc = vctxt->aidcs; 26402 do { 26403 if (aidc->keyrefDepth == vctxt->depth) { 26404 /* 26405 * A 'keyrefDepth' of a key/unique IDC matches the current 26406 * depth, this means that we are leaving the scope of the 26407 * top-most keyref IDC which refers to this IDC. 26408 */ 26409 aidc->keyrefDepth = -1; 26410 } 26411 aidc = aidc->next; 26412 } while (aidc != NULL); 26413 } 26414 vctxt->depth--; 26415 vctxt->inode = vctxt->elemInfos[vctxt->depth]; 26416 /* 26417 * VAL TODO: 7 If the element information item is the �validation root�, it must be 26418 * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4). 26419 */ 26420 return (ret); 26421 26422 internal_error: 26423 vctxt->err = -1; 26424 return (-1); 26425 } 26426 26427 /* 26428 * 3.4.4 Complex Type Definition Validation Rules 26429 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type) 26430 */ 26431 static int 26432 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) 26433 { 26434 xmlSchemaNodeInfoPtr pielem; 26435 xmlSchemaTypePtr ptype; 26436 int ret = 0; 26437 26438 if (vctxt->depth <= 0) { 26439 VERROR_INT("xmlSchemaValidateChildElem", 26440 "not intended for the validation root"); 26441 return (-1); 26442 } 26443 pielem = vctxt->elemInfos[vctxt->depth -1]; 26444 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 26445 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 26446 /* 26447 * Handle 'nilled' elements. 26448 */ 26449 if (INODE_NILLED(pielem)) { 26450 /* 26451 * SPEC (cvc-elt) (3.3.4) : (3.2.1) 26452 */ 26453 ACTIVATE_PARENT_ELEM; 26454 ret = XML_SCHEMAV_CVC_ELT_3_2_1; 26455 VERROR(ret, NULL, 26456 "Neither character nor element content is allowed, " 26457 "because the element was 'nilled'"); 26458 ACTIVATE_ELEM; 26459 goto unexpected_elem; 26460 } 26461 26462 ptype = pielem->typeDef; 26463 26464 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) { 26465 /* 26466 * Workaround for "anyType": we have currently no content model 26467 * assigned for "anyType", so handle it explicitely. 26468 * "anyType" has an unbounded, lax "any" wildcard. 26469 */ 26470 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26471 vctxt->inode->localName, 26472 vctxt->inode->nsName); 26473 26474 if (vctxt->inode->decl == NULL) { 26475 xmlSchemaAttrInfoPtr iattr; 26476 /* 26477 * Process "xsi:type". 26478 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3) 26479 */ 26480 iattr = xmlSchemaGetMetaAttrInfo(vctxt, 26481 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE); 26482 if (iattr != NULL) { 26483 ret = xmlSchemaProcessXSIType(vctxt, iattr, 26484 &(vctxt->inode->typeDef), NULL); 26485 if (ret != 0) { 26486 if (ret == -1) { 26487 VERROR_INT("xmlSchemaValidateChildElem", 26488 "calling xmlSchemaProcessXSIType() to " 26489 "process the attribute 'xsi:nil'"); 26490 return (-1); 26491 } 26492 return (ret); 26493 } 26494 } else { 26495 /* 26496 * Fallback to "anyType". 26497 * 26498 * SPEC (cvc-assess-elt) 26499 * "If the item cannot be �strictly assessed�, [...] 26500 * an element information item's schema validity may be laxly 26501 * assessed if its �context-determined declaration� is not 26502 * skip by �validating� with respect to the �ur-type 26503 * definition� as per Element Locally Valid (Type) (�3.3.4)." 26504 */ 26505 vctxt->inode->typeDef = 26506 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 26507 } 26508 } 26509 return (0); 26510 } 26511 26512 switch (ptype->contentType) { 26513 case XML_SCHEMA_CONTENT_EMPTY: 26514 /* 26515 * SPEC (2.1) "If the {content type} is empty, then the 26516 * element information item has no character or element 26517 * information item [children]." 26518 */ 26519 ACTIVATE_PARENT_ELEM 26520 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1; 26521 VERROR(ret, NULL, 26522 "Element content is not allowed, " 26523 "because the content type is empty"); 26524 ACTIVATE_ELEM 26525 goto unexpected_elem; 26526 break; 26527 26528 case XML_SCHEMA_CONTENT_MIXED: 26529 case XML_SCHEMA_CONTENT_ELEMENTS: { 26530 xmlRegExecCtxtPtr regexCtxt; 26531 xmlChar *values[10]; 26532 int terminal, nbval = 10, nbneg; 26533 26534 /* VAL TODO: Optimized "anyType" validation.*/ 26535 26536 if (ptype->contModel == NULL) { 26537 VERROR_INT("xmlSchemaValidateChildElem", 26538 "type has elem content but no content model"); 26539 return (-1); 26540 } 26541 /* 26542 * Safety belf for evaluation if the cont. model was already 26543 * examined to be invalid. 26544 */ 26545 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) { 26546 VERROR_INT("xmlSchemaValidateChildElem", 26547 "validating elem, but elem content is already invalid"); 26548 return (-1); 26549 } 26550 26551 regexCtxt = pielem->regexCtxt; 26552 if (regexCtxt == NULL) { 26553 /* 26554 * Create the regex context. 26555 */ 26556 regexCtxt = xmlRegNewExecCtxt(ptype->contModel, 26557 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, 26558 vctxt); 26559 if (regexCtxt == NULL) { 26560 VERROR_INT("xmlSchemaValidateChildElem", 26561 "failed to create a regex context"); 26562 return (-1); 26563 } 26564 pielem->regexCtxt = regexCtxt; 26565 #ifdef DEBUG_AUTOMATA 26566 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n", 26567 pielem->localName); 26568 #endif 26569 } 26570 26571 /* 26572 * SPEC (2.4) "If the {content type} is element-only or mixed, 26573 * then the sequence of the element information item's 26574 * element information item [children], if any, taken in 26575 * order, is �valid� with respect to the {content type}'s 26576 * particle, as defined in Element Sequence Locally Valid 26577 * (Particle) (�3.9.4)." 26578 */ 26579 ret = xmlRegExecPushString2(regexCtxt, 26580 vctxt->inode->localName, 26581 vctxt->inode->nsName, 26582 vctxt->inode); 26583 #ifdef DEBUG_AUTOMATA 26584 if (ret < 0) 26585 xmlGenericError(xmlGenericErrorContext, 26586 "AUTOMATON push ERROR for '%s' on '%s'\n", 26587 vctxt->inode->localName, pielem->localName); 26588 else 26589 xmlGenericError(xmlGenericErrorContext, 26590 "AUTOMATON push OK for '%s' on '%s'\n", 26591 vctxt->inode->localName, pielem->localName); 26592 #endif 26593 if (vctxt->err == XML_SCHEMAV_INTERNAL) { 26594 VERROR_INT("xmlSchemaValidateChildElem", 26595 "calling xmlRegExecPushString2()"); 26596 return (-1); 26597 } 26598 if (ret < 0) { 26599 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg, 26600 &values[0], &terminal); 26601 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt, 26602 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL, 26603 "This element is not expected", 26604 nbval, nbneg, values); 26605 ret = vctxt->err; 26606 goto unexpected_elem; 26607 } else 26608 ret = 0; 26609 } 26610 break; 26611 case XML_SCHEMA_CONTENT_SIMPLE: 26612 case XML_SCHEMA_CONTENT_BASIC: 26613 ACTIVATE_PARENT_ELEM 26614 if (WXS_IS_COMPLEX(ptype)) { 26615 /* 26616 * SPEC (cvc-complex-type) (2.2) 26617 * "If the {content type} is a simple type definition, then 26618 * the element information item has no element information 26619 * item [children], ..." 26620 */ 26621 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2; 26622 VERROR(ret, NULL, "Element content is not allowed, " 26623 "because the content type is a simple type definition"); 26624 } else { 26625 /* 26626 * SPEC (cvc-type) (3.1.2) "The element information item must 26627 * have no element information item [children]." 26628 */ 26629 ret = XML_SCHEMAV_CVC_TYPE_3_1_2; 26630 VERROR(ret, NULL, "Element content is not allowed, " 26631 "because the type definition is simple"); 26632 } 26633 ACTIVATE_ELEM 26634 ret = vctxt->err; 26635 goto unexpected_elem; 26636 break; 26637 26638 default: 26639 break; 26640 } 26641 return (ret); 26642 unexpected_elem: 26643 /* 26644 * Pop this element and set the skipDepth to skip 26645 * all further content of the parent element. 26646 */ 26647 vctxt->skipDepth = vctxt->depth; 26648 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED; 26649 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT; 26650 return (ret); 26651 } 26652 26653 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1 26654 #define XML_SCHEMA_PUSH_TEXT_CREATED 2 26655 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3 26656 26657 static int 26658 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt, 26659 int nodeType, const xmlChar *value, int len, 26660 int mode, int *consumed) 26661 { 26662 /* 26663 * Unfortunately we have to duplicate the text sometimes. 26664 * OPTIMIZE: Maybe we could skip it, if: 26665 * 1. content type is simple 26666 * 2. whitespace is "collapse" 26667 * 3. it consists of whitespace only 26668 * 26669 * Process character content. 26670 */ 26671 if (consumed != NULL) 26672 *consumed = 0; 26673 if (INODE_NILLED(vctxt->inode)) { 26674 /* 26675 * SPEC cvc-elt (3.3.4 - 3.2.1) 26676 * "The element information item must have no character or 26677 * element information item [children]." 26678 */ 26679 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL, 26680 "Neither character nor element content is allowed " 26681 "because the element is 'nilled'"); 26682 return (vctxt->err); 26683 } 26684 /* 26685 * SPEC (2.1) "If the {content type} is empty, then the 26686 * element information item has no character or element 26687 * information item [children]." 26688 */ 26689 if (vctxt->inode->typeDef->contentType == 26690 XML_SCHEMA_CONTENT_EMPTY) { 26691 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL, 26692 "Character content is not allowed, " 26693 "because the content type is empty"); 26694 return (vctxt->err); 26695 } 26696 26697 if (vctxt->inode->typeDef->contentType == 26698 XML_SCHEMA_CONTENT_ELEMENTS) { 26699 if ((nodeType != XML_TEXT_NODE) || 26700 (! xmlSchemaIsBlank((xmlChar *) value, len))) { 26701 /* 26702 * SPEC cvc-complex-type (2.3) 26703 * "If the {content type} is element-only, then the 26704 * element information item has no character information 26705 * item [children] other than those whose [character 26706 * code] is defined as a white space in [XML 1.0 (Second 26707 * Edition)]." 26708 */ 26709 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL, 26710 "Character content other than whitespace is not allowed " 26711 "because the content type is 'element-only'"); 26712 return (vctxt->err); 26713 } 26714 return (0); 26715 } 26716 26717 if ((value == NULL) || (value[0] == 0)) 26718 return (0); 26719 /* 26720 * Save the value. 26721 * NOTE that even if the content type is *mixed*, we need the 26722 * *initial value* for default/fixed value constraints. 26723 */ 26724 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) && 26725 ((vctxt->inode->decl == NULL) || 26726 (vctxt->inode->decl->value == NULL))) 26727 return (0); 26728 26729 if (vctxt->inode->value == NULL) { 26730 /* 26731 * Set the value. 26732 */ 26733 switch (mode) { 26734 case XML_SCHEMA_PUSH_TEXT_PERSIST: 26735 /* 26736 * When working on a tree. 26737 */ 26738 vctxt->inode->value = value; 26739 break; 26740 case XML_SCHEMA_PUSH_TEXT_CREATED: 26741 /* 26742 * When working with the reader. 26743 * The value will be freed by the element info. 26744 */ 26745 vctxt->inode->value = value; 26746 if (consumed != NULL) 26747 *consumed = 1; 26748 vctxt->inode->flags |= 26749 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26750 break; 26751 case XML_SCHEMA_PUSH_TEXT_VOLATILE: 26752 /* 26753 * When working with SAX. 26754 * The value will be freed by the element info. 26755 */ 26756 if (len != -1) 26757 vctxt->inode->value = BAD_CAST xmlStrndup(value, len); 26758 else 26759 vctxt->inode->value = BAD_CAST xmlStrdup(value); 26760 vctxt->inode->flags |= 26761 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26762 break; 26763 default: 26764 break; 26765 } 26766 } else { 26767 if (len < 0) 26768 len = xmlStrlen(value); 26769 /* 26770 * Concat the value. 26771 */ 26772 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) { 26773 vctxt->inode->value = BAD_CAST xmlStrncat( 26774 (xmlChar *) vctxt->inode->value, value, len); 26775 } else { 26776 vctxt->inode->value = 26777 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len); 26778 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES; 26779 } 26780 } 26781 26782 return (0); 26783 } 26784 26785 static int 26786 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) 26787 { 26788 int ret = 0; 26789 26790 if ((vctxt->skipDepth != -1) && 26791 (vctxt->depth >= vctxt->skipDepth)) { 26792 VERROR_INT("xmlSchemaValidateElem", 26793 "in skip-state"); 26794 goto internal_error; 26795 } 26796 if (vctxt->xsiAssemble) { 26797 /* 26798 * We will stop validation if there was an error during 26799 * dynamic schema construction. 26800 * Note that we simply set @skipDepth to 0, this could 26801 * mean that a streaming document via SAX would be 26802 * still read to the end but it won't be validated any more. 26803 * TODO: If we are sure how to stop the validation at once 26804 * for all input scenarios, then this should be changed to 26805 * instantly stop the validation. 26806 */ 26807 ret = xmlSchemaAssembleByXSI(vctxt); 26808 if (ret != 0) { 26809 if (ret == -1) 26810 goto internal_error; 26811 vctxt->skipDepth = 0; 26812 return(ret); 26813 } 26814 /* 26815 * Augment the IDC definitions for the main schema and all imported ones 26816 * NOTE: main schema is the first in the imported list 26817 */ 26818 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 26819 } 26820 if (vctxt->depth > 0) { 26821 /* 26822 * Validate this element against the content model 26823 * of the parent. 26824 */ 26825 ret = xmlSchemaValidateChildElem(vctxt); 26826 if (ret != 0) { 26827 if (ret < 0) { 26828 VERROR_INT("xmlSchemaValidateElem", 26829 "calling xmlSchemaStreamValidateChildElement()"); 26830 goto internal_error; 26831 } 26832 goto exit; 26833 } 26834 if (vctxt->depth == vctxt->skipDepth) 26835 goto exit; 26836 if ((vctxt->inode->decl == NULL) && 26837 (vctxt->inode->typeDef == NULL)) { 26838 VERROR_INT("xmlSchemaValidateElem", 26839 "the child element was valid but neither the " 26840 "declaration nor the type was set"); 26841 goto internal_error; 26842 } 26843 } else { 26844 /* 26845 * Get the declaration of the validation root. 26846 */ 26847 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema, 26848 vctxt->inode->localName, 26849 vctxt->inode->nsName); 26850 if (vctxt->inode->decl == NULL) { 26851 ret = XML_SCHEMAV_CVC_ELT_1; 26852 VERROR(ret, NULL, 26853 "No matching global declaration available " 26854 "for the validation root"); 26855 goto exit; 26856 } 26857 } 26858 26859 if (vctxt->inode->decl == NULL) 26860 goto type_validation; 26861 26862 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) { 26863 int skip; 26864 /* 26865 * Wildcards. 26866 */ 26867 ret = xmlSchemaValidateElemWildcard(vctxt, &skip); 26868 if (ret != 0) { 26869 if (ret < 0) { 26870 VERROR_INT("xmlSchemaValidateElem", 26871 "calling xmlSchemaValidateElemWildcard()"); 26872 goto internal_error; 26873 } 26874 goto exit; 26875 } 26876 if (skip) { 26877 vctxt->skipDepth = vctxt->depth; 26878 goto exit; 26879 } 26880 /* 26881 * The declaration might be set by the wildcard validation, 26882 * when the processContents is "lax" or "strict". 26883 */ 26884 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) { 26885 /* 26886 * Clear the "decl" field to not confuse further processing. 26887 */ 26888 vctxt->inode->decl = NULL; 26889 goto type_validation; 26890 } 26891 } 26892 /* 26893 * Validate against the declaration. 26894 */ 26895 ret = xmlSchemaValidateElemDecl(vctxt); 26896 if (ret != 0) { 26897 if (ret < 0) { 26898 VERROR_INT("xmlSchemaValidateElem", 26899 "calling xmlSchemaValidateElemDecl()"); 26900 goto internal_error; 26901 } 26902 goto exit; 26903 } 26904 /* 26905 * Validate against the type definition. 26906 */ 26907 type_validation: 26908 26909 if (vctxt->inode->typeDef == NULL) { 26910 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26911 ret = XML_SCHEMAV_CVC_TYPE_1; 26912 VERROR(ret, NULL, 26913 "The type definition is absent"); 26914 goto exit; 26915 } 26916 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) { 26917 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE; 26918 ret = XML_SCHEMAV_CVC_TYPE_2; 26919 VERROR(ret, NULL, 26920 "The type definition is abstract"); 26921 goto exit; 26922 } 26923 /* 26924 * Evaluate IDCs. Do it here, since new IDC matchers are registered 26925 * during validation against the declaration. This must be done 26926 * _before_ attribute validation. 26927 */ 26928 if (vctxt->xpathStates != NULL) { 26929 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE); 26930 vctxt->inode->appliedXPath = 1; 26931 if (ret == -1) { 26932 VERROR_INT("xmlSchemaValidateElem", 26933 "calling xmlSchemaXPathEvaluate()"); 26934 goto internal_error; 26935 } 26936 } 26937 /* 26938 * Validate attributes. 26939 */ 26940 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) { 26941 if ((vctxt->nbAttrInfos != 0) || 26942 (vctxt->inode->typeDef->attrUses != NULL)) { 26943 26944 ret = xmlSchemaVAttributesComplex(vctxt); 26945 } 26946 } else if (vctxt->nbAttrInfos != 0) { 26947 26948 ret = xmlSchemaVAttributesSimple(vctxt); 26949 } 26950 /* 26951 * Clear registered attributes. 26952 */ 26953 if (vctxt->nbAttrInfos != 0) 26954 xmlSchemaClearAttrInfos(vctxt); 26955 if (ret == -1) { 26956 VERROR_INT("xmlSchemaValidateElem", 26957 "calling attributes validation"); 26958 goto internal_error; 26959 } 26960 /* 26961 * Don't return an error if attributes are invalid on purpose. 26962 */ 26963 ret = 0; 26964 26965 exit: 26966 if (ret != 0) 26967 vctxt->skipDepth = vctxt->depth; 26968 return (ret); 26969 internal_error: 26970 return (-1); 26971 } 26972 26973 #ifdef XML_SCHEMA_READER_ENABLED 26974 static int 26975 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt) 26976 { 26977 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15; 26978 int depth, nodeType, ret = 0, consumed; 26979 xmlSchemaNodeInfoPtr ielem; 26980 26981 vctxt->depth = -1; 26982 ret = xmlTextReaderRead(vctxt->reader); 26983 /* 26984 * Move to the document element. 26985 */ 26986 while (ret == 1) { 26987 nodeType = xmlTextReaderNodeType(vctxt->reader); 26988 if (nodeType == XML_ELEMENT_NODE) 26989 goto root_found; 26990 ret = xmlTextReaderRead(vctxt->reader); 26991 } 26992 goto exit; 26993 26994 root_found: 26995 26996 do { 26997 depth = xmlTextReaderDepth(vctxt->reader); 26998 nodeType = xmlTextReaderNodeType(vctxt->reader); 26999 27000 if (nodeType == XML_ELEMENT_NODE) { 27001 27002 vctxt->depth++; 27003 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27004 VERROR_INT("xmlSchemaVReaderWalk", 27005 "calling xmlSchemaValidatorPushElem()"); 27006 goto internal_error; 27007 } 27008 ielem = vctxt->inode; 27009 ielem->localName = xmlTextReaderLocalName(vctxt->reader); 27010 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader); 27011 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES; 27012 /* 27013 * Is the element empty? 27014 */ 27015 ret = xmlTextReaderIsEmptyElement(vctxt->reader); 27016 if (ret == -1) { 27017 VERROR_INT("xmlSchemaVReaderWalk", 27018 "calling xmlTextReaderIsEmptyElement()"); 27019 goto internal_error; 27020 } 27021 if (ret) { 27022 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27023 } 27024 /* 27025 * Register attributes. 27026 */ 27027 vctxt->nbAttrInfos = 0; 27028 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader); 27029 if (ret == -1) { 27030 VERROR_INT("xmlSchemaVReaderWalk", 27031 "calling xmlTextReaderMoveToFirstAttribute()"); 27032 goto internal_error; 27033 } 27034 if (ret == 1) { 27035 do { 27036 /* 27037 * VAL TODO: How do we know that the reader works on a 27038 * node tree, to be able to pass a node here? 27039 */ 27040 if (xmlSchemaValidatorPushAttribute(vctxt, NULL, 27041 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader), 27042 xmlTextReaderNamespaceUri(vctxt->reader), 1, 27043 xmlTextReaderValue(vctxt->reader), 1) == -1) { 27044 27045 VERROR_INT("xmlSchemaVReaderWalk", 27046 "calling xmlSchemaValidatorPushAttribute()"); 27047 goto internal_error; 27048 } 27049 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader); 27050 if (ret == -1) { 27051 VERROR_INT("xmlSchemaVReaderWalk", 27052 "calling xmlTextReaderMoveToFirstAttribute()"); 27053 goto internal_error; 27054 } 27055 } while (ret == 1); 27056 /* 27057 * Back to element position. 27058 */ 27059 ret = xmlTextReaderMoveToElement(vctxt->reader); 27060 if (ret == -1) { 27061 VERROR_INT("xmlSchemaVReaderWalk", 27062 "calling xmlTextReaderMoveToElement()"); 27063 goto internal_error; 27064 } 27065 } 27066 /* 27067 * Validate the element. 27068 */ 27069 ret= xmlSchemaValidateElem(vctxt); 27070 if (ret != 0) { 27071 if (ret == -1) { 27072 VERROR_INT("xmlSchemaVReaderWalk", 27073 "calling xmlSchemaValidateElem()"); 27074 goto internal_error; 27075 } 27076 goto exit; 27077 } 27078 if (vctxt->depth == vctxt->skipDepth) { 27079 int curDepth; 27080 /* 27081 * Skip all content. 27082 */ 27083 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) { 27084 ret = xmlTextReaderRead(vctxt->reader); 27085 curDepth = xmlTextReaderDepth(vctxt->reader); 27086 while ((ret == 1) && (curDepth != depth)) { 27087 ret = xmlTextReaderRead(vctxt->reader); 27088 curDepth = xmlTextReaderDepth(vctxt->reader); 27089 } 27090 if (ret < 0) { 27091 /* 27092 * VAL TODO: A reader error occured; what to do here? 27093 */ 27094 ret = 1; 27095 goto exit; 27096 } 27097 } 27098 goto leave_elem; 27099 } 27100 /* 27101 * READER VAL TODO: Is an END_ELEM really never called 27102 * if the elem is empty? 27103 */ 27104 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27105 goto leave_elem; 27106 } else if (nodeType == END_ELEM) { 27107 /* 27108 * Process END of element. 27109 */ 27110 leave_elem: 27111 ret = xmlSchemaValidatorPopElem(vctxt); 27112 if (ret != 0) { 27113 if (ret < 0) { 27114 VERROR_INT("xmlSchemaVReaderWalk", 27115 "calling xmlSchemaValidatorPopElem()"); 27116 goto internal_error; 27117 } 27118 goto exit; 27119 } 27120 if (vctxt->depth >= 0) 27121 ielem = vctxt->inode; 27122 else 27123 ielem = NULL; 27124 } else if ((nodeType == XML_TEXT_NODE) || 27125 (nodeType == XML_CDATA_SECTION_NODE) || 27126 (nodeType == WHTSP) || 27127 (nodeType == SIGN_WHTSP)) { 27128 /* 27129 * Process character content. 27130 */ 27131 xmlChar *value; 27132 27133 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP)) 27134 nodeType = XML_TEXT_NODE; 27135 27136 value = xmlTextReaderValue(vctxt->reader); 27137 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value, 27138 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed); 27139 if (! consumed) 27140 xmlFree(value); 27141 if (ret == -1) { 27142 VERROR_INT("xmlSchemaVReaderWalk", 27143 "calling xmlSchemaVPushText()"); 27144 goto internal_error; 27145 } 27146 } else if ((nodeType == XML_ENTITY_NODE) || 27147 (nodeType == XML_ENTITY_REF_NODE)) { 27148 /* 27149 * VAL TODO: What to do with entities? 27150 */ 27151 TODO 27152 } 27153 /* 27154 * Read next node. 27155 */ 27156 ret = xmlTextReaderRead(vctxt->reader); 27157 } while (ret == 1); 27158 27159 exit: 27160 return (ret); 27161 internal_error: 27162 return (-1); 27163 } 27164 #endif 27165 27166 /************************************************************************ 27167 * * 27168 * SAX validation handlers * 27169 * * 27170 ************************************************************************/ 27171 27172 /* 27173 * Process text content. 27174 */ 27175 static void 27176 xmlSchemaSAXHandleText(void *ctx, 27177 const xmlChar * ch, 27178 int len) 27179 { 27180 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27181 27182 if (vctxt->depth < 0) 27183 return; 27184 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27185 return; 27186 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27187 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27188 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len, 27189 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27190 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27191 "calling xmlSchemaVPushText()"); 27192 vctxt->err = -1; 27193 xmlStopParser(vctxt->parserCtxt); 27194 } 27195 } 27196 27197 /* 27198 * Process CDATA content. 27199 */ 27200 static void 27201 xmlSchemaSAXHandleCDataSection(void *ctx, 27202 const xmlChar * ch, 27203 int len) 27204 { 27205 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27206 27207 if (vctxt->depth < 0) 27208 return; 27209 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27210 return; 27211 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) 27212 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27213 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len, 27214 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) { 27215 VERROR_INT("xmlSchemaSAXHandleCDataSection", 27216 "calling xmlSchemaVPushText()"); 27217 vctxt->err = -1; 27218 xmlStopParser(vctxt->parserCtxt); 27219 } 27220 } 27221 27222 static void 27223 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED, 27224 const xmlChar * name ATTRIBUTE_UNUSED) 27225 { 27226 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27227 27228 if (vctxt->depth < 0) 27229 return; 27230 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27231 return; 27232 /* SAX VAL TODO: What to do here? */ 27233 TODO 27234 } 27235 27236 static void 27237 xmlSchemaSAXHandleStartElementNs(void *ctx, 27238 const xmlChar * localname, 27239 const xmlChar * prefix ATTRIBUTE_UNUSED, 27240 const xmlChar * URI, 27241 int nb_namespaces, 27242 const xmlChar ** namespaces, 27243 int nb_attributes, 27244 int nb_defaulted ATTRIBUTE_UNUSED, 27245 const xmlChar ** attributes) 27246 { 27247 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27248 int ret; 27249 xmlSchemaNodeInfoPtr ielem; 27250 int i, j; 27251 27252 /* 27253 * SAX VAL TODO: What to do with nb_defaulted? 27254 */ 27255 /* 27256 * Skip elements if inside a "skip" wildcard or invalid. 27257 */ 27258 vctxt->depth++; 27259 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27260 return; 27261 /* 27262 * Push the element. 27263 */ 27264 if (xmlSchemaValidatorPushElem(vctxt) == -1) { 27265 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27266 "calling xmlSchemaValidatorPushElem()"); 27267 goto internal_error; 27268 } 27269 ielem = vctxt->inode; 27270 /* 27271 * TODO: Is this OK? 27272 */ 27273 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt); 27274 ielem->localName = localname; 27275 ielem->nsName = URI; 27276 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27277 /* 27278 * Register namespaces on the elem info. 27279 */ 27280 if (nb_namespaces != 0) { 27281 /* 27282 * Although the parser builds its own namespace list, 27283 * we have no access to it, so we'll use an own one. 27284 */ 27285 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) { 27286 /* 27287 * Store prefix and namespace name. 27288 */ 27289 if (ielem->nsBindings == NULL) { 27290 ielem->nsBindings = 27291 (const xmlChar **) xmlMalloc(10 * 27292 sizeof(const xmlChar *)); 27293 if (ielem->nsBindings == NULL) { 27294 xmlSchemaVErrMemory(vctxt, 27295 "allocating namespace bindings for SAX validation", 27296 NULL); 27297 goto internal_error; 27298 } 27299 ielem->nbNsBindings = 0; 27300 ielem->sizeNsBindings = 5; 27301 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) { 27302 ielem->sizeNsBindings *= 2; 27303 ielem->nsBindings = 27304 (const xmlChar **) xmlRealloc( 27305 (void *) ielem->nsBindings, 27306 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *)); 27307 if (ielem->nsBindings == NULL) { 27308 xmlSchemaVErrMemory(vctxt, 27309 "re-allocating namespace bindings for SAX validation", 27310 NULL); 27311 goto internal_error; 27312 } 27313 } 27314 27315 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j]; 27316 if (namespaces[j+1][0] == 0) { 27317 /* 27318 * Handle xmlns="". 27319 */ 27320 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL; 27321 } else 27322 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = 27323 namespaces[j+1]; 27324 ielem->nbNsBindings++; 27325 } 27326 } 27327 /* 27328 * Register attributes. 27329 * SAX VAL TODO: We are not adding namespace declaration 27330 * attributes yet. 27331 */ 27332 if (nb_attributes != 0) { 27333 xmlChar *value; 27334 27335 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { 27336 /* 27337 * Duplicate the value. 27338 */ 27339 value = xmlStrndup(attributes[j+3], 27340 attributes[j+4] - attributes[j+3]); 27341 /* 27342 * TODO: Set the node line. 27343 */ 27344 ret = xmlSchemaValidatorPushAttribute(vctxt, 27345 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0, 27346 value, 1); 27347 if (ret == -1) { 27348 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27349 "calling xmlSchemaValidatorPushAttribute()"); 27350 goto internal_error; 27351 } 27352 } 27353 } 27354 /* 27355 * Validate the element. 27356 */ 27357 ret = xmlSchemaValidateElem(vctxt); 27358 if (ret != 0) { 27359 if (ret == -1) { 27360 VERROR_INT("xmlSchemaSAXHandleStartElementNs", 27361 "calling xmlSchemaValidateElem()"); 27362 goto internal_error; 27363 } 27364 goto exit; 27365 } 27366 27367 exit: 27368 return; 27369 internal_error: 27370 vctxt->err = -1; 27371 xmlStopParser(vctxt->parserCtxt); 27372 return; 27373 } 27374 27375 static void 27376 xmlSchemaSAXHandleEndElementNs(void *ctx, 27377 const xmlChar * localname ATTRIBUTE_UNUSED, 27378 const xmlChar * prefix ATTRIBUTE_UNUSED, 27379 const xmlChar * URI ATTRIBUTE_UNUSED) 27380 { 27381 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx; 27382 int res; 27383 27384 /* 27385 * Skip elements if inside a "skip" wildcard or if invalid. 27386 */ 27387 if (vctxt->skipDepth != -1) { 27388 if (vctxt->depth > vctxt->skipDepth) { 27389 vctxt->depth--; 27390 return; 27391 } else 27392 vctxt->skipDepth = -1; 27393 } 27394 /* 27395 * SAX VAL TODO: Just a temporary check. 27396 */ 27397 if ((!xmlStrEqual(vctxt->inode->localName, localname)) || 27398 (!xmlStrEqual(vctxt->inode->nsName, URI))) { 27399 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27400 "elem pop mismatch"); 27401 } 27402 res = xmlSchemaValidatorPopElem(vctxt); 27403 if (res != 0) { 27404 if (res < 0) { 27405 VERROR_INT("xmlSchemaSAXHandleEndElementNs", 27406 "calling xmlSchemaValidatorPopElem()"); 27407 goto internal_error; 27408 } 27409 goto exit; 27410 } 27411 exit: 27412 return; 27413 internal_error: 27414 vctxt->err = -1; 27415 xmlStopParser(vctxt->parserCtxt); 27416 return; 27417 } 27418 27419 /************************************************************************ 27420 * * 27421 * Validation interfaces * 27422 * * 27423 ************************************************************************/ 27424 27433 xmlSchemaValidCtxtPtr 27434 xmlSchemaNewValidCtxt(xmlSchemaPtr schema) 27435 { 27436 xmlSchemaValidCtxtPtr ret; 27437 27438 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt)); 27439 if (ret == NULL) { 27440 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL); 27441 return (NULL); 27442 } 27443 memset(ret, 0, sizeof(xmlSchemaValidCtxt)); 27444 ret->type = XML_SCHEMA_CTXT_VALIDATOR; 27445 ret->dict = xmlDictCreate(); 27446 ret->nodeQNames = xmlSchemaItemListCreate(); 27447 ret->schema = schema; 27448 return (ret); 27449 } 27450 27458 static void 27459 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) 27460 { 27461 if (vctxt == NULL) 27462 return; 27463 27464 /* 27465 * TODO: Should we clear the flags? 27466 * Might be problematic if one reuses the context 27467 * and assumes that the options remain the same. 27468 */ 27469 vctxt->flags = 0; 27470 vctxt->validationRoot = NULL; 27471 vctxt->doc = NULL; 27472 #ifdef LIBXML_READER_ENABLED 27473 vctxt->reader = NULL; 27474 #endif 27475 vctxt->hasKeyrefs = 0; 27476 27477 if (vctxt->value != NULL) { 27478 xmlSchemaFreeValue(vctxt->value); 27479 vctxt->value = NULL; 27480 } 27481 /* 27482 * Augmented IDC information. 27483 */ 27484 if (vctxt->aidcs != NULL) { 27485 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next; 27486 do { 27487 next = cur->next; 27488 xmlFree(cur); 27489 cur = next; 27490 } while (cur != NULL); 27491 vctxt->aidcs = NULL; 27492 } 27493 if (vctxt->idcMatcherCache != NULL) { 27494 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp; 27495 27496 while (matcher) { 27497 tmp = matcher; 27498 matcher = matcher->nextCached; 27499 xmlSchemaIDCFreeMatcherList(tmp); 27500 } 27501 vctxt->idcMatcherCache = NULL; 27502 } 27503 27504 27505 if (vctxt->idcNodes != NULL) { 27506 int i; 27507 xmlSchemaPSVIIDCNodePtr item; 27508 27509 for (i = 0; i < vctxt->nbIdcNodes; i++) { 27510 item = vctxt->idcNodes[i]; 27511 xmlFree(item->keys); 27512 xmlFree(item); 27513 } 27514 xmlFree(vctxt->idcNodes); 27515 vctxt->idcNodes = NULL; 27516 vctxt->nbIdcNodes = 0; 27517 vctxt->sizeIdcNodes = 0; 27518 } 27519 /* 27520 * Note that we won't delete the XPath state pool here. 27521 */ 27522 if (vctxt->xpathStates != NULL) { 27523 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates); 27524 vctxt->xpathStates = NULL; 27525 } 27526 /* 27527 * Attribute info. 27528 */ 27529 if (vctxt->nbAttrInfos != 0) { 27530 xmlSchemaClearAttrInfos(vctxt); 27531 } 27532 /* 27533 * Element info. 27534 */ 27535 if (vctxt->elemInfos != NULL) { 27536 int i; 27537 xmlSchemaNodeInfoPtr ei; 27538 27539 for (i = 0; i < vctxt->sizeElemInfos; i++) { 27540 ei = vctxt->elemInfos[i]; 27541 if (ei == NULL) 27542 break; 27543 xmlSchemaClearElemInfo(vctxt, ei); 27544 } 27545 } 27546 xmlSchemaItemListClear(vctxt->nodeQNames); 27547 /* Recreate the dict. */ 27548 xmlDictFree(vctxt->dict); 27549 /* 27550 * TODO: Is is save to recreate it? Do we have a scenario 27551 * where the user provides the dict? 27552 */ 27553 vctxt->dict = xmlDictCreate(); 27554 } 27555 27562 void 27563 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) 27564 { 27565 if (ctxt == NULL) 27566 return; 27567 if (ctxt->value != NULL) 27568 xmlSchemaFreeValue(ctxt->value); 27569 if (ctxt->pctxt != NULL) 27570 xmlSchemaFreeParserCtxt(ctxt->pctxt); 27571 if (ctxt->idcNodes != NULL) { 27572 int i; 27573 xmlSchemaPSVIIDCNodePtr item; 27574 27575 for (i = 0; i < ctxt->nbIdcNodes; i++) { 27576 item = ctxt->idcNodes[i]; 27577 xmlFree(item->keys); 27578 xmlFree(item); 27579 } 27580 xmlFree(ctxt->idcNodes); 27581 } 27582 if (ctxt->idcKeys != NULL) { 27583 int i; 27584 for (i = 0; i < ctxt->nbIdcKeys; i++) 27585 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]); 27586 xmlFree(ctxt->idcKeys); 27587 } 27588 27589 if (ctxt->xpathStates != NULL) { 27590 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates); 27591 ctxt->xpathStates = NULL; 27592 } 27593 if (ctxt->xpathStatePool != NULL) { 27594 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool); 27595 ctxt->xpathStatePool = NULL; 27596 } 27597 27598 /* 27599 * Augmented IDC information. 27600 */ 27601 if (ctxt->aidcs != NULL) { 27602 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next; 27603 do { 27604 next = cur->next; 27605 xmlFree(cur); 27606 cur = next; 27607 } while (cur != NULL); 27608 } 27609 if (ctxt->attrInfos != NULL) { 27610 int i; 27611 xmlSchemaAttrInfoPtr attr; 27612 27613 /* Just a paranoid call to the cleanup. */ 27614 if (ctxt->nbAttrInfos != 0) 27615 xmlSchemaClearAttrInfos(ctxt); 27616 for (i = 0; i < ctxt->sizeAttrInfos; i++) { 27617 attr = ctxt->attrInfos[i]; 27618 xmlFree(attr); 27619 } 27620 xmlFree(ctxt->attrInfos); 27621 } 27622 if (ctxt->elemInfos != NULL) { 27623 int i; 27624 xmlSchemaNodeInfoPtr ei; 27625 27626 for (i = 0; i < ctxt->sizeElemInfos; i++) { 27627 ei = ctxt->elemInfos[i]; 27628 if (ei == NULL) 27629 break; 27630 xmlSchemaClearElemInfo(ctxt, ei); 27631 xmlFree(ei); 27632 } 27633 xmlFree(ctxt->elemInfos); 27634 } 27635 if (ctxt->nodeQNames != NULL) 27636 xmlSchemaItemListFree(ctxt->nodeQNames); 27637 if (ctxt->dict != NULL) 27638 xmlDictFree(ctxt->dict); 27639 xmlFree(ctxt); 27640 } 27641 27651 int 27652 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt) 27653 { 27654 if (ctxt == NULL) 27655 return(-1); 27656 return(ctxt->err == 0); 27657 } 27658 27668 void 27669 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27670 xmlSchemaValidityErrorFunc err, 27671 xmlSchemaValidityWarningFunc warn, void *ctx) 27672 { 27673 if (ctxt == NULL) 27674 return; 27675 ctxt->error = err; 27676 ctxt->warning = warn; 27677 ctxt->errCtxt = ctx; 27678 if (ctxt->pctxt != NULL) 27679 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx); 27680 } 27681 27690 void 27691 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, 27692 xmlStructuredErrorFunc serror, void *ctx) 27693 { 27694 if (ctxt == NULL) 27695 return; 27696 ctxt->serror = serror; 27697 ctxt->error = NULL; 27698 ctxt->warning = NULL; 27699 ctxt->errCtxt = ctx; 27700 if (ctxt->pctxt != NULL) 27701 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx); 27702 } 27703 27715 int 27716 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt, 27717 xmlSchemaValidityErrorFunc * err, 27718 xmlSchemaValidityWarningFunc * warn, void **ctx) 27719 { 27720 if (ctxt == NULL) 27721 return (-1); 27722 if (err != NULL) 27723 *err = ctxt->error; 27724 if (warn != NULL) 27725 *warn = ctxt->warning; 27726 if (ctx != NULL) 27727 *ctx = ctxt->errCtxt; 27728 return (0); 27729 } 27730 27731 27742 int 27743 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt, 27744 int options) 27745 27746 { 27747 int i; 27748 27749 if (ctxt == NULL) 27750 return (-1); 27751 /* 27752 * WARNING: Change the start value if adding to the 27753 * xmlSchemaValidOption. 27754 * TODO: Is there an other, more easy to maintain, 27755 * way? 27756 */ 27757 for (i = 1; i < (int) sizeof(int) * 8; i++) { 27758 if (options & 1<<i) 27759 return (-1); 27760 } 27761 ctxt->options = options; 27762 return (0); 27763 } 27764 27773 int 27774 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt) 27775 27776 { 27777 if (ctxt == NULL) 27778 return (-1); 27779 else 27780 return (ctxt->options); 27781 } 27782 27783 static int 27784 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt) 27785 { 27786 xmlAttrPtr attr; 27787 int ret = 0; 27788 xmlSchemaNodeInfoPtr ielem = NULL; 27789 xmlNodePtr node, valRoot; 27790 const xmlChar *nsName; 27791 27792 /* DOC VAL TODO: Move this to the start function. */ 27793 valRoot = xmlDocGetRootElement(vctxt->doc); 27794 if (valRoot == NULL) { 27795 /* VAL TODO: Error code? */ 27796 VERROR(1, NULL, "The document has no document element"); 27797 return (1); 27798 } 27799 vctxt->depth = -1; 27800 vctxt->validationRoot = valRoot; 27801 node = valRoot; 27802 while (node != NULL) { 27803 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth)) 27804 goto next_sibling; 27805 if (node->type == XML_ELEMENT_NODE) { 27806 27807 /* 27808 * Init the node-info. 27809 */ 27810 vctxt->depth++; 27811 if (xmlSchemaValidatorPushElem(vctxt) == -1) 27812 goto internal_error; 27813 ielem = vctxt->inode; 27814 ielem->node = node; 27815 ielem->nodeLine = node->line; 27816 ielem->localName = node->name; 27817 if (node->ns != NULL) 27818 ielem->nsName = node->ns->href; 27819 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY; 27820 /* 27821 * Register attributes. 27822 * DOC VAL TODO: We do not register namespace declaration 27823 * attributes yet. 27824 */ 27825 vctxt->nbAttrInfos = 0; 27826 if (node->properties != NULL) { 27827 attr = node->properties; 27828 do { 27829 if (attr->ns != NULL) 27830 nsName = attr->ns->href; 27831 else 27832 nsName = NULL; 27833 ret = xmlSchemaValidatorPushAttribute(vctxt, 27834 (xmlNodePtr) attr, 27835 /* 27836 * Note that we give it the line number of the 27837 * parent element. 27838 */ 27839 ielem->nodeLine, 27840 attr->name, nsName, 0, 27841 xmlNodeListGetString(attr->doc, attr->children, 1), 1); 27842 if (ret == -1) { 27843 VERROR_INT("xmlSchemaDocWalk", 27844 "calling xmlSchemaValidatorPushAttribute()"); 27845 goto internal_error; 27846 } 27847 attr = attr->next; 27848 } while (attr); 27849 } 27850 /* 27851 * Validate the element. 27852 */ 27853 ret = xmlSchemaValidateElem(vctxt); 27854 if (ret != 0) { 27855 if (ret == -1) { 27856 VERROR_INT("xmlSchemaDocWalk", 27857 "calling xmlSchemaValidateElem()"); 27858 goto internal_error; 27859 } 27860 /* 27861 * Don't stop validation; just skip the content 27862 * of this element. 27863 */ 27864 goto leave_node; 27865 } 27866 if ((vctxt->skipDepth != -1) && 27867 (vctxt->depth >= vctxt->skipDepth)) 27868 goto leave_node; 27869 } else if ((node->type == XML_TEXT_NODE) || 27870 (node->type == XML_CDATA_SECTION_NODE)) { 27871 /* 27872 * Process character content. 27873 */ 27874 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)) 27875 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY; 27876 ret = xmlSchemaVPushText(vctxt, node->type, node->content, 27877 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL); 27878 if (ret < 0) { 27879 VERROR_INT("xmlSchemaVDocWalk", 27880 "calling xmlSchemaVPushText()"); 27881 goto internal_error; 27882 } 27883 /* 27884 * DOC VAL TODO: Should we skip further validation of the 27885 * element content here? 27886 */ 27887 } else if ((node->type == XML_ENTITY_NODE) || 27888 (node->type == XML_ENTITY_REF_NODE)) { 27889 /* 27890 * DOC VAL TODO: What to do with entities? 27891 */ 27892 VERROR_INT("xmlSchemaVDocWalk", 27893 "there is at least one entity reference in the node-tree " 27894 "currently being validated. Processing of entities with " 27895 "this XML Schema processor is not supported (yet). Please " 27896 "substitute entities before validation."); 27897 goto internal_error; 27898 } else { 27899 goto leave_node; 27900 /* 27901 * DOC VAL TODO: XInclude nodes, etc. 27902 */ 27903 } 27904 /* 27905 * Walk the doc. 27906 */ 27907 if (node->children != NULL) { 27908 node = node->children; 27909 continue; 27910 } 27911 leave_node: 27912 if (node->type == XML_ELEMENT_NODE) { 27913 /* 27914 * Leaving the scope of an element. 27915 */ 27916 if (node != vctxt->inode->node) { 27917 VERROR_INT("xmlSchemaVDocWalk", 27918 "element position mismatch"); 27919 goto internal_error; 27920 } 27921 ret = xmlSchemaValidatorPopElem(vctxt); 27922 if (ret != 0) { 27923 if (ret < 0) { 27924 VERROR_INT("xmlSchemaVDocWalk", 27925 "calling xmlSchemaValidatorPopElem()"); 27926 goto internal_error; 27927 } 27928 } 27929 if (node == valRoot) 27930 goto exit; 27931 } 27932 next_sibling: 27933 if (node->next != NULL) 27934 node = node->next; 27935 else { 27936 node = node->parent; 27937 goto leave_node; 27938 } 27939 } 27940 27941 exit: 27942 return (ret); 27943 internal_error: 27944 return (-1); 27945 } 27946 27947 static int 27948 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { 27949 /* 27950 * Some initialization. 27951 */ 27952 vctxt->err = 0; 27953 vctxt->nberrors = 0; 27954 vctxt->depth = -1; 27955 vctxt->skipDepth = -1; 27956 vctxt->xsiAssemble = 0; 27957 vctxt->hasKeyrefs = 0; 27958 #ifdef ENABLE_IDC_NODE_TABLES_TEST 27959 vctxt->createIDCNodeTables = 1; 27960 #else 27961 vctxt->createIDCNodeTables = 0; 27962 #endif 27963 /* 27964 * Create a schema + parser if necessary. 27965 */ 27966 if (vctxt->schema == NULL) { 27967 xmlSchemaParserCtxtPtr pctxt; 27968 27969 vctxt->xsiAssemble = 1; 27970 /* 27971 * If not schema was given then we will create a schema 27972 * dynamically using XSI schema locations. 27973 * 27974 * Create the schema parser context. 27975 */ 27976 if ((vctxt->pctxt == NULL) && 27977 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1)) 27978 return (-1); 27979 pctxt = vctxt->pctxt; 27980 pctxt->xsiAssemble = 1; 27981 /* 27982 * Create the schema. 27983 */ 27984 vctxt->schema = xmlSchemaNewSchema(pctxt); 27985 if (vctxt->schema == NULL) 27986 return (-1); 27987 /* 27988 * Create the schema construction context. 27989 */ 27990 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict); 27991 if (pctxt->constructor == NULL) 27992 return(-1); 27993 pctxt->constructor->mainSchema = vctxt->schema; 27994 /* 27995 * Take ownership of the constructor to be able to free it. 27996 */ 27997 pctxt->ownsConstructor = 1; 27998 } 27999 /* 28000 * Augment the IDC definitions for the main schema and all imported ones 28001 * NOTE: main schema if the first in the imported list 28002 */ 28003 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); 28004 28005 return(0); 28006 } 28007 28008 static void 28009 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) { 28010 if (vctxt->xsiAssemble) { 28011 if (vctxt->schema != NULL) { 28012 xmlSchemaFree(vctxt->schema); 28013 vctxt->schema = NULL; 28014 } 28015 } 28016 xmlSchemaClearValidCtxt(vctxt); 28017 } 28018 28019 static int 28020 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt) 28021 { 28022 int ret = 0; 28023 28024 if (xmlSchemaPreRun(vctxt) < 0) 28025 return(-1); 28026 28027 if (vctxt->doc != NULL) { 28028 /* 28029 * Tree validation. 28030 */ 28031 ret = xmlSchemaVDocWalk(vctxt); 28032 #ifdef LIBXML_READER_ENABLED 28033 } else if (vctxt->reader != NULL) { 28034 /* 28035 * XML Reader validation. 28036 */ 28037 #ifdef XML_SCHEMA_READER_ENABLED 28038 ret = xmlSchemaVReaderWalk(vctxt); 28039 #endif 28040 #endif 28041 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) { 28042 /* 28043 * SAX validation. 28044 */ 28045 ret = xmlParseDocument(vctxt->parserCtxt); 28046 } else { 28047 VERROR_INT("xmlSchemaVStart", 28048 "no instance to validate"); 28049 ret = -1; 28050 } 28051 28052 xmlSchemaPostRun(vctxt); 28053 if (ret == 0) 28054 ret = vctxt->err; 28055 return (ret); 28056 } 28057 28068 int 28069 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) 28070 { 28071 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE)) 28072 return (-1); 28073 28074 if (ctxt->schema == NULL) 28075 return (-1); 28076 28077 ctxt->doc = elem->doc; 28078 ctxt->node = elem; 28079 ctxt->validationRoot = elem; 28080 return(xmlSchemaVStart(ctxt)); 28081 } 28082 28093 int 28094 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) 28095 { 28096 if ((ctxt == NULL) || (doc == NULL)) 28097 return (-1); 28098 28099 ctxt->doc = doc; 28100 ctxt->node = xmlDocGetRootElement(doc); 28101 if (ctxt->node == NULL) { 28102 xmlSchemaCustomErr(ACTXT_CAST ctxt, 28103 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, 28104 (xmlNodePtr) doc, NULL, 28105 "The document has no document element", NULL, NULL); 28106 return (ctxt->err); 28107 } 28108 ctxt->validationRoot = ctxt->node; 28109 return (xmlSchemaVStart(ctxt)); 28110 } 28111 28112 28113 /************************************************************************ 28114 * * 28115 * Function and data for SAX streaming API * 28116 * * 28117 ************************************************************************/ 28118 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData; 28119 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr; 28120 28121 struct _xmlSchemaSplitSAXData { 28122 xmlSAXHandlerPtr user_sax; 28123 void *user_data; 28124 xmlSchemaValidCtxtPtr ctxt; 28125 xmlSAXHandlerPtr schemas_sax; 28126 }; 28127 28128 #define XML_SAX_PLUG_MAGIC 0xdc43ba21 28129 28130 struct _xmlSchemaSAXPlug { 28131 unsigned int magic; 28132 28133 /* the original callbacks informations */ 28134 xmlSAXHandlerPtr *user_sax_ptr; 28135 xmlSAXHandlerPtr user_sax; 28136 void **user_data_ptr; 28137 void *user_data; 28138 28139 /* the block plugged back and validation informations */ 28140 xmlSAXHandler schemas_sax; 28141 xmlSchemaValidCtxtPtr ctxt; 28142 }; 28143 28144 /* All those functions just bounces to the user provided SAX handlers */ 28145 static void 28146 internalSubsetSplit(void *ctx, const xmlChar *name, 28147 const xmlChar *ExternalID, const xmlChar *SystemID) 28148 { 28149 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28150 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28151 (ctxt->user_sax->internalSubset != NULL)) 28152 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID, 28153 SystemID); 28154 } 28155 28156 static int 28157 isStandaloneSplit(void *ctx) 28158 { 28159 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28160 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28161 (ctxt->user_sax->isStandalone != NULL)) 28162 return(ctxt->user_sax->isStandalone(ctxt->user_data)); 28163 return(0); 28164 } 28165 28166 static int 28167 hasInternalSubsetSplit(void *ctx) 28168 { 28169 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28170 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28171 (ctxt->user_sax->hasInternalSubset != NULL)) 28172 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data)); 28173 return(0); 28174 } 28175 28176 static int 28177 hasExternalSubsetSplit(void *ctx) 28178 { 28179 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28180 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28181 (ctxt->user_sax->hasExternalSubset != NULL)) 28182 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data)); 28183 return(0); 28184 } 28185 28186 static void 28187 externalSubsetSplit(void *ctx, const xmlChar *name, 28188 const xmlChar *ExternalID, const xmlChar *SystemID) 28189 { 28190 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28191 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28192 (ctxt->user_sax->externalSubset != NULL)) 28193 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID, 28194 SystemID); 28195 } 28196 28197 static xmlParserInputPtr 28198 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId) 28199 { 28200 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28201 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28202 (ctxt->user_sax->resolveEntity != NULL)) 28203 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId, 28204 systemId)); 28205 return(NULL); 28206 } 28207 28208 static xmlEntityPtr 28209 getEntitySplit(void *ctx, const xmlChar *name) 28210 { 28211 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28212 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28213 (ctxt->user_sax->getEntity != NULL)) 28214 return(ctxt->user_sax->getEntity(ctxt->user_data, name)); 28215 return(NULL); 28216 } 28217 28218 static xmlEntityPtr 28219 getParameterEntitySplit(void *ctx, const xmlChar *name) 28220 { 28221 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28222 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28223 (ctxt->user_sax->getParameterEntity != NULL)) 28224 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name)); 28225 return(NULL); 28226 } 28227 28228 28229 static void 28230 entityDeclSplit(void *ctx, const xmlChar *name, int type, 28231 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) 28232 { 28233 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28234 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28235 (ctxt->user_sax->entityDecl != NULL)) 28236 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId, 28237 systemId, content); 28238 } 28239 28240 static void 28241 attributeDeclSplit(void *ctx, const xmlChar * elem, 28242 const xmlChar * name, int type, int def, 28243 const xmlChar * defaultValue, xmlEnumerationPtr tree) 28244 { 28245 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28246 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28247 (ctxt->user_sax->attributeDecl != NULL)) { 28248 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type, 28249 def, defaultValue, tree); 28250 } else { 28251 xmlFreeEnumeration(tree); 28252 } 28253 } 28254 28255 static void 28256 elementDeclSplit(void *ctx, const xmlChar *name, int type, 28257 xmlElementContentPtr content) 28258 { 28259 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28260 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28261 (ctxt->user_sax->elementDecl != NULL)) 28262 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content); 28263 } 28264 28265 static void 28266 notationDeclSplit(void *ctx, const xmlChar *name, 28267 const xmlChar *publicId, const xmlChar *systemId) 28268 { 28269 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28270 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28271 (ctxt->user_sax->notationDecl != NULL)) 28272 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId, 28273 systemId); 28274 } 28275 28276 static void 28277 unparsedEntityDeclSplit(void *ctx, const xmlChar *name, 28278 const xmlChar *publicId, const xmlChar *systemId, 28279 const xmlChar *notationName) 28280 { 28281 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28282 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28283 (ctxt->user_sax->unparsedEntityDecl != NULL)) 28284 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId, 28285 systemId, notationName); 28286 } 28287 28288 static void 28289 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc) 28290 { 28291 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28292 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28293 (ctxt->user_sax->setDocumentLocator != NULL)) 28294 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc); 28295 } 28296 28297 static void 28298 startDocumentSplit(void *ctx) 28299 { 28300 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28301 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28302 (ctxt->user_sax->startDocument != NULL)) 28303 ctxt->user_sax->startDocument(ctxt->user_data); 28304 } 28305 28306 static void 28307 endDocumentSplit(void *ctx) 28308 { 28309 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28310 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28311 (ctxt->user_sax->endDocument != NULL)) 28312 ctxt->user_sax->endDocument(ctxt->user_data); 28313 } 28314 28315 static void 28316 processingInstructionSplit(void *ctx, const xmlChar *target, 28317 const xmlChar *data) 28318 { 28319 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28320 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28321 (ctxt->user_sax->processingInstruction != NULL)) 28322 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data); 28323 } 28324 28325 static void 28326 commentSplit(void *ctx, const xmlChar *value) 28327 { 28328 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28329 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28330 (ctxt->user_sax->comment != NULL)) 28331 ctxt->user_sax->comment(ctxt->user_data, value); 28332 } 28333 28334 /* 28335 * Varargs error callbacks to the user application, harder ... 28336 */ 28337 28338 static void XMLCDECL 28339 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28340 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28341 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28342 (ctxt->user_sax->warning != NULL)) { 28343 TODO 28344 } 28345 } 28346 static void XMLCDECL 28347 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28348 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28349 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28350 (ctxt->user_sax->error != NULL)) { 28351 TODO 28352 } 28353 } 28354 static void XMLCDECL 28355 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) { 28356 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28357 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28358 (ctxt->user_sax->fatalError != NULL)) { 28359 TODO 28360 } 28361 } 28362 28363 /* 28364 * Those are function where both the user handler and the schemas handler 28365 * need to be called. 28366 */ 28367 static void 28368 charactersSplit(void *ctx, const xmlChar *ch, int len) 28369 { 28370 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28371 if (ctxt == NULL) 28372 return; 28373 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL)) 28374 ctxt->user_sax->characters(ctxt->user_data, ch, len); 28375 if (ctxt->ctxt != NULL) 28376 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28377 } 28378 28379 static void 28380 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len) 28381 { 28382 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28383 if (ctxt == NULL) 28384 return; 28385 if ((ctxt->user_sax != NULL) && 28386 (ctxt->user_sax->ignorableWhitespace != NULL)) 28387 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len); 28388 if (ctxt->ctxt != NULL) 28389 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len); 28390 } 28391 28392 static void 28393 cdataBlockSplit(void *ctx, const xmlChar *value, int len) 28394 { 28395 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28396 if (ctxt == NULL) 28397 return; 28398 if ((ctxt->user_sax != NULL) && 28399 (ctxt->user_sax->cdataBlock != NULL)) 28400 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len); 28401 if (ctxt->ctxt != NULL) 28402 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len); 28403 } 28404 28405 static void 28406 referenceSplit(void *ctx, const xmlChar *name) 28407 { 28408 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28409 if (ctxt == NULL) 28410 return; 28411 if ((ctxt != NULL) && (ctxt->user_sax != NULL) && 28412 (ctxt->user_sax->reference != NULL)) 28413 ctxt->user_sax->reference(ctxt->user_data, name); 28414 if (ctxt->ctxt != NULL) 28415 xmlSchemaSAXHandleReference(ctxt->user_data, name); 28416 } 28417 28418 static void 28419 startElementNsSplit(void *ctx, const xmlChar * localname, 28420 const xmlChar * prefix, const xmlChar * URI, 28421 int nb_namespaces, const xmlChar ** namespaces, 28422 int nb_attributes, int nb_defaulted, 28423 const xmlChar ** attributes) { 28424 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28425 if (ctxt == NULL) 28426 return; 28427 if ((ctxt->user_sax != NULL) && 28428 (ctxt->user_sax->startElementNs != NULL)) 28429 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix, 28430 URI, nb_namespaces, namespaces, 28431 nb_attributes, nb_defaulted, 28432 attributes); 28433 if (ctxt->ctxt != NULL) 28434 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix, 28435 URI, nb_namespaces, namespaces, 28436 nb_attributes, nb_defaulted, 28437 attributes); 28438 } 28439 28440 static void 28441 endElementNsSplit(void *ctx, const xmlChar * localname, 28442 const xmlChar * prefix, const xmlChar * URI) { 28443 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx; 28444 if (ctxt == NULL) 28445 return; 28446 if ((ctxt->user_sax != NULL) && 28447 (ctxt->user_sax->endElementNs != NULL)) 28448 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI); 28449 if (ctxt->ctxt != NULL) 28450 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI); 28451 } 28452 28466 xmlSchemaSAXPlugPtr 28467 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt, 28468 xmlSAXHandlerPtr *sax, void **user_data) 28469 { 28470 xmlSchemaSAXPlugPtr ret; 28471 xmlSAXHandlerPtr old_sax; 28472 28473 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL)) 28474 return(NULL); 28475 28476 /* 28477 * We only allow to plug into SAX2 event streams 28478 */ 28479 old_sax = *sax; 28480 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC)) 28481 return(NULL); 28482 if ((old_sax != NULL) && 28483 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) && 28484 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL))) 28485 return(NULL); 28486 28487 /* 28488 * everything seems right allocate the local data needed for that layer 28489 */ 28490 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct)); 28491 if (ret == NULL) { 28492 return(NULL); 28493 } 28494 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct)); 28495 ret->magic = XML_SAX_PLUG_MAGIC; 28496 ret->schemas_sax.initialized = XML_SAX2_MAGIC; 28497 ret->ctxt = ctxt; 28498 ret->user_sax_ptr = sax; 28499 ret->user_sax = old_sax; 28500 if (old_sax == NULL) { 28501 /* 28502 * go direct, no need for the split block and functions. 28503 */ 28504 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs; 28505 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs; 28506 /* 28507 * Note that we use the same text-function for both, to prevent 28508 * the parser from testing for ignorable whitespace. 28509 */ 28510 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText; 28511 ret->schemas_sax.characters = xmlSchemaSAXHandleText; 28512 28513 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection; 28514 ret->schemas_sax.reference = xmlSchemaSAXHandleReference; 28515 28516 ret->user_data = ctxt; 28517 *user_data = ctxt; 28518 } else { 28519 /* 28520 * for each callback unused by Schemas initialize it to the Split 28521 * routine only if non NULL in the user block, this can speed up 28522 * things at the SAX level. 28523 */ 28524 if (old_sax->internalSubset != NULL) 28525 ret->schemas_sax.internalSubset = internalSubsetSplit; 28526 if (old_sax->isStandalone != NULL) 28527 ret->schemas_sax.isStandalone = isStandaloneSplit; 28528 if (old_sax->hasInternalSubset != NULL) 28529 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit; 28530 if (old_sax->hasExternalSubset != NULL) 28531 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit; 28532 if (old_sax->resolveEntity != NULL) 28533 ret->schemas_sax.resolveEntity = resolveEntitySplit; 28534 if (old_sax->getEntity != NULL) 28535 ret->schemas_sax.getEntity = getEntitySplit; 28536 if (old_sax->entityDecl != NULL) 28537 ret->schemas_sax.entityDecl = entityDeclSplit; 28538 if (old_sax->notationDecl != NULL) 28539 ret->schemas_sax.notationDecl = notationDeclSplit; 28540 if (old_sax->attributeDecl != NULL) 28541 ret->schemas_sax.attributeDecl = attributeDeclSplit; 28542 if (old_sax->elementDecl != NULL) 28543 ret->schemas_sax.elementDecl = elementDeclSplit; 28544 if (old_sax->unparsedEntityDecl != NULL) 28545 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit; 28546 if (old_sax->setDocumentLocator != NULL) 28547 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit; 28548 if (old_sax->startDocument != NULL) 28549 ret->schemas_sax.startDocument = startDocumentSplit; 28550 if (old_sax->endDocument != NULL) 28551 ret->schemas_sax.endDocument = endDocumentSplit; 28552 if (old_sax->processingInstruction != NULL) 28553 ret->schemas_sax.processingInstruction = processingInstructionSplit; 28554 if (old_sax->comment != NULL) 28555 ret->schemas_sax.comment = commentSplit; 28556 if (old_sax->warning != NULL) 28557 ret->schemas_sax.warning = warningSplit; 28558 if (old_sax->error != NULL) 28559 ret->schemas_sax.error = errorSplit; 28560 if (old_sax->fatalError != NULL) 28561 ret->schemas_sax.fatalError = fatalErrorSplit; 28562 if (old_sax->getParameterEntity != NULL) 28563 ret->schemas_sax.getParameterEntity = getParameterEntitySplit; 28564 if (old_sax->externalSubset != NULL) 28565 ret->schemas_sax.externalSubset = externalSubsetSplit; 28566 28567 /* 28568 * the 6 schemas callback have to go to the splitter functions 28569 * Note that we use the same text-function for ignorableWhitespace 28570 * if possible, to prevent the parser from testing for ignorable 28571 * whitespace. 28572 */ 28573 ret->schemas_sax.characters = charactersSplit; 28574 if ((old_sax->ignorableWhitespace != NULL) && 28575 (old_sax->ignorableWhitespace != old_sax->characters)) 28576 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit; 28577 else 28578 ret->schemas_sax.ignorableWhitespace = charactersSplit; 28579 ret->schemas_sax.cdataBlock = cdataBlockSplit; 28580 ret->schemas_sax.reference = referenceSplit; 28581 ret->schemas_sax.startElementNs = startElementNsSplit; 28582 ret->schemas_sax.endElementNs = endElementNsSplit; 28583 28584 ret->user_data_ptr = user_data; 28585 ret->user_data = *user_data; 28586 *user_data = ret; 28587 } 28588 28589 /* 28590 * plug the pointers back. 28591 */ 28592 *sax = &(ret->schemas_sax); 28593 ctxt->sax = *sax; 28594 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28595 xmlSchemaPreRun(ctxt); 28596 return(ret); 28597 } 28598 28608 int 28609 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug) 28610 { 28611 xmlSAXHandlerPtr *sax; 28612 void **user_data; 28613 28614 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC)) 28615 return(-1); 28616 plug->magic = 0; 28617 28618 xmlSchemaPostRun(plug->ctxt); 28619 /* restore the data */ 28620 sax = plug->user_sax_ptr; 28621 *sax = plug->user_sax; 28622 if (plug->user_sax != NULL) { 28623 user_data = plug->user_data_ptr; 28624 *user_data = plug->user_data; 28625 } 28626 28627 /* free and return */ 28628 xmlFree(plug); 28629 return(0); 28630 } 28631 28647 int 28648 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, 28649 xmlParserInputBufferPtr input, xmlCharEncoding enc, 28650 xmlSAXHandlerPtr sax, void *user_data) 28651 { 28652 xmlSchemaSAXPlugPtr plug = NULL; 28653 xmlSAXHandlerPtr old_sax = NULL; 28654 xmlParserCtxtPtr pctxt = NULL; 28655 xmlParserInputPtr inputStream = NULL; 28656 int ret; 28657 28658 if ((ctxt == NULL) || (input == NULL)) 28659 return (-1); 28660 28661 /* 28662 * prepare the parser 28663 */ 28664 pctxt = xmlNewParserCtxt(); 28665 if (pctxt == NULL) 28666 return (-1); 28667 old_sax = pctxt->sax; 28668 pctxt->sax = sax; 28669 pctxt->userData = user_data; 28670 #if 0 28671 if (options) 28672 xmlCtxtUseOptions(pctxt, options); 28673 #endif 28674 pctxt->linenumbers = 1; 28675 28676 inputStream = xmlNewIOInputStream(pctxt, input, enc);; 28677 if (inputStream == NULL) { 28678 ret = -1; 28679 goto done; 28680 } 28681 inputPush(pctxt, inputStream); 28682 ctxt->parserCtxt = pctxt; 28683 ctxt->input = input; 28684 28685 /* 28686 * Plug the validation and launch the parsing 28687 */ 28688 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData)); 28689 if (plug == NULL) { 28690 ret = -1; 28691 goto done; 28692 } 28693 ctxt->input = input; 28694 ctxt->enc = enc; 28695 ctxt->sax = pctxt->sax; 28696 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM; 28697 ret = xmlSchemaVStart(ctxt); 28698 28699 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) { 28700 ret = ctxt->parserCtxt->errNo; 28701 if (ret == 0) 28702 ret = 1; 28703 } 28704 28705 done: 28706 ctxt->parserCtxt = NULL; 28707 ctxt->sax = NULL; 28708 ctxt->input = NULL; 28709 if (plug != NULL) { 28710 xmlSchemaSAXUnplug(plug); 28711 } 28712 /* cleanup */ 28713 if (pctxt != NULL) { 28714 pctxt->sax = old_sax; 28715 xmlFreeParserCtxt(pctxt); 28716 } 28717 return (ret); 28718 } 28719 28732 int 28733 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt, 28734 const char * filename, 28735 int options ATTRIBUTE_UNUSED) 28736 { 28737 int ret; 28738 xmlParserInputBufferPtr input; 28739 28740 if ((ctxt == NULL) || (filename == NULL)) 28741 return (-1); 28742 28743 input = xmlParserInputBufferCreateFilename(filename, 28744 XML_CHAR_ENCODING_NONE); 28745 if (input == NULL) 28746 return (-1); 28747 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE, 28748 NULL, NULL); 28749 return (ret); 28750 } 28751 28761 xmlParserCtxtPtr 28762 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt) 28763 { 28764 if (ctxt == NULL) 28765 return(NULL); 28766 return (ctxt->parserCtxt); 28767 } 28768 28769 #define bottom_xmlschemas 28770 #include "elfgcchack.h" 28771 #endif /* LIBXML_SCHEMAS_ENABLED */ Generated on Sat May 26 2012 04:33:52 for ReactOS by
1.7.6.1
|