1 /* 2 * schemas.c : implementation of the XML Schema handling and 3 * schema validity checking 4 * 5 * See Copyright for the status of this software. 6 * 7 * Daniel Veillard <veillard (at) redhat.com> 8 */ 9 10 /* 11 * TODO: 12 * - when types are redefined in includes, check that all 13 * types in the redef list are equal 14 * -> need a type equality operation. 15 * - if we don't intend to use the schema for schemas, we 16 * need to validate all schema attributes (ref, type, name) 17 * against their types. 18 * - Eliminate item creation for: ?? 19 * 20 * URGENT TODO: 21 * - For xsi-driven schema acquisition, augment the IDCs after every 22 * acquisition episode (xmlSchemaAugmentIDC). 23 * 24 * NOTES: 25 * - Elimated item creation for: <restriction>, <extension>, 26 * <simpleContent>, <complexContent>, <list>, <union> 27 * 28 * PROBLEMS: 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so 31 * XPath will have trouble to resolve to this namespace, since not known. 32 * 33 * 34 * CONSTRAINTS: 35 * 36 * Schema Component Constraint: 37 * All Group Limited (cos-all-limited) 38 * Status: complete 39 * (1.2) 40 * In xmlSchemaGroupDefReferenceTermFixup() and 41 * (2) 42 * In xmlSchemaParseModelGroup() 43 * TODO: Actually this should go to component-level checks, 44 * but is done here due to performance. Move it to an other layer 45 * is schema construction via an API is implemented. 46 */ 47 #define IN_LIBXML 48 #include "libxml.h" 49 50 #ifdef LIBXML_SCHEMAS_ENABLED 51 52 #include <string.h> 53 #include <libxml/xmlmemory.h> 54 #include <libxml/parser.h> 55 #include <libxml/parserInternals.h> 56 #include <libxml/hash.h> 57 #include <libxml/uri.h> 58 #include <libxml/xmlschemas.h> 59 #include <libxml/schemasInternals.h> 60 #include <libxml/xmlschemastypes.h> 61 #include <libxml/xmlautomata.h> 62 #include <libxml/xmlregexp.h> 63 #include <libxml/dict.h> 64 #include <libxml/encoding.h> 65 #include <libxml/xmlIO.h> 66 #ifdef LIBXML_PATTERN_ENABLED 67 #include <libxml/pattern.h> 68 #endif 69 #ifdef LIBXML_READER_ENABLED 70 #include <libxml/xmlreader.h> 71 #endif 72 73 /* #define DEBUG 1 */ 74 75 /* #define DEBUG_CONTENT 1 */ 76 77 /* #define DEBUG_TYPE 1 */ 78 79 /* #define DEBUG_CONTENT_REGEXP 1 */ 80 81 /* #define DEBUG_AUTOMATA 1 */ 82 83 /* #define DEBUG_IDC */ 84 85 /* #define DEBUG_IDC_NODE_TABLE */ 86 87 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 88 89 #ifdef DEBUG_IDC 90 #ifndef DEBUG_IDC_NODE_TABLE 91 #define DEBUG_IDC_NODE_TABLE 92 #endif 93 #endif 94 95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 96 97 #define ENABLE_REDEFINE 98 99 /* #define ENABLE_NAMED_LOCALS */ 100 101 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 102 103 #define DUMP_CONTENT_MODEL 104 105 #ifdef LIBXML_READER_ENABLED 106 /* #define XML_SCHEMA_READER_ENABLED */ 107 #endif 108 109 #define UNBOUNDED (1 << 30) 110 #define TODO \ 111 xmlGenericError(xmlGenericErrorContext, \ 112 "Unimplemented block at %s:%d\n", \ 113 __FILE__, __LINE__); 114 115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 116 117 /* 118 * The XML Schemas namespaces 119 */ 120 static const xmlChar *xmlSchemaNs = (const xmlChar *) 121 "http://www.w3.org/2001/XMLSchema"; 122 123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 124 "http://www.w3.org/2001/XMLSchema-instance"; 125 126 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 127 "http://www.w3.org/2000/xmlns/"; 128 129 /* 130 * Come casting macros. 131 */ 132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 137 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 138 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 139 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 146 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 148 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 149 150 /* 151 * Macros to query common properties of components. 152 */ 153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 154 155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 156 /* 157 * Macros for element declarations. 158 */ 159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 160 161 #define WXS_SUBST_HEAD(item) (item)->refDecl 162 /* 163 * Macros for attribute declarations. 164 */ 165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 166 /* 167 * Macros for attribute uses. 168 */ 169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl 170 171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 172 173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 174 175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 176 /* 177 * Macros for attribute groups. 178 */ 179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 181 /* 182 * Macros for particles. 183 */ 184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 185 186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 187 188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 189 190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 191 /* 192 * Macros for model groups definitions. 193 */ 194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 195 /* 196 * Macros for model groups. 197 */ 198 #define WXS_IS_MODEL_GROUP(i) \ 199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 201 ((i)->type == XML_SCHEMA_TYPE_ALL)) 202 203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 204 /* 205 * Macros for schema buckets. 206 */ 207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 209 210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 211 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 212 213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 214 215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 216 /* 217 * Macros for complex/simple types. 218 */ 219 #define WXS_IS_ANYTYPE(i) \ 220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 222 223 #define WXS_IS_COMPLEX(i) \ 224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 226 227 #define WXS_IS_SIMPLE(item) \ 228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 230 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 231 232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 235 236 #define WXS_IS_RESTRICTION(t) \ 237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 238 239 #define WXS_IS_EXTENSION(t) \ 240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 241 242 #define WXS_IS_TYPE_NOT_FIXED(i) \ 243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 245 246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 249 250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 251 252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 253 /* 254 * Macros for exclusively for complex types. 255 */ 256 #define WXS_HAS_COMPLEX_CONTENT(item) \ 257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 260 261 #define WXS_HAS_SIMPLE_CONTENT(item) \ 262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 263 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 264 265 #define WXS_HAS_MIXED_CONTENT(item) \ 266 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 267 268 #define WXS_EMPTIABLE(t) \ 269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 270 271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 272 273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 274 275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 276 /* 277 * Macros for exclusively for simple types. 278 */ 279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 280 281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 282 283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 284 285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 286 /* 287 * Misc parser context macros. 288 */ 289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 290 291 #define WXS_HAS_BUCKETS(ctx) \ 292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 294 295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 296 297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 298 299 #define WXS_SCHEMA(ctx) (ctx)->schema 300 301 #define WXS_ADD_LOCAL(ctx, item) \ 302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 303 304 #define WXS_ADD_GLOBAL(ctx, item) \ 305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 306 307 #define WXS_ADD_PENDING(ctx, item) \ 308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 309 /* 310 * xmlSchemaItemList macros. 311 */ 312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 313 /* 314 * Misc macros. 315 */ 316 #define IS_SCHEMA(node, type) \ 317 ((node != NULL) && (node->ns != NULL) && \ 318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 319 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 320 321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 322 323 /* 324 * Since we put the default/fixed values into the dict, we can 325 * use pointer comparison for those values. 326 * REMOVED: (xmlStrEqual((v1), (v2))) 327 */ 328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 329 330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 331 332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 333 334 #define HFAILURE if (res == -1) goto exit_failure; 335 336 #define HERROR if (res != 0) goto exit_error; 337 338 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 339 /* 340 * Some flags used for various schema constraints. 341 */ 342 #define SUBSET_RESTRICTION 1<<0 343 #define SUBSET_EXTENSION 1<<1 344 #define SUBSET_SUBSTITUTION 1<<2 345 #define SUBSET_LIST 1<<3 346 #define SUBSET_UNION 1<<4 347 348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 350 351 typedef struct _xmlSchemaItemList xmlSchemaItemList; 352 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 353 struct _xmlSchemaItemList { 354 void **items; /* used for dynamic addition of schemata */ 355 int nbItems; /* used for dynamic addition of schemata */ 356 int sizeItems; /* used for dynamic addition of schemata */ 357 }; 358 359 #define XML_SCHEMA_CTXT_PARSER 1 360 #define XML_SCHEMA_CTXT_VALIDATOR 2 361 362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 364 struct _xmlSchemaAbstractCtxt { 365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 366 }; 367 368 typedef struct _xmlSchemaBucket xmlSchemaBucket; 369 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 370 371 #define XML_SCHEMA_SCHEMA_MAIN 0 372 #define XML_SCHEMA_SCHEMA_IMPORT 1 373 #define XML_SCHEMA_SCHEMA_INCLUDE 2 374 #define XML_SCHEMA_SCHEMA_REDEFINE 3 375 376 /** 377 * xmlSchemaSchemaRelation: 378 * 379 * Used to create a graph of schema relationships. 380 */ 381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 383 struct _xmlSchemaSchemaRelation { 384 xmlSchemaSchemaRelationPtr next; 385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 386 const xmlChar *importNamespace; 387 xmlSchemaBucketPtr bucket; 388 }; 389 390 #define XML_SCHEMA_BUCKET_MARKED 1<<0 391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 392 393 struct _xmlSchemaBucket { 394 int type; 395 int flags; 396 const xmlChar *schemaLocation; 397 const xmlChar *origTargetNamespace; 398 const xmlChar *targetNamespace; 399 xmlDocPtr doc; 400 xmlSchemaSchemaRelationPtr relations; 401 int located; 402 int parsed; 403 int imported; 404 int preserveDoc; 405 xmlSchemaItemListPtr globals; /* Global components. */ 406 xmlSchemaItemListPtr locals; /* Local components. */ 407 }; 408 409 /** 410 * xmlSchemaImport: 411 * (extends xmlSchemaBucket) 412 * 413 * Reflects a schema. Holds some information 414 * about the schema and its toplevel components. Duplicate 415 * toplevel components are not checked at this level. 416 */ 417 typedef struct _xmlSchemaImport xmlSchemaImport; 418 typedef xmlSchemaImport *xmlSchemaImportPtr; 419 struct _xmlSchemaImport { 420 int type; /* Main OR import OR include. */ 421 int flags; 422 const xmlChar *schemaLocation; /* The URI of the schema document. */ 423 /* For chameleon includes, @origTargetNamespace will be NULL */ 424 const xmlChar *origTargetNamespace; 425 /* 426 * For chameleon includes, @targetNamespace will be the 427 * targetNamespace of the including schema. 428 */ 429 const xmlChar *targetNamespace; 430 xmlDocPtr doc; /* The schema node-tree. */ 431 /* @relations will hold any included/imported/redefined schemas. */ 432 xmlSchemaSchemaRelationPtr relations; 433 int located; 434 int parsed; 435 int imported; 436 int preserveDoc; 437 xmlSchemaItemListPtr globals; 438 xmlSchemaItemListPtr locals; 439 /* The imported schema. */ 440 xmlSchemaPtr schema; 441 }; 442 443 /* 444 * (extends xmlSchemaBucket) 445 */ 446 typedef struct _xmlSchemaInclude xmlSchemaInclude; 447 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 448 struct _xmlSchemaInclude { 449 int type; 450 int flags; 451 const xmlChar *schemaLocation; 452 const xmlChar *origTargetNamespace; 453 const xmlChar *targetNamespace; 454 xmlDocPtr doc; 455 xmlSchemaSchemaRelationPtr relations; 456 int located; 457 int parsed; 458 int imported; 459 int preserveDoc; 460 xmlSchemaItemListPtr globals; /* Global components. */ 461 xmlSchemaItemListPtr locals; /* Local components. */ 462 463 /* The owning main or import schema bucket. */ 464 xmlSchemaImportPtr ownerImport; 465 }; 466 467 /** 468 * xmlSchemaBasicItem: 469 * 470 * The abstract base type for schema components. 471 */ 472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 474 struct _xmlSchemaBasicItem { 475 xmlSchemaTypeType type; 476 }; 477 478 /** 479 * xmlSchemaAnnotItem: 480 * 481 * The abstract base type for annotated schema components. 482 * (Extends xmlSchemaBasicItem) 483 */ 484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 486 struct _xmlSchemaAnnotItem { 487 xmlSchemaTypeType type; 488 xmlSchemaAnnotPtr annot; 489 }; 490 491 /** 492 * xmlSchemaTreeItem: 493 * 494 * The abstract base type for tree-like structured schema components. 495 * (Extends xmlSchemaAnnotItem) 496 */ 497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 499 struct _xmlSchemaTreeItem { 500 xmlSchemaTypeType type; 501 xmlSchemaAnnotPtr annot; 502 xmlSchemaTreeItemPtr next; 503 xmlSchemaTreeItemPtr children; 504 }; 505 506 507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 508 /** 509 * xmlSchemaAttributeUsePtr: 510 * 511 * The abstract base type for tree-like structured schema components. 512 * (Extends xmlSchemaTreeItem) 513 */ 514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 516 struct _xmlSchemaAttributeUse { 517 xmlSchemaTypeType type; 518 xmlSchemaAnnotPtr annot; 519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 520 /* 521 * The attr. decl. OR a QName-ref. to an attr. decl. OR 522 * a QName-ref. to an attribute group definition. 523 */ 524 xmlSchemaAttributePtr attrDecl; 525 526 int flags; 527 xmlNodePtr node; 528 int occurs; /* required, optional */ 529 const xmlChar * defValue; 530 xmlSchemaValPtr defVal; 531 }; 532 533 /** 534 * xmlSchemaAttributeUseProhibPtr: 535 * 536 * A helper component to reflect attribute prohibitions. 537 * (Extends xmlSchemaBasicItem) 538 */ 539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 541 struct _xmlSchemaAttributeUseProhib { 542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 543 xmlNodePtr node; 544 const xmlChar *name; 545 const xmlChar *targetNamespace; 546 int isRef; 547 }; 548 549 /** 550 * xmlSchemaRedef: 551 */ 552 typedef struct _xmlSchemaRedef xmlSchemaRedef; 553 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 554 struct _xmlSchemaRedef { 555 xmlSchemaRedefPtr next; 556 xmlSchemaBasicItemPtr item; /* The redefining component. */ 557 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 559 const xmlChar *refName; /* The name of the to-be-redefined component. */ 560 const xmlChar *refTargetNs; /* The target namespace of the 561 to-be-redefined comp. */ 562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 563 }; 564 565 /** 566 * xmlSchemaConstructionCtxt: 567 */ 568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 570 struct _xmlSchemaConstructionCtxt { 571 xmlSchemaPtr mainSchema; /* The main schema. */ 572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 573 xmlDictPtr dict; 574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 576 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 577 xmlSchemaItemListPtr pending; /* All Components of all schemas that 578 need to be fixed. */ 579 xmlHashTablePtr substGroups; 580 xmlSchemaRedefPtr redefs; 581 xmlSchemaRedefPtr lastRedef; 582 }; 583 584 #define XML_SCHEMAS_PARSE_ERROR 1 585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 586 587 struct _xmlSchemaParserCtxt { 588 int type; 589 void *errCtxt; /* user specific error context */ 590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 592 int err; 593 int nberrors; 594 xmlStructuredErrorFunc serror; 595 596 xmlSchemaConstructionCtxtPtr constructor; 597 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 598 599 /* xmlSchemaPtr topschema; */ 600 /* xmlHashTablePtr namespaces; */ 601 602 xmlSchemaPtr schema; /* The main schema in use */ 603 int counter; 604 605 const xmlChar *URL; 606 xmlDocPtr doc; 607 int preserve; /* Whether the doc should be freed */ 608 609 const char *buffer; 610 int size; 611 612 /* 613 * Used to build complex element content models 614 */ 615 xmlAutomataPtr am; 616 xmlAutomataStatePtr start; 617 xmlAutomataStatePtr end; 618 xmlAutomataStatePtr state; 619 620 xmlDictPtr dict; /* dictionary for interned string names */ 621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 622 int options; 623 xmlSchemaValidCtxtPtr vctxt; 624 int isS4S; 625 int isRedefine; 626 int xsiAssemble; 627 int stop; /* If the parser should stop; i.e. a critical error. */ 628 const xmlChar *targetNamespace; 629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 630 631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 632 int redefCounter; /* Used for redefinitions. */ 633 xmlSchemaItemListPtr attrProhibs; 634 }; 635 636 /** 637 * xmlSchemaQNameRef: 638 * 639 * A component reference item (not a schema component) 640 * (Extends xmlSchemaBasicItem) 641 */ 642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 644 struct _xmlSchemaQNameRef { 645 xmlSchemaTypeType type; 646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 647 xmlSchemaTypeType itemType; 648 const xmlChar *name; 649 const xmlChar *targetNamespace; 650 xmlNodePtr node; 651 }; 652 653 /** 654 * xmlSchemaParticle: 655 * 656 * A particle component. 657 * (Extends xmlSchemaTreeItem) 658 */ 659 typedef struct _xmlSchemaParticle xmlSchemaParticle; 660 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 661 struct _xmlSchemaParticle { 662 xmlSchemaTypeType type; 663 xmlSchemaAnnotPtr annot; 664 xmlSchemaTreeItemPtr next; /* next particle */ 665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 667 etc.) */ 668 int minOccurs; 669 int maxOccurs; 670 xmlNodePtr node; 671 }; 672 673 /** 674 * xmlSchemaModelGroup: 675 * 676 * A model group component. 677 * (Extends xmlSchemaTreeItem) 678 */ 679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 681 struct _xmlSchemaModelGroup { 682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 683 xmlSchemaAnnotPtr annot; 684 xmlSchemaTreeItemPtr next; /* not used */ 685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 686 xmlNodePtr node; 687 }; 688 689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 691 /** 692 * xmlSchemaModelGroupDef: 693 * 694 * A model group definition component. 695 * (Extends xmlSchemaTreeItem) 696 */ 697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 699 struct _xmlSchemaModelGroupDef { 700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 701 xmlSchemaAnnotPtr annot; 702 xmlSchemaTreeItemPtr next; /* not used */ 703 xmlSchemaTreeItemPtr children; /* the "model group" */ 704 const xmlChar *name; 705 const xmlChar *targetNamespace; 706 xmlNodePtr node; 707 int flags; 708 }; 709 710 typedef struct _xmlSchemaIDC xmlSchemaIDC; 711 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 712 713 /** 714 * xmlSchemaIDCSelect: 715 * 716 * The identity-constraint "field" and "selector" item, holding the 717 * XPath expression. 718 */ 719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 721 struct _xmlSchemaIDCSelect { 722 xmlSchemaIDCSelectPtr next; 723 xmlSchemaIDCPtr idc; 724 int index; /* an index position if significant for IDC key-sequences */ 725 const xmlChar *xpath; /* the XPath expression */ 726 void *xpathComp; /* the compiled XPath expression */ 727 }; 728 729 /** 730 * xmlSchemaIDC: 731 * 732 * The identity-constraint definition component. 733 * (Extends xmlSchemaAnnotItem) 734 */ 735 736 struct _xmlSchemaIDC { 737 xmlSchemaTypeType type; 738 xmlSchemaAnnotPtr annot; 739 xmlSchemaIDCPtr next; 740 xmlNodePtr node; 741 const xmlChar *name; 742 const xmlChar *targetNamespace; 743 xmlSchemaIDCSelectPtr selector; 744 xmlSchemaIDCSelectPtr fields; 745 int nbFields; 746 xmlSchemaQNameRefPtr ref; 747 }; 748 749 /** 750 * xmlSchemaIDCAug: 751 * 752 * The augmented IDC information used for validation. 753 */ 754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 756 struct _xmlSchemaIDCAug { 757 xmlSchemaIDCAugPtr next; /* next in a list */ 758 xmlSchemaIDCPtr def; /* the IDC definition */ 759 int keyrefDepth; /* the lowest tree level to which IDC 760 tables need to be bubbled upwards */ 761 }; 762 763 /** 764 * xmlSchemaPSVIIDCKeySequence: 765 * 766 * The key sequence of a node table item. 767 */ 768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 770 struct _xmlSchemaPSVIIDCKey { 771 xmlSchemaTypePtr type; 772 xmlSchemaValPtr val; 773 }; 774 775 /** 776 * xmlSchemaPSVIIDCNode: 777 * 778 * The node table item of a node table. 779 */ 780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 782 struct _xmlSchemaPSVIIDCNode { 783 xmlNodePtr node; 784 xmlSchemaPSVIIDCKeyPtr *keys; 785 int nodeLine; 786 int nodeQNameID; 787 788 }; 789 790 /** 791 * xmlSchemaPSVIIDCBinding: 792 * 793 * The identity-constraint binding item of the [identity-constraint table]. 794 */ 795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 797 struct _xmlSchemaPSVIIDCBinding { 798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 799 xmlSchemaIDCPtr definition; /* the IDC definition */ 800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 801 int nbNodes; /* number of entries in the node table */ 802 int sizeNodes; /* size of the node table */ 803 xmlSchemaItemListPtr dupls; 804 }; 805 806 807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 809 810 #define XPATH_STATE_OBJ_MATCHES -2 811 #define XPATH_STATE_OBJ_BLOCKED -3 812 813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 815 816 /** 817 * xmlSchemaIDCStateObj: 818 * 819 * The state object used to evaluate XPath expressions. 820 */ 821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 823 struct _xmlSchemaIDCStateObj { 824 int type; 825 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 826 int depth; /* depth of creation */ 827 int *history; /* list of (depth, state-id) tuples */ 828 int nbHistory; 829 int sizeHistory; 830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 831 matcher */ 832 xmlSchemaIDCSelectPtr sel; 833 void *xpathCtxt; 834 }; 835 836 #define IDC_MATCHER 0 837 838 /** 839 * xmlSchemaIDCMatcher: 840 * 841 * Used to evaluate IDC selectors (and fields). 842 */ 843 struct _xmlSchemaIDCMatcher { 844 int type; 845 int depth; /* the tree depth at creation time */ 846 xmlSchemaIDCMatcherPtr next; /* next in the list */ 847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 849 int idcType; 850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 851 elements */ 852 int sizeKeySeqs; 853 xmlSchemaItemListPtr targets; /* list of target-node 854 (xmlSchemaPSVIIDCNodePtr) entries */ 855 }; 856 857 /* 858 * Element info flags. 859 */ 860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 862 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 864 865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 866 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 868 869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 873 874 /** 875 * xmlSchemaNodeInfo: 876 * 877 * Holds information of an element node. 878 */ 879 struct _xmlSchemaNodeInfo { 880 int nodeType; 881 xmlNodePtr node; 882 int nodeLine; 883 const xmlChar *localName; 884 const xmlChar *nsName; 885 const xmlChar *value; 886 xmlSchemaValPtr val; /* the pre-computed value if any */ 887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 888 889 int flags; /* combination of node info flags */ 890 891 int valNeeded; 892 int normVal; 893 894 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 895 int depth; 896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 897 for the scope element*/ 898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 899 element */ 900 xmlRegExecCtxtPtr regexCtxt; 901 902 const xmlChar **nsBindings; /* Namespace bindings on this element */ 903 int nbNsBindings; 904 int sizeNsBindings; 905 906 int hasKeyrefs; 907 int appliedXPath; /* Indicates that an XPath has been applied. */ 908 }; 909 910 #define XML_SCHEMAS_ATTR_UNKNOWN 1 911 #define XML_SCHEMAS_ATTR_ASSESSED 2 912 #define XML_SCHEMAS_ATTR_PROHIBITED 3 913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 917 #define XML_SCHEMAS_ATTR_DEFAULT 8 918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 926 #define XML_SCHEMAS_ATTR_META 17 927 /* 928 * @metaType values of xmlSchemaAttrInfo. 929 */ 930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 935 936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 938 struct _xmlSchemaAttrInfo { 939 int nodeType; 940 xmlNodePtr node; 941 int nodeLine; 942 const xmlChar *localName; 943 const xmlChar *nsName; 944 const xmlChar *value; 945 xmlSchemaValPtr val; /* the pre-computed value if any */ 946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 947 int flags; /* combination of node info flags */ 948 949 xmlSchemaAttributePtr decl; /* the attribute declaration */ 950 xmlSchemaAttributeUsePtr use; /* the attribute use */ 951 int state; 952 int metaType; 953 const xmlChar *vcValue; /* the value constraint value */ 954 xmlSchemaNodeInfoPtr parent; 955 }; 956 957 958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 959 /** 960 * xmlSchemaValidCtxt: 961 * 962 * A Schemas validation context 963 */ 964 struct _xmlSchemaValidCtxt { 965 int type; 966 void *errCtxt; /* user specific data block */ 967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 969 xmlStructuredErrorFunc serror; 970 971 xmlSchemaPtr schema; /* The schema in use */ 972 xmlDocPtr doc; 973 xmlParserInputBufferPtr input; 974 xmlCharEncoding enc; 975 xmlSAXHandlerPtr sax; 976 xmlParserCtxtPtr parserCtxt; 977 void *user_data; /* TODO: What is this for? */ 978 char *filename; 979 980 int err; 981 int nberrors; 982 983 xmlNodePtr node; 984 xmlNodePtr cur; 985 /* xmlSchemaTypePtr type; */ 986 987 xmlRegExecCtxtPtr regexp; 988 xmlSchemaValPtr value; 989 990 int valueWS; 991 int options; 992 xmlNodePtr validationRoot; 993 xmlSchemaParserCtxtPtr pctxt; 994 int xsiAssemble; 995 996 int depth; 997 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 998 int sizeElemInfos; 999 xmlSchemaNodeInfoPtr inode; /* the current element information */ 1000 1001 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1002 1003 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1004 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1005 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1006 1007 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1008 int nbIdcNodes; 1009 int sizeIdcNodes; 1010 1011 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1012 int nbIdcKeys; 1013 int sizeIdcKeys; 1014 1015 int flags; 1016 1017 xmlDictPtr dict; 1018 1019 #ifdef LIBXML_READER_ENABLED 1020 xmlTextReaderPtr reader; 1021 #endif 1022 1023 xmlSchemaAttrInfoPtr *attrInfos; 1024 int nbAttrInfos; 1025 int sizeAttrInfos; 1026 1027 int skipDepth; 1028 xmlSchemaItemListPtr nodeQNames; 1029 int hasKeyrefs; 1030 int createIDCNodeTables; 1031 int psviExposeIDCNodeTables; 1032 1033 /* Locator for error reporting in streaming mode */ 1034 xmlSchemaValidityLocatorFunc locFunc; 1035 void *locCtxt; 1036 }; 1037 1038 /** 1039 * xmlSchemaSubstGroup: 1040 * 1041 * 1042 */ 1043 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1044 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1045 struct _xmlSchemaSubstGroup { 1046 xmlSchemaElementPtr head; 1047 xmlSchemaItemListPtr members; 1048 }; 1049 1050 /************************************************************************ 1051 * * 1052 * Some predeclarations * 1053 * * 1054 ************************************************************************/ 1055 1056 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1057 xmlSchemaPtr schema, 1058 xmlNodePtr node); 1059 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1060 xmlSchemaPtr schema, 1061 xmlNodePtr node); 1062 static int 1063 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1064 xmlSchemaAbstractCtxtPtr ctxt); 1065 static const xmlChar * 1066 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1067 static int 1068 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1069 xmlNodePtr node); 1070 static int 1071 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1072 xmlSchemaParserCtxtPtr ctxt); 1073 static void 1074 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1075 static xmlSchemaWhitespaceValueType 1076 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1077 static xmlSchemaTreeItemPtr 1078 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1079 xmlNodePtr node, xmlSchemaTypeType type, 1080 int withParticle); 1081 static const xmlChar * 1082 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1083 static xmlSchemaTypeLinkPtr 1084 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1085 static void 1086 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1087 const char *funcName, 1088 const char *message) LIBXML_ATTR_FORMAT(3,0); 1089 static int 1090 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1091 xmlSchemaTypePtr type, 1092 xmlSchemaTypePtr baseType, 1093 int subset); 1094 static void 1095 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1096 xmlSchemaParserCtxtPtr ctxt); 1097 static void 1098 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1099 static xmlSchemaQNameRefPtr 1100 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1101 xmlSchemaPtr schema, 1102 xmlNodePtr node); 1103 1104 /************************************************************************ 1105 * * 1106 * Helper functions * 1107 * * 1108 ************************************************************************/ 1109 1110 /** 1111 * xmlSchemaItemTypeToStr: 1112 * @type: the type of the schema item 1113 * 1114 * Returns the component name of a schema item. 1115 */ 1116 static const xmlChar * 1117 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1118 { 1119 switch (type) { 1120 case XML_SCHEMA_TYPE_BASIC: 1121 return(BAD_CAST "simple type definition"); 1122 case XML_SCHEMA_TYPE_SIMPLE: 1123 return(BAD_CAST "simple type definition"); 1124 case XML_SCHEMA_TYPE_COMPLEX: 1125 return(BAD_CAST "complex type definition"); 1126 case XML_SCHEMA_TYPE_ELEMENT: 1127 return(BAD_CAST "element declaration"); 1128 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1129 return(BAD_CAST "attribute use"); 1130 case XML_SCHEMA_TYPE_ATTRIBUTE: 1131 return(BAD_CAST "attribute declaration"); 1132 case XML_SCHEMA_TYPE_GROUP: 1133 return(BAD_CAST "model group definition"); 1134 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1135 return(BAD_CAST "attribute group definition"); 1136 case XML_SCHEMA_TYPE_NOTATION: 1137 return(BAD_CAST "notation declaration"); 1138 case XML_SCHEMA_TYPE_SEQUENCE: 1139 return(BAD_CAST "model group (sequence)"); 1140 case XML_SCHEMA_TYPE_CHOICE: 1141 return(BAD_CAST "model group (choice)"); 1142 case XML_SCHEMA_TYPE_ALL: 1143 return(BAD_CAST "model group (all)"); 1144 case XML_SCHEMA_TYPE_PARTICLE: 1145 return(BAD_CAST "particle"); 1146 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1147 return(BAD_CAST "unique identity-constraint"); 1148 /* return(BAD_CAST "IDC (unique)"); */ 1149 case XML_SCHEMA_TYPE_IDC_KEY: 1150 return(BAD_CAST "key identity-constraint"); 1151 /* return(BAD_CAST "IDC (key)"); */ 1152 case XML_SCHEMA_TYPE_IDC_KEYREF: 1153 return(BAD_CAST "keyref identity-constraint"); 1154 /* return(BAD_CAST "IDC (keyref)"); */ 1155 case XML_SCHEMA_TYPE_ANY: 1156 return(BAD_CAST "wildcard (any)"); 1157 case XML_SCHEMA_EXTRA_QNAMEREF: 1158 return(BAD_CAST "[helper component] QName reference"); 1159 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1160 return(BAD_CAST "[helper component] attribute use prohibition"); 1161 default: 1162 return(BAD_CAST "Not a schema component"); 1163 } 1164 } 1165 1166 /** 1167 * xmlSchemaGetComponentTypeStr: 1168 * @type: the type of the schema item 1169 * 1170 * Returns the component name of a schema item. 1171 */ 1172 static const xmlChar * 1173 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1174 { 1175 switch (item->type) { 1176 case XML_SCHEMA_TYPE_BASIC: 1177 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1178 return(BAD_CAST "complex type definition"); 1179 else 1180 return(BAD_CAST "simple type definition"); 1181 default: 1182 return(xmlSchemaItemTypeToStr(item->type)); 1183 } 1184 } 1185 1186 /** 1187 * xmlSchemaGetComponentNode: 1188 * @item: a schema component 1189 * 1190 * Returns node associated with the schema component. 1191 * NOTE that such a node need not be available; plus, a component's 1192 * node need not to reflect the component directly, since there is no 1193 * one-to-one relationship between the XML Schema representation and 1194 * the component representation. 1195 */ 1196 static xmlNodePtr 1197 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1198 { 1199 switch (item->type) { 1200 case XML_SCHEMA_TYPE_ELEMENT: 1201 return (((xmlSchemaElementPtr) item)->node); 1202 case XML_SCHEMA_TYPE_ATTRIBUTE: 1203 return (((xmlSchemaAttributePtr) item)->node); 1204 case XML_SCHEMA_TYPE_COMPLEX: 1205 case XML_SCHEMA_TYPE_SIMPLE: 1206 return (((xmlSchemaTypePtr) item)->node); 1207 case XML_SCHEMA_TYPE_ANY: 1208 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1209 return (((xmlSchemaWildcardPtr) item)->node); 1210 case XML_SCHEMA_TYPE_PARTICLE: 1211 return (((xmlSchemaParticlePtr) item)->node); 1212 case XML_SCHEMA_TYPE_SEQUENCE: 1213 case XML_SCHEMA_TYPE_CHOICE: 1214 case XML_SCHEMA_TYPE_ALL: 1215 return (((xmlSchemaModelGroupPtr) item)->node); 1216 case XML_SCHEMA_TYPE_GROUP: 1217 return (((xmlSchemaModelGroupDefPtr) item)->node); 1218 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1219 return (((xmlSchemaAttributeGroupPtr) item)->node); 1220 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1221 case XML_SCHEMA_TYPE_IDC_KEY: 1222 case XML_SCHEMA_TYPE_IDC_KEYREF: 1223 return (((xmlSchemaIDCPtr) item)->node); 1224 case XML_SCHEMA_EXTRA_QNAMEREF: 1225 return(((xmlSchemaQNameRefPtr) item)->node); 1226 /* TODO: What to do with NOTATIONs? 1227 case XML_SCHEMA_TYPE_NOTATION: 1228 return (((xmlSchemaNotationPtr) item)->node); 1229 */ 1230 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1231 return (((xmlSchemaAttributeUsePtr) item)->node); 1232 default: 1233 return (NULL); 1234 } 1235 } 1236 1237 #if 0 1238 /** 1239 * xmlSchemaGetNextComponent: 1240 * @item: a schema component 1241 * 1242 * Returns the next sibling of the schema component. 1243 */ 1244 static xmlSchemaBasicItemPtr 1245 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1246 { 1247 switch (item->type) { 1248 case XML_SCHEMA_TYPE_ELEMENT: 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1250 case XML_SCHEMA_TYPE_ATTRIBUTE: 1251 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1252 case XML_SCHEMA_TYPE_COMPLEX: 1253 case XML_SCHEMA_TYPE_SIMPLE: 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1255 case XML_SCHEMA_TYPE_ANY: 1256 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1257 return (NULL); 1258 case XML_SCHEMA_TYPE_PARTICLE: 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1260 case XML_SCHEMA_TYPE_SEQUENCE: 1261 case XML_SCHEMA_TYPE_CHOICE: 1262 case XML_SCHEMA_TYPE_ALL: 1263 return (NULL); 1264 case XML_SCHEMA_TYPE_GROUP: 1265 return (NULL); 1266 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1268 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1269 case XML_SCHEMA_TYPE_IDC_KEY: 1270 case XML_SCHEMA_TYPE_IDC_KEYREF: 1271 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1272 default: 1273 return (NULL); 1274 } 1275 } 1276 #endif 1277 1278 1279 /** 1280 * xmlSchemaFormatQName: 1281 * @buf: the string buffer 1282 * @namespaceName: the namespace name 1283 * @localName: the local name 1284 * 1285 * Returns the given QName in the format "{namespaceName}localName" or 1286 * just "localName" if @namespaceName is NULL. 1287 * 1288 * Returns the localName if @namespaceName is NULL, a formatted 1289 * string otherwise. 1290 */ 1291 static const xmlChar* 1292 xmlSchemaFormatQName(xmlChar **buf, 1293 const xmlChar *namespaceName, 1294 const xmlChar *localName) 1295 { 1296 FREE_AND_NULL(*buf) 1297 if (namespaceName != NULL) { 1298 *buf = xmlStrdup(BAD_CAST "{"); 1299 *buf = xmlStrcat(*buf, namespaceName); 1300 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1301 } 1302 if (localName != NULL) { 1303 if (namespaceName == NULL) 1304 return(localName); 1305 *buf = xmlStrcat(*buf, localName); 1306 } else { 1307 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1308 } 1309 return ((const xmlChar *) *buf); 1310 } 1311 1312 static const xmlChar* 1313 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1314 { 1315 if (ns != NULL) 1316 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1317 else 1318 return (xmlSchemaFormatQName(buf, NULL, localName)); 1319 } 1320 1321 static const xmlChar * 1322 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1323 { 1324 switch (item->type) { 1325 case XML_SCHEMA_TYPE_ELEMENT: 1326 return (((xmlSchemaElementPtr) item)->name); 1327 case XML_SCHEMA_TYPE_ATTRIBUTE: 1328 return (((xmlSchemaAttributePtr) item)->name); 1329 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1330 return (((xmlSchemaAttributeGroupPtr) item)->name); 1331 case XML_SCHEMA_TYPE_BASIC: 1332 case XML_SCHEMA_TYPE_SIMPLE: 1333 case XML_SCHEMA_TYPE_COMPLEX: 1334 return (((xmlSchemaTypePtr) item)->name); 1335 case XML_SCHEMA_TYPE_GROUP: 1336 return (((xmlSchemaModelGroupDefPtr) item)->name); 1337 case XML_SCHEMA_TYPE_IDC_KEY: 1338 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1339 case XML_SCHEMA_TYPE_IDC_KEYREF: 1340 return (((xmlSchemaIDCPtr) item)->name); 1341 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1342 if (WXS_ATTRUSE_DECL(item) != NULL) { 1343 return(xmlSchemaGetComponentName( 1344 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1345 } else 1346 return(NULL); 1347 case XML_SCHEMA_EXTRA_QNAMEREF: 1348 return (((xmlSchemaQNameRefPtr) item)->name); 1349 case XML_SCHEMA_TYPE_NOTATION: 1350 return (((xmlSchemaNotationPtr) item)->name); 1351 default: 1352 /* 1353 * Other components cannot have names. 1354 */ 1355 break; 1356 } 1357 return (NULL); 1358 } 1359 1360 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1361 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1362 /* 1363 static const xmlChar * 1364 xmlSchemaGetQNameRefName(void *ref) 1365 { 1366 return(((xmlSchemaQNameRefPtr) ref)->name); 1367 } 1368 1369 static const xmlChar * 1370 xmlSchemaGetQNameRefTargetNs(void *ref) 1371 { 1372 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1373 } 1374 */ 1375 1376 static const xmlChar * 1377 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1378 { 1379 switch (item->type) { 1380 case XML_SCHEMA_TYPE_ELEMENT: 1381 return (((xmlSchemaElementPtr) item)->targetNamespace); 1382 case XML_SCHEMA_TYPE_ATTRIBUTE: 1383 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1384 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1385 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1386 case XML_SCHEMA_TYPE_BASIC: 1387 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1388 case XML_SCHEMA_TYPE_SIMPLE: 1389 case XML_SCHEMA_TYPE_COMPLEX: 1390 return (((xmlSchemaTypePtr) item)->targetNamespace); 1391 case XML_SCHEMA_TYPE_GROUP: 1392 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1393 case XML_SCHEMA_TYPE_IDC_KEY: 1394 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1395 case XML_SCHEMA_TYPE_IDC_KEYREF: 1396 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1397 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1398 if (WXS_ATTRUSE_DECL(item) != NULL) { 1399 return(xmlSchemaGetComponentTargetNs( 1400 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1401 } 1402 /* TODO: Will returning NULL break something? */ 1403 break; 1404 case XML_SCHEMA_EXTRA_QNAMEREF: 1405 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1406 case XML_SCHEMA_TYPE_NOTATION: 1407 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1408 default: 1409 /* 1410 * Other components cannot have names. 1411 */ 1412 break; 1413 } 1414 return (NULL); 1415 } 1416 1417 static const xmlChar* 1418 xmlSchemaGetComponentQName(xmlChar **buf, 1419 void *item) 1420 { 1421 return (xmlSchemaFormatQName(buf, 1422 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1423 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1424 } 1425 1426 static const xmlChar* 1427 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1428 { 1429 xmlChar *str = NULL; 1430 1431 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1432 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1433 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1434 (xmlSchemaBasicItemPtr) item)); 1435 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1436 FREE_AND_NULL(str); 1437 return(*buf); 1438 } 1439 1440 static const xmlChar* 1441 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1442 { 1443 return(xmlSchemaGetComponentDesignation(buf, idc)); 1444 } 1445 1446 /** 1447 * xmlSchemaWildcardPCToString: 1448 * @pc: the type of processContents 1449 * 1450 * Returns a string representation of the type of 1451 * processContents. 1452 */ 1453 static const xmlChar * 1454 xmlSchemaWildcardPCToString(int pc) 1455 { 1456 switch (pc) { 1457 case XML_SCHEMAS_ANY_SKIP: 1458 return (BAD_CAST "skip"); 1459 case XML_SCHEMAS_ANY_LAX: 1460 return (BAD_CAST "lax"); 1461 case XML_SCHEMAS_ANY_STRICT: 1462 return (BAD_CAST "strict"); 1463 default: 1464 return (BAD_CAST "invalid process contents"); 1465 } 1466 } 1467 1468 /** 1469 * xmlSchemaGetCanonValueWhtspExt: 1470 * @val: the precomputed value 1471 * @retValue: the returned value 1472 * @ws: the whitespace type of the value 1473 * 1474 * Get a the canonical representation of the value. 1475 * The caller has to free the returned retValue. 1476 * 1477 * Returns 0 if the value could be built and -1 in case of 1478 * API errors or if the value type is not supported yet. 1479 */ 1480 static int 1481 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1482 xmlSchemaWhitespaceValueType ws, 1483 xmlChar **retValue) 1484 { 1485 int list; 1486 xmlSchemaValType valType; 1487 const xmlChar *value, *value2 = NULL; 1488 1489 1490 if ((retValue == NULL) || (val == NULL)) 1491 return (-1); 1492 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1493 *retValue = NULL; 1494 do { 1495 value = NULL; 1496 valType = xmlSchemaGetValType(val); 1497 switch (valType) { 1498 case XML_SCHEMAS_STRING: 1499 case XML_SCHEMAS_NORMSTRING: 1500 case XML_SCHEMAS_ANYSIMPLETYPE: 1501 value = xmlSchemaValueGetAsString(val); 1502 if (value != NULL) { 1503 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1504 value2 = xmlSchemaCollapseString(value); 1505 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1506 value2 = xmlSchemaWhiteSpaceReplace(value); 1507 if (value2 != NULL) 1508 value = value2; 1509 } 1510 break; 1511 default: 1512 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1513 if (value2 != NULL) 1514 xmlFree((xmlChar *) value2); 1515 goto internal_error; 1516 } 1517 value = value2; 1518 } 1519 if (*retValue == NULL) 1520 if (value == NULL) { 1521 if (! list) 1522 *retValue = xmlStrdup(BAD_CAST ""); 1523 } else 1524 *retValue = xmlStrdup(value); 1525 else if (value != NULL) { 1526 /* List. */ 1527 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1528 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1529 } 1530 FREE_AND_NULL(value2) 1531 val = xmlSchemaValueGetNext(val); 1532 } while (val != NULL); 1533 1534 return (0); 1535 internal_error: 1536 if (*retValue != NULL) 1537 xmlFree((xmlChar *) (*retValue)); 1538 if (value2 != NULL) 1539 xmlFree((xmlChar *) value2); 1540 return (-1); 1541 } 1542 1543 /** 1544 * xmlSchemaFormatItemForReport: 1545 * @buf: the string buffer 1546 * @itemDes: the designation of the item 1547 * @itemName: the name of the item 1548 * @item: the item as an object 1549 * @itemNode: the node of the item 1550 * @local: the local name 1551 * @parsing: if the function is used during the parse 1552 * 1553 * Returns a representation of the given item used 1554 * for error reports. 1555 * 1556 * The following order is used to build the resulting 1557 * designation if the arguments are not NULL: 1558 * 1a. If itemDes not NULL -> itemDes 1559 * 1b. If (itemDes not NULL) and (itemName not NULL) 1560 * -> itemDes + itemName 1561 * 2. If the preceding was NULL and (item not NULL) -> item 1562 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1563 * 1564 * If the itemNode is an attribute node, the name of the attribute 1565 * will be appended to the result. 1566 * 1567 * Returns the formatted string and sets @buf to the resulting value. 1568 */ 1569 static xmlChar* 1570 xmlSchemaFormatItemForReport(xmlChar **buf, 1571 const xmlChar *itemDes, 1572 xmlSchemaBasicItemPtr item, 1573 xmlNodePtr itemNode) 1574 { 1575 xmlChar *str = NULL; 1576 int named = 1; 1577 1578 if (*buf != NULL) { 1579 xmlFree(*buf); 1580 *buf = NULL; 1581 } 1582 1583 if (itemDes != NULL) { 1584 *buf = xmlStrdup(itemDes); 1585 } else if (item != NULL) { 1586 switch (item->type) { 1587 case XML_SCHEMA_TYPE_BASIC: { 1588 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1589 1590 if (WXS_IS_ATOMIC(type)) 1591 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1592 else if (WXS_IS_LIST(type)) 1593 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1594 else if (WXS_IS_UNION(type)) 1595 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1596 else 1597 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1598 *buf = xmlStrcat(*buf, type->name); 1599 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1600 } 1601 break; 1602 case XML_SCHEMA_TYPE_SIMPLE: { 1603 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1604 1605 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1606 *buf = xmlStrdup(BAD_CAST""); 1607 } else { 1608 *buf = xmlStrdup(BAD_CAST "local "); 1609 } 1610 if (WXS_IS_ATOMIC(type)) 1611 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1612 else if (WXS_IS_LIST(type)) 1613 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1614 else if (WXS_IS_UNION(type)) 1615 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1616 else 1617 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1618 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1619 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1620 *buf = xmlStrcat(*buf, type->name); 1621 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1622 } 1623 } 1624 break; 1625 case XML_SCHEMA_TYPE_COMPLEX: { 1626 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1627 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1629 *buf = xmlStrdup(BAD_CAST ""); 1630 else 1631 *buf = xmlStrdup(BAD_CAST "local "); 1632 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1633 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1634 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1635 *buf = xmlStrcat(*buf, type->name); 1636 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1637 } 1638 } 1639 break; 1640 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1641 xmlSchemaAttributeUsePtr ause; 1642 1643 ause = WXS_ATTR_USE_CAST item; 1644 *buf = xmlStrdup(BAD_CAST "attribute use "); 1645 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1646 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1647 *buf = xmlStrcat(*buf, 1648 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1649 FREE_AND_NULL(str) 1650 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1651 } else { 1652 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1653 } 1654 } 1655 break; 1656 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1657 xmlSchemaAttributePtr attr; 1658 1659 attr = (xmlSchemaAttributePtr) item; 1660 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1661 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1662 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1663 attr->targetNamespace, attr->name)); 1664 FREE_AND_NULL(str) 1665 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1666 } 1667 break; 1668 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1669 xmlSchemaGetComponentDesignation(buf, item); 1670 break; 1671 case XML_SCHEMA_TYPE_ELEMENT: { 1672 xmlSchemaElementPtr elem; 1673 1674 elem = (xmlSchemaElementPtr) item; 1675 *buf = xmlStrdup(BAD_CAST "element decl."); 1676 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1677 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1678 elem->targetNamespace, elem->name)); 1679 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1680 } 1681 break; 1682 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1683 case XML_SCHEMA_TYPE_IDC_KEY: 1684 case XML_SCHEMA_TYPE_IDC_KEYREF: 1685 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1686 *buf = xmlStrdup(BAD_CAST "unique '"); 1687 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1688 *buf = xmlStrdup(BAD_CAST "key '"); 1689 else 1690 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1691 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1692 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1693 break; 1694 case XML_SCHEMA_TYPE_ANY: 1695 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1696 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1697 ((xmlSchemaWildcardPtr) item)->processContents)); 1698 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1699 break; 1700 case XML_SCHEMA_FACET_MININCLUSIVE: 1701 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1702 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1703 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1704 case XML_SCHEMA_FACET_TOTALDIGITS: 1705 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1706 case XML_SCHEMA_FACET_PATTERN: 1707 case XML_SCHEMA_FACET_ENUMERATION: 1708 case XML_SCHEMA_FACET_WHITESPACE: 1709 case XML_SCHEMA_FACET_LENGTH: 1710 case XML_SCHEMA_FACET_MAXLENGTH: 1711 case XML_SCHEMA_FACET_MINLENGTH: 1712 *buf = xmlStrdup(BAD_CAST "facet '"); 1713 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1714 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1715 break; 1716 case XML_SCHEMA_TYPE_GROUP: { 1717 *buf = xmlStrdup(BAD_CAST "model group def."); 1718 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1719 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1720 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1721 FREE_AND_NULL(str) 1722 } 1723 break; 1724 case XML_SCHEMA_TYPE_SEQUENCE: 1725 case XML_SCHEMA_TYPE_CHOICE: 1726 case XML_SCHEMA_TYPE_ALL: 1727 case XML_SCHEMA_TYPE_PARTICLE: 1728 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1729 break; 1730 case XML_SCHEMA_TYPE_NOTATION: { 1731 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1732 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1733 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1734 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1735 FREE_AND_NULL(str); 1736 } 1737 default: 1738 named = 0; 1739 } 1740 } else 1741 named = 0; 1742 1743 if ((named == 0) && (itemNode != NULL)) { 1744 xmlNodePtr elem; 1745 1746 if (itemNode->type == XML_ATTRIBUTE_NODE) 1747 elem = itemNode->parent; 1748 else 1749 elem = itemNode; 1750 *buf = xmlStrdup(BAD_CAST "Element '"); 1751 if (elem->ns != NULL) { 1752 *buf = xmlStrcat(*buf, 1753 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1754 FREE_AND_NULL(str) 1755 } else 1756 *buf = xmlStrcat(*buf, elem->name); 1757 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1758 1759 } 1760 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1761 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1762 if (itemNode->ns != NULL) { 1763 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1764 itemNode->ns->href, itemNode->name)); 1765 FREE_AND_NULL(str) 1766 } else 1767 *buf = xmlStrcat(*buf, itemNode->name); 1768 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1769 } 1770 FREE_AND_NULL(str) 1771 1772 return (xmlEscapeFormatString(buf)); 1773 } 1774 1775 /** 1776 * xmlSchemaFormatFacetEnumSet: 1777 * @buf: the string buffer 1778 * @type: the type holding the enumeration facets 1779 * 1780 * Builds a string consisting of all enumeration elements. 1781 * 1782 * Returns a string of all enumeration elements. 1783 */ 1784 static const xmlChar * 1785 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1786 xmlChar **buf, xmlSchemaTypePtr type) 1787 { 1788 xmlSchemaFacetPtr facet; 1789 xmlSchemaWhitespaceValueType ws; 1790 xmlChar *value = NULL; 1791 int res, found = 0; 1792 1793 if (*buf != NULL) 1794 xmlFree(*buf); 1795 *buf = NULL; 1796 1797 do { 1798 /* 1799 * Use the whitespace type of the base type. 1800 */ 1801 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1802 for (facet = type->facets; facet != NULL; facet = facet->next) { 1803 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1804 continue; 1805 found = 1; 1806 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1807 ws, &value); 1808 if (res == -1) { 1809 xmlSchemaInternalErr(actxt, 1810 "xmlSchemaFormatFacetEnumSet", 1811 "compute the canonical lexical representation"); 1812 if (*buf != NULL) 1813 xmlFree(*buf); 1814 *buf = NULL; 1815 return (NULL); 1816 } 1817 if (*buf == NULL) 1818 *buf = xmlStrdup(BAD_CAST "'"); 1819 else 1820 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1821 *buf = xmlStrcat(*buf, BAD_CAST value); 1822 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1823 if (value != NULL) { 1824 xmlFree((xmlChar *)value); 1825 value = NULL; 1826 } 1827 } 1828 /* 1829 * The enumeration facet of a type restricts the enumeration 1830 * facet of the ancestor type; i.e., such restricted enumerations 1831 * do not belong to the set of the given type. Thus we break 1832 * on the first found enumeration. 1833 */ 1834 if (found) 1835 break; 1836 type = type->baseType; 1837 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1838 1839 return ((const xmlChar *) *buf); 1840 } 1841 1842 /************************************************************************ 1843 * * 1844 * Error functions * 1845 * * 1846 ************************************************************************/ 1847 1848 #if 0 1849 static void 1850 xmlSchemaErrMemory(const char *msg) 1851 { 1852 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1853 msg); 1854 } 1855 #endif 1856 1857 static void 1858 xmlSchemaPSimpleErr(const char *msg) 1859 { 1860 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1861 msg); 1862 } 1863 1864 /** 1865 * xmlSchemaPErrMemory: 1866 * @node: a context node 1867 * @extra: extra informations 1868 * 1869 * Handle an out of memory condition 1870 */ 1871 static void 1872 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1873 const char *extra, xmlNodePtr node) 1874 { 1875 if (ctxt != NULL) 1876 ctxt->nberrors++; 1877 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1878 extra); 1879 } 1880 1881 /** 1882 * xmlSchemaPErr: 1883 * @ctxt: the parsing context 1884 * @node: the context node 1885 * @error: the error code 1886 * @msg: the error message 1887 * @str1: extra data 1888 * @str2: extra data 1889 * 1890 * Handle a parser error 1891 */ 1892 static void LIBXML_ATTR_FORMAT(4,0) 1893 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1894 const char *msg, const xmlChar * str1, const xmlChar * str2) 1895 { 1896 xmlGenericErrorFunc channel = NULL; 1897 xmlStructuredErrorFunc schannel = NULL; 1898 void *data = NULL; 1899 1900 if (ctxt != NULL) { 1901 ctxt->nberrors++; 1902 ctxt->err = error; 1903 channel = ctxt->error; 1904 data = ctxt->errCtxt; 1905 schannel = ctxt->serror; 1906 } 1907 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1908 error, XML_ERR_ERROR, NULL, 0, 1909 (const char *) str1, (const char *) str2, NULL, 0, 0, 1910 msg, str1, str2); 1911 } 1912 1913 /** 1914 * xmlSchemaPErr2: 1915 * @ctxt: the parsing context 1916 * @node: the context node 1917 * @node: the current child 1918 * @error: the error code 1919 * @msg: the error message 1920 * @str1: extra data 1921 * @str2: extra data 1922 * 1923 * Handle a parser error 1924 */ 1925 static void LIBXML_ATTR_FORMAT(5,0) 1926 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1927 xmlNodePtr child, int error, 1928 const char *msg, const xmlChar * str1, const xmlChar * str2) 1929 { 1930 if (child != NULL) 1931 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1932 else 1933 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1934 } 1935 1936 1937 /** 1938 * xmlSchemaPErrExt: 1939 * @ctxt: the parsing context 1940 * @node: the context node 1941 * @error: the error code 1942 * @strData1: extra data 1943 * @strData2: extra data 1944 * @strData3: extra data 1945 * @msg: the message 1946 * @str1: extra parameter for the message display 1947 * @str2: extra parameter for the message display 1948 * @str3: extra parameter for the message display 1949 * @str4: extra parameter for the message display 1950 * @str5: extra parameter for the message display 1951 * 1952 * Handle a parser error 1953 */ 1954 static void LIBXML_ATTR_FORMAT(7,0) 1955 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1956 const xmlChar * strData1, const xmlChar * strData2, 1957 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1958 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1959 const xmlChar * str5) 1960 { 1961 1962 xmlGenericErrorFunc channel = NULL; 1963 xmlStructuredErrorFunc schannel = NULL; 1964 void *data = NULL; 1965 1966 if (ctxt != NULL) { 1967 ctxt->nberrors++; 1968 ctxt->err = error; 1969 channel = ctxt->error; 1970 data = ctxt->errCtxt; 1971 schannel = ctxt->serror; 1972 } 1973 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1974 error, XML_ERR_ERROR, NULL, 0, 1975 (const char *) strData1, (const char *) strData2, 1976 (const char *) strData3, 0, 0, msg, str1, str2, 1977 str3, str4, str5); 1978 } 1979 1980 /************************************************************************ 1981 * * 1982 * Allround error functions * 1983 * * 1984 ************************************************************************/ 1985 1986 /** 1987 * xmlSchemaVTypeErrMemory: 1988 * @node: a context node 1989 * @extra: extra informations 1990 * 1991 * Handle an out of memory condition 1992 */ 1993 static void 1994 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 1995 const char *extra, xmlNodePtr node) 1996 { 1997 if (ctxt != NULL) { 1998 ctxt->nberrors++; 1999 ctxt->err = XML_SCHEMAV_INTERNAL; 2000 } 2001 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2002 extra); 2003 } 2004 2005 static void LIBXML_ATTR_FORMAT(2,0) 2006 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2007 const char *msg, const xmlChar *str) 2008 { 2009 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2010 msg, (const char *) str); 2011 } 2012 2013 #define WXS_ERROR_TYPE_ERROR 1 2014 #define WXS_ERROR_TYPE_WARNING 2 2015 /** 2016 * xmlSchemaErr4Line: 2017 * @ctxt: the validation context 2018 * @errorLevel: the error level 2019 * @error: the error code 2020 * @node: the context node 2021 * @line: the line number 2022 * @msg: the error message 2023 * @str1: extra data 2024 * @str2: extra data 2025 * @str3: extra data 2026 * @str4: extra data 2027 * 2028 * Handle a validation error 2029 */ 2030 static void LIBXML_ATTR_FORMAT(6,0) 2031 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2032 xmlErrorLevel errorLevel, 2033 int error, xmlNodePtr node, int line, const char *msg, 2034 const xmlChar *str1, const xmlChar *str2, 2035 const xmlChar *str3, const xmlChar *str4) 2036 { 2037 xmlStructuredErrorFunc schannel = NULL; 2038 xmlGenericErrorFunc channel = NULL; 2039 void *data = NULL; 2040 2041 if (ctxt != NULL) { 2042 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2043 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2044 const char *file = NULL; 2045 int col = 0; 2046 if (errorLevel != XML_ERR_WARNING) { 2047 vctxt->nberrors++; 2048 vctxt->err = error; 2049 channel = vctxt->error; 2050 } else { 2051 channel = vctxt->warning; 2052 } 2053 schannel = vctxt->serror; 2054 data = vctxt->errCtxt; 2055 2056 /* 2057 * Error node. If we specify a line number, then 2058 * do not channel any node to the error function. 2059 */ 2060 if (line == 0) { 2061 if ((node == NULL) && 2062 (vctxt->depth >= 0) && 2063 (vctxt->inode != NULL)) { 2064 node = vctxt->inode->node; 2065 } 2066 /* 2067 * Get filename and line if no node-tree. 2068 */ 2069 if ((node == NULL) && 2070 (vctxt->parserCtxt != NULL) && 2071 (vctxt->parserCtxt->input != NULL)) { 2072 file = vctxt->parserCtxt->input->filename; 2073 line = vctxt->parserCtxt->input->line; 2074 col = vctxt->parserCtxt->input->col; 2075 } 2076 } else { 2077 /* 2078 * Override the given node's (if any) position 2079 * and channel only the given line number. 2080 */ 2081 node = NULL; 2082 /* 2083 * Get filename. 2084 */ 2085 if (vctxt->doc != NULL) 2086 file = (const char *) vctxt->doc->URL; 2087 else if ((vctxt->parserCtxt != NULL) && 2088 (vctxt->parserCtxt->input != NULL)) 2089 file = vctxt->parserCtxt->input->filename; 2090 } 2091 if (vctxt->locFunc != NULL) { 2092 if ((file == NULL) || (line == 0)) { 2093 unsigned long l; 2094 const char *f; 2095 vctxt->locFunc(vctxt->locCtxt, &f, &l); 2096 if (file == NULL) 2097 file = f; 2098 if (line == 0) 2099 line = (int) l; 2100 } 2101 } 2102 if ((file == NULL) && (vctxt->filename != NULL)) 2103 file = vctxt->filename; 2104 2105 __xmlRaiseError(schannel, channel, data, ctxt, 2106 node, XML_FROM_SCHEMASV, 2107 error, errorLevel, file, line, 2108 (const char *) str1, (const char *) str2, 2109 (const char *) str3, 0, col, msg, str1, str2, str3, str4); 2110 2111 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2112 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2113 if (errorLevel != XML_ERR_WARNING) { 2114 pctxt->nberrors++; 2115 pctxt->err = error; 2116 channel = pctxt->error; 2117 } else { 2118 channel = pctxt->warning; 2119 } 2120 schannel = pctxt->serror; 2121 data = pctxt->errCtxt; 2122 __xmlRaiseError(schannel, channel, data, ctxt, 2123 node, XML_FROM_SCHEMASP, error, 2124 errorLevel, NULL, 0, 2125 (const char *) str1, (const char *) str2, 2126 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2127 } else { 2128 TODO 2129 } 2130 } 2131 } 2132 2133 /** 2134 * xmlSchemaErr3: 2135 * @ctxt: the validation context 2136 * @node: the context node 2137 * @error: the error code 2138 * @msg: the error message 2139 * @str1: extra data 2140 * @str2: extra data 2141 * @str3: extra data 2142 * 2143 * Handle a validation error 2144 */ 2145 static void LIBXML_ATTR_FORMAT(4,0) 2146 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2147 int error, xmlNodePtr node, const char *msg, 2148 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2149 { 2150 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2151 msg, str1, str2, str3, NULL); 2152 } 2153 2154 static void LIBXML_ATTR_FORMAT(4,0) 2155 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2156 int error, xmlNodePtr node, const char *msg, 2157 const xmlChar *str1, const xmlChar *str2, 2158 const xmlChar *str3, const xmlChar *str4) 2159 { 2160 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2161 msg, str1, str2, str3, str4); 2162 } 2163 2164 static void LIBXML_ATTR_FORMAT(4,0) 2165 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2166 int error, xmlNodePtr node, const char *msg, 2167 const xmlChar *str1, const xmlChar *str2) 2168 { 2169 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2170 } 2171 2172 static xmlChar * 2173 xmlSchemaFormatNodeForError(xmlChar ** msg, 2174 xmlSchemaAbstractCtxtPtr actxt, 2175 xmlNodePtr node) 2176 { 2177 xmlChar *str = NULL; 2178 2179 *msg = NULL; 2180 if ((node != NULL) && 2181 (node->type != XML_ELEMENT_NODE) && 2182 (node->type != XML_ATTRIBUTE_NODE)) 2183 { 2184 /* 2185 * Don't try to format other nodes than element and 2186 * attribute nodes. 2187 * Play safe and return an empty string. 2188 */ 2189 *msg = xmlStrdup(BAD_CAST ""); 2190 return(*msg); 2191 } 2192 if (node != NULL) { 2193 /* 2194 * Work on tree nodes. 2195 */ 2196 if (node->type == XML_ATTRIBUTE_NODE) { 2197 xmlNodePtr elem = node->parent; 2198 2199 *msg = xmlStrdup(BAD_CAST "Element '"); 2200 if (elem->ns != NULL) 2201 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2202 elem->ns->href, elem->name)); 2203 else 2204 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2205 NULL, elem->name)); 2206 FREE_AND_NULL(str); 2207 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2208 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2209 } else { 2210 *msg = xmlStrdup(BAD_CAST "Element '"); 2211 } 2212 if (node->ns != NULL) 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2214 node->ns->href, node->name)); 2215 else 2216 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2217 NULL, node->name)); 2218 FREE_AND_NULL(str); 2219 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2220 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2221 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2222 /* 2223 * Work on node infos. 2224 */ 2225 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2226 xmlSchemaNodeInfoPtr ielem = 2227 vctxt->elemInfos[vctxt->depth]; 2228 2229 *msg = xmlStrdup(BAD_CAST "Element '"); 2230 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2231 ielem->nsName, ielem->localName)); 2232 FREE_AND_NULL(str); 2233 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2234 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2235 } else { 2236 *msg = xmlStrdup(BAD_CAST "Element '"); 2237 } 2238 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2239 vctxt->inode->nsName, vctxt->inode->localName)); 2240 FREE_AND_NULL(str); 2241 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2242 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2243 /* 2244 * Hmm, no node while parsing? 2245 * Return an empty string, in case NULL will break something. 2246 */ 2247 *msg = xmlStrdup(BAD_CAST ""); 2248 } else { 2249 TODO 2250 return (NULL); 2251 } 2252 2253 /* 2254 * xmlSchemaFormatItemForReport() also returns an escaped format 2255 * string, so do this before calling it below (in the future). 2256 */ 2257 xmlEscapeFormatString(msg); 2258 2259 /* 2260 * VAL TODO: The output of the given schema component is currently 2261 * disabled. 2262 */ 2263 #if 0 2264 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2265 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2266 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2267 NULL, type, NULL, 0)); 2268 FREE_AND_NULL(str) 2269 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2270 } 2271 #endif 2272 return (*msg); 2273 } 2274 2275 static void LIBXML_ATTR_FORMAT(3,0) 2276 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2277 const char *funcName, 2278 const char *message, 2279 const xmlChar *str1, 2280 const xmlChar *str2) 2281 { 2282 xmlChar *msg = NULL; 2283 2284 if (actxt == NULL) 2285 return; 2286 msg = xmlStrdup(BAD_CAST "Internal error: %s, "); 2287 msg = xmlStrcat(msg, BAD_CAST message); 2288 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2289 2290 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2291 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, 2292 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2293 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2294 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, 2295 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2296 2297 FREE_AND_NULL(msg) 2298 } 2299 2300 static void LIBXML_ATTR_FORMAT(3,0) 2301 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2302 const char *funcName, 2303 const char *message) 2304 { 2305 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2306 } 2307 2308 #if 0 2309 static void LIBXML_ATTR_FORMAT(3,0) 2310 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2311 const char *funcName, 2312 const char *message, 2313 const xmlChar *str1, 2314 const xmlChar *str2) 2315 { 2316 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2317 str1, str2); 2318 } 2319 #endif 2320 2321 static void LIBXML_ATTR_FORMAT(5,0) 2322 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2323 xmlParserErrors error, 2324 xmlNodePtr node, 2325 xmlSchemaBasicItemPtr item, 2326 const char *message, 2327 const xmlChar *str1, const xmlChar *str2, 2328 const xmlChar *str3, const xmlChar *str4) 2329 { 2330 xmlChar *msg = NULL; 2331 2332 if ((node == NULL) && (item != NULL) && 2333 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2334 node = WXS_ITEM_NODE(item); 2335 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2336 msg = xmlStrcat(msg, BAD_CAST ": "); 2337 } else 2338 xmlSchemaFormatNodeForError(&msg, actxt, node); 2339 msg = xmlStrcat(msg, (const xmlChar *) message); 2340 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2341 xmlSchemaErr4(actxt, error, node, 2342 (const char *) msg, str1, str2, str3, str4); 2343 FREE_AND_NULL(msg) 2344 } 2345 2346 static void LIBXML_ATTR_FORMAT(5,0) 2347 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2348 xmlParserErrors error, 2349 xmlNodePtr node, 2350 xmlSchemaBasicItemPtr item, 2351 const char *message, 2352 const xmlChar *str1, 2353 const xmlChar *str2) 2354 { 2355 xmlSchemaCustomErr4(actxt, error, node, item, 2356 message, str1, str2, NULL, NULL); 2357 } 2358 2359 2360 2361 static void LIBXML_ATTR_FORMAT(5,0) 2362 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2363 xmlParserErrors error, 2364 xmlNodePtr node, 2365 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2366 const char *message, 2367 const xmlChar *str1, 2368 const xmlChar *str2, 2369 const xmlChar *str3) 2370 { 2371 xmlChar *msg = NULL; 2372 2373 xmlSchemaFormatNodeForError(&msg, actxt, node); 2374 msg = xmlStrcat(msg, (const xmlChar *) message); 2375 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2376 2377 /* URGENT TODO: Set the error code to something sane. */ 2378 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2379 (const char *) msg, str1, str2, str3, NULL); 2380 2381 FREE_AND_NULL(msg) 2382 } 2383 2384 2385 2386 static void LIBXML_ATTR_FORMAT(5,0) 2387 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2388 xmlParserErrors error, 2389 xmlSchemaPSVIIDCNodePtr idcNode, 2390 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2391 const char *message, 2392 const xmlChar *str1, 2393 const xmlChar *str2) 2394 { 2395 xmlChar *msg = NULL, *qname = NULL; 2396 2397 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2398 msg = xmlStrcat(msg, (const xmlChar *) message); 2399 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2400 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2401 error, NULL, idcNode->nodeLine, (const char *) msg, 2402 xmlSchemaFormatQName(&qname, 2403 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2404 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2405 str1, str2, NULL); 2406 FREE_AND_NULL(qname); 2407 FREE_AND_NULL(msg); 2408 } 2409 2410 static int 2411 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2412 xmlNodePtr node) 2413 { 2414 if (node != NULL) 2415 return (node->type); 2416 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2417 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2418 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2419 return (-1); 2420 } 2421 2422 static int 2423 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2424 { 2425 switch (item->type) { 2426 case XML_SCHEMA_TYPE_COMPLEX: 2427 case XML_SCHEMA_TYPE_SIMPLE: 2428 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2429 return(1); 2430 break; 2431 case XML_SCHEMA_TYPE_GROUP: 2432 return (1); 2433 case XML_SCHEMA_TYPE_ELEMENT: 2434 if ( ((xmlSchemaElementPtr) item)->flags & 2435 XML_SCHEMAS_ELEM_GLOBAL) 2436 return(1); 2437 break; 2438 case XML_SCHEMA_TYPE_ATTRIBUTE: 2439 if ( ((xmlSchemaAttributePtr) item)->flags & 2440 XML_SCHEMAS_ATTR_GLOBAL) 2441 return(1); 2442 break; 2443 /* Note that attribute groups are always global. */ 2444 default: 2445 return(1); 2446 } 2447 return (0); 2448 } 2449 2450 static void 2451 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2452 xmlParserErrors error, 2453 xmlNodePtr node, 2454 const xmlChar *value, 2455 xmlSchemaTypePtr type, 2456 int displayValue) 2457 { 2458 xmlChar *msg = NULL; 2459 2460 xmlSchemaFormatNodeForError(&msg, actxt, node); 2461 2462 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2463 XML_ATTRIBUTE_NODE)) 2464 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2465 else 2466 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2467 "value of "); 2468 2469 if (! xmlSchemaIsGlobalItem(type)) 2470 msg = xmlStrcat(msg, BAD_CAST "the local "); 2471 else 2472 msg = xmlStrcat(msg, BAD_CAST "the "); 2473 2474 if (WXS_IS_ATOMIC(type)) 2475 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2476 else if (WXS_IS_LIST(type)) 2477 msg = xmlStrcat(msg, BAD_CAST "list type"); 2478 else if (WXS_IS_UNION(type)) 2479 msg = xmlStrcat(msg, BAD_CAST "union type"); 2480 2481 if (xmlSchemaIsGlobalItem(type)) { 2482 xmlChar *str = NULL; 2483 msg = xmlStrcat(msg, BAD_CAST " '"); 2484 if (type->builtInType != 0) { 2485 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2486 str = xmlStrdup(type->name); 2487 } else { 2488 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 2489 if (!str) 2490 str = xmlStrdup(qName); 2491 } 2492 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2493 msg = xmlStrcat(msg, BAD_CAST "'"); 2494 FREE_AND_NULL(str); 2495 } 2496 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2497 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2498 XML_ATTRIBUTE_NODE)) 2499 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2500 else 2501 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2502 FREE_AND_NULL(msg) 2503 } 2504 2505 static const xmlChar * 2506 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2507 xmlSchemaNodeInfoPtr ni, 2508 xmlNodePtr node) 2509 { 2510 if (node != NULL) { 2511 if (node->ns != NULL) 2512 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2513 else 2514 return (xmlSchemaFormatQName(str, NULL, node->name)); 2515 } else if (ni != NULL) 2516 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2517 return (NULL); 2518 } 2519 2520 static void 2521 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2522 xmlParserErrors error, 2523 xmlSchemaAttrInfoPtr ni, 2524 xmlNodePtr node) 2525 { 2526 xmlChar *msg = NULL, *str = NULL; 2527 2528 xmlSchemaFormatNodeForError(&msg, actxt, node); 2529 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2530 xmlSchemaErr(actxt, error, node, (const char *) msg, 2531 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2532 NULL); 2533 FREE_AND_NULL(str) 2534 FREE_AND_NULL(msg) 2535 } 2536 2537 static void LIBXML_ATTR_FORMAT(5,0) 2538 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2539 xmlParserErrors error, 2540 xmlNodePtr node, 2541 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2542 const char *message, 2543 int nbval, 2544 int nbneg, 2545 xmlChar **values) 2546 { 2547 xmlChar *str = NULL, *msg = NULL; 2548 xmlChar *localName, *nsName; 2549 const xmlChar *cur, *end; 2550 int i; 2551 2552 xmlSchemaFormatNodeForError(&msg, actxt, node); 2553 msg = xmlStrcat(msg, (const xmlChar *) message); 2554 msg = xmlStrcat(msg, BAD_CAST "."); 2555 /* 2556 * Note that is does not make sense to report that we have a 2557 * wildcard here, since the wildcard might be unfolded into 2558 * multiple transitions. 2559 */ 2560 if (nbval + nbneg > 0) { 2561 if (nbval + nbneg > 1) { 2562 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2563 } else 2564 str = xmlStrdup(BAD_CAST " Expected is ( "); 2565 nsName = NULL; 2566 2567 for (i = 0; i < nbval + nbneg; i++) { 2568 cur = values[i]; 2569 if (cur == NULL) 2570 continue; 2571 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2572 (cur[3] == ' ')) { 2573 cur += 4; 2574 str = xmlStrcat(str, BAD_CAST "##other"); 2575 } 2576 /* 2577 * Get the local name. 2578 */ 2579 localName = NULL; 2580 2581 end = cur; 2582 if (*end == '*') { 2583 localName = xmlStrdup(BAD_CAST "*"); 2584 end++; 2585 } else { 2586 while ((*end != 0) && (*end != '|')) 2587 end++; 2588 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2589 } 2590 if (*end != 0) { 2591 end++; 2592 /* 2593 * Skip "*|*" if they come with negated expressions, since 2594 * they represent the same negated wildcard. 2595 */ 2596 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2597 /* 2598 * Get the namespace name. 2599 */ 2600 cur = end; 2601 if (*end == '*') { 2602 nsName = xmlStrdup(BAD_CAST "{*}"); 2603 } else { 2604 while (*end != 0) 2605 end++; 2606 2607 if (i >= nbval) 2608 nsName = xmlStrdup(BAD_CAST "{##other:"); 2609 else 2610 nsName = xmlStrdup(BAD_CAST "{"); 2611 2612 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2613 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2614 } 2615 str = xmlStrcat(str, BAD_CAST nsName); 2616 FREE_AND_NULL(nsName) 2617 } else { 2618 FREE_AND_NULL(localName); 2619 continue; 2620 } 2621 } 2622 str = xmlStrcat(str, BAD_CAST localName); 2623 FREE_AND_NULL(localName); 2624 2625 if (i < nbval + nbneg -1) 2626 str = xmlStrcat(str, BAD_CAST ", "); 2627 } 2628 str = xmlStrcat(str, BAD_CAST " ).\n"); 2629 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2630 FREE_AND_NULL(str) 2631 } else 2632 msg = xmlStrcat(msg, BAD_CAST "\n"); 2633 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2634 xmlFree(msg); 2635 } 2636 2637 static void LIBXML_ATTR_FORMAT(8,0) 2638 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2639 xmlParserErrors error, 2640 xmlNodePtr node, 2641 const xmlChar *value, 2642 unsigned long length, 2643 xmlSchemaTypePtr type, 2644 xmlSchemaFacetPtr facet, 2645 const char *message, 2646 const xmlChar *str1, 2647 const xmlChar *str2) 2648 { 2649 xmlChar *str = NULL, *msg = NULL; 2650 xmlSchemaTypeType facetType; 2651 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2652 2653 xmlSchemaFormatNodeForError(&msg, actxt, node); 2654 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2655 facetType = XML_SCHEMA_FACET_ENUMERATION; 2656 /* 2657 * If enumerations are validated, one must not expect the 2658 * facet to be given. 2659 */ 2660 } else 2661 facetType = facet->type; 2662 msg = xmlStrcat(msg, BAD_CAST "["); 2663 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2664 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2665 msg = xmlStrcat(msg, BAD_CAST "'] "); 2666 if (message == NULL) { 2667 /* 2668 * Use a default message. 2669 */ 2670 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2671 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2672 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2673 2674 char len[25], actLen[25]; 2675 2676 /* FIXME, TODO: What is the max expected string length of the 2677 * this value? 2678 */ 2679 if (nodeType == XML_ATTRIBUTE_NODE) 2680 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2681 else 2682 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2683 2684 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2685 snprintf(actLen, 24, "%lu", length); 2686 2687 if (facetType == XML_SCHEMA_FACET_LENGTH) 2688 msg = xmlStrcat(msg, 2689 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2690 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2691 msg = xmlStrcat(msg, 2692 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2693 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2694 msg = xmlStrcat(msg, 2695 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2696 2697 if (nodeType == XML_ATTRIBUTE_NODE) 2698 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2699 value, (const xmlChar *) actLen, (const xmlChar *) len); 2700 else 2701 xmlSchemaErr(actxt, error, node, (const char *) msg, 2702 (const xmlChar *) actLen, (const xmlChar *) len); 2703 2704 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2705 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2706 "of the set {%s}.\n"); 2707 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2708 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2709 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2710 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2711 "by the pattern '%s'.\n"); 2712 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2713 facet->value); 2714 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2715 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2716 "minimum value allowed ('%s').\n"); 2717 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2718 facet->value); 2719 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2720 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2721 "maximum value allowed ('%s').\n"); 2722 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2723 facet->value); 2724 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2725 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2726 "'%s'.\n"); 2727 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2728 facet->value); 2729 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2730 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2731 "'%s'.\n"); 2732 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2733 facet->value); 2734 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2735 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2736 "digits than are allowed ('%s').\n"); 2737 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2738 facet->value); 2739 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2740 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2741 "digits than are allowed ('%s').\n"); 2742 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2743 facet->value); 2744 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2745 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2746 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2747 } else { 2748 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2749 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2750 } 2751 } else { 2752 msg = xmlStrcat(msg, (const xmlChar *) message); 2753 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2754 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2755 } 2756 FREE_AND_NULL(str) 2757 xmlFree(msg); 2758 } 2759 2760 #define VERROR(err, type, msg) \ 2761 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2762 2763 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2764 2765 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2766 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2767 2768 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2769 2770 2771 /** 2772 * xmlSchemaPMissingAttrErr: 2773 * @ctxt: the schema validation context 2774 * @ownerDes: the designation of the owner 2775 * @ownerName: the name of the owner 2776 * @ownerItem: the owner as a schema object 2777 * @ownerElem: the owner as an element node 2778 * @node: the parent element node of the missing attribute node 2779 * @type: the corresponding type of the attribute node 2780 * 2781 * Reports an illegal attribute. 2782 */ 2783 static void 2784 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2785 xmlParserErrors error, 2786 xmlSchemaBasicItemPtr ownerItem, 2787 xmlNodePtr ownerElem, 2788 const char *name, 2789 const char *message) 2790 { 2791 xmlChar *des = NULL; 2792 2793 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2794 2795 if (message != NULL) 2796 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2797 else 2798 xmlSchemaPErr(ctxt, ownerElem, error, 2799 "%s: The attribute '%s' is required but missing.\n", 2800 BAD_CAST des, BAD_CAST name); 2801 FREE_AND_NULL(des); 2802 } 2803 2804 2805 /** 2806 * xmlSchemaPResCompAttrErr: 2807 * @ctxt: the schema validation context 2808 * @error: the error code 2809 * @ownerDes: the designation of the owner 2810 * @ownerItem: the owner as a schema object 2811 * @ownerElem: the owner as an element node 2812 * @name: the name of the attribute holding the QName 2813 * @refName: the referenced local name 2814 * @refURI: the referenced namespace URI 2815 * @message: optional message 2816 * 2817 * Used to report QName attribute values that failed to resolve 2818 * to schema components. 2819 */ 2820 static void 2821 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2822 xmlParserErrors error, 2823 xmlSchemaBasicItemPtr ownerItem, 2824 xmlNodePtr ownerElem, 2825 const char *name, 2826 const xmlChar *refName, 2827 const xmlChar *refURI, 2828 xmlSchemaTypeType refType, 2829 const char *refTypeStr) 2830 { 2831 xmlChar *des = NULL, *strA = NULL; 2832 2833 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2834 if (refTypeStr == NULL) 2835 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2836 xmlSchemaPErrExt(ctxt, ownerElem, error, 2837 NULL, NULL, NULL, 2838 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2839 "%s.\n", BAD_CAST des, BAD_CAST name, 2840 xmlSchemaFormatQName(&strA, refURI, refName), 2841 BAD_CAST refTypeStr, NULL); 2842 FREE_AND_NULL(des) 2843 FREE_AND_NULL(strA) 2844 } 2845 2846 /** 2847 * xmlSchemaPCustomAttrErr: 2848 * @ctxt: the schema parser context 2849 * @error: the error code 2850 * @ownerDes: the designation of the owner 2851 * @ownerItem: the owner as a schema object 2852 * @attr: the illegal attribute node 2853 * 2854 * Reports an illegal attribute during the parse. 2855 */ 2856 static void 2857 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2858 xmlParserErrors error, 2859 xmlChar **ownerDes, 2860 xmlSchemaBasicItemPtr ownerItem, 2861 xmlAttrPtr attr, 2862 const char *msg) 2863 { 2864 xmlChar *des = NULL; 2865 2866 if (ownerDes == NULL) 2867 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2868 else if (*ownerDes == NULL) { 2869 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2870 des = *ownerDes; 2871 } else 2872 des = *ownerDes; 2873 if (attr == NULL) { 2874 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2875 "%s, attribute '%s': %s.\n", 2876 BAD_CAST des, (const xmlChar *) "Unknown", 2877 (const xmlChar *) msg, NULL, NULL); 2878 } else { 2879 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2880 "%s, attribute '%s': %s.\n", 2881 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2882 } 2883 if (ownerDes == NULL) 2884 FREE_AND_NULL(des); 2885 } 2886 2887 /** 2888 * xmlSchemaPIllegalAttrErr: 2889 * @ctxt: the schema parser context 2890 * @error: the error code 2891 * @ownerDes: the designation of the attribute's owner 2892 * @ownerItem: the attribute's owner item 2893 * @attr: the illegal attribute node 2894 * 2895 * Reports an illegal attribute during the parse. 2896 */ 2897 static void 2898 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2899 xmlParserErrors error, 2900 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2901 xmlAttrPtr attr) 2902 { 2903 xmlChar *strA = NULL, *strB = NULL; 2904 2905 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2906 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2907 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2908 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2909 NULL, NULL); 2910 FREE_AND_NULL(strA); 2911 FREE_AND_NULL(strB); 2912 } 2913 2914 /** 2915 * xmlSchemaPCustomErr: 2916 * @ctxt: the schema parser context 2917 * @error: the error code 2918 * @itemDes: the designation of the schema item 2919 * @item: the schema item 2920 * @itemElem: the node of the schema item 2921 * @message: the error message 2922 * @str1: an optional param for the error message 2923 * @str2: an optional param for the error message 2924 * @str3: an optional param for the error message 2925 * 2926 * Reports an error during parsing. 2927 */ 2928 static void LIBXML_ATTR_FORMAT(5,0) 2929 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2930 xmlParserErrors error, 2931 xmlSchemaBasicItemPtr item, 2932 xmlNodePtr itemElem, 2933 const char *message, 2934 const xmlChar *str1, 2935 const xmlChar *str2, 2936 const xmlChar *str3) 2937 { 2938 xmlChar *des = NULL, *msg = NULL; 2939 2940 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2941 msg = xmlStrdup(BAD_CAST "%s: "); 2942 msg = xmlStrcat(msg, (const xmlChar *) message); 2943 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2944 if ((itemElem == NULL) && (item != NULL)) 2945 itemElem = WXS_ITEM_NODE(item); 2946 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2947 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2948 FREE_AND_NULL(des); 2949 FREE_AND_NULL(msg); 2950 } 2951 2952 /** 2953 * xmlSchemaPCustomErr: 2954 * @ctxt: the schema parser context 2955 * @error: the error code 2956 * @itemDes: the designation of the schema item 2957 * @item: the schema item 2958 * @itemElem: the node of the schema item 2959 * @message: the error message 2960 * @str1: the optional param for the error message 2961 * 2962 * Reports an error during parsing. 2963 */ 2964 static void LIBXML_ATTR_FORMAT(5,0) 2965 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2966 xmlParserErrors error, 2967 xmlSchemaBasicItemPtr item, 2968 xmlNodePtr itemElem, 2969 const char *message, 2970 const xmlChar *str1) 2971 { 2972 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2973 str1, NULL, NULL); 2974 } 2975 2976 /** 2977 * xmlSchemaPAttrUseErr: 2978 * @ctxt: the schema parser context 2979 * @error: the error code 2980 * @itemDes: the designation of the schema type 2981 * @item: the schema type 2982 * @itemElem: the node of the schema type 2983 * @attr: the invalid schema attribute 2984 * @message: the error message 2985 * @str1: the optional param for the error message 2986 * 2987 * Reports an attribute use error during parsing. 2988 */ 2989 static void LIBXML_ATTR_FORMAT(6,0) 2990 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 2991 xmlParserErrors error, 2992 xmlNodePtr node, 2993 xmlSchemaBasicItemPtr ownerItem, 2994 const xmlSchemaAttributeUsePtr attruse, 2995 const char *message, 2996 const xmlChar *str1, const xmlChar *str2, 2997 const xmlChar *str3,const xmlChar *str4) 2998 { 2999 xmlChar *str = NULL, *msg = NULL; 3000 3001 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 3002 msg = xmlStrcat(msg, BAD_CAST ", "); 3003 msg = xmlStrcat(msg, 3004 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 3005 WXS_BASIC_CAST attruse, NULL)); 3006 FREE_AND_NULL(str); 3007 msg = xmlStrcat(msg, BAD_CAST ": "); 3008 msg = xmlStrcat(msg, (const xmlChar *) message); 3009 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3010 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 3011 (const char *) msg, str1, str2, str3, str4); 3012 xmlFree(msg); 3013 } 3014 3015 /** 3016 * xmlSchemaPIllegalFacetAtomicErr: 3017 * @ctxt: the schema parser context 3018 * @error: the error code 3019 * @type: the schema type 3020 * @baseType: the base type of type 3021 * @facet: the illegal facet 3022 * 3023 * Reports an illegal facet for atomic simple types. 3024 */ 3025 static void 3026 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 3027 xmlParserErrors error, 3028 xmlSchemaTypePtr type, 3029 xmlSchemaTypePtr baseType, 3030 xmlSchemaFacetPtr facet) 3031 { 3032 xmlChar *des = NULL, *strT = NULL; 3033 3034 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3035 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3036 "%s: The facet '%s' is not allowed on types derived from the " 3037 "type %s.\n", 3038 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3039 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3040 NULL, NULL); 3041 FREE_AND_NULL(des); 3042 FREE_AND_NULL(strT); 3043 } 3044 3045 /** 3046 * xmlSchemaPIllegalFacetListUnionErr: 3047 * @ctxt: the schema parser context 3048 * @error: the error code 3049 * @itemDes: the designation of the schema item involved 3050 * @item: the schema item involved 3051 * @facet: the illegal facet 3052 * 3053 * Reports an illegal facet for <list> and <union>. 3054 */ 3055 static void 3056 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3057 xmlParserErrors error, 3058 xmlSchemaTypePtr type, 3059 xmlSchemaFacetPtr facet) 3060 { 3061 xmlChar *des = NULL; 3062 3063 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3064 type->node); 3065 xmlSchemaPErr(ctxt, type->node, error, 3066 "%s: The facet '%s' is not allowed.\n", 3067 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3068 FREE_AND_NULL(des); 3069 } 3070 3071 /** 3072 * xmlSchemaPMutualExclAttrErr: 3073 * @ctxt: the schema validation context 3074 * @error: the error code 3075 * @elemDes: the designation of the parent element node 3076 * @attr: the bad attribute node 3077 * @type: the corresponding type of the attribute node 3078 * 3079 * Reports an illegal attribute. 3080 */ 3081 static void 3082 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3083 xmlParserErrors error, 3084 xmlSchemaBasicItemPtr ownerItem, 3085 xmlAttrPtr attr, 3086 const char *name1, 3087 const char *name2) 3088 { 3089 xmlChar *des = NULL; 3090 3091 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3092 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3093 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3094 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3095 FREE_AND_NULL(des); 3096 } 3097 3098 /** 3099 * xmlSchemaPSimpleTypeErr: 3100 * @ctxt: the schema validation context 3101 * @error: the error code 3102 * @type: the type specifier 3103 * @ownerDes: the designation of the owner 3104 * @ownerItem: the schema object if existent 3105 * @node: the validated node 3106 * @value: the validated value 3107 * 3108 * Reports a simple type validation error. 3109 * TODO: Should this report the value of an element as well? 3110 */ 3111 static void LIBXML_ATTR_FORMAT(8,0) 3112 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3113 xmlParserErrors error, 3114 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3115 xmlNodePtr node, 3116 xmlSchemaTypePtr type, 3117 const char *expected, 3118 const xmlChar *value, 3119 const char *message, 3120 const xmlChar *str1, 3121 const xmlChar *str2) 3122 { 3123 xmlChar *msg = NULL; 3124 3125 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3126 if (message == NULL) { 3127 /* 3128 * Use default messages. 3129 */ 3130 if (type != NULL) { 3131 if (node->type == XML_ATTRIBUTE_NODE) 3132 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3133 else 3134 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3135 "valid value of "); 3136 if (! xmlSchemaIsGlobalItem(type)) 3137 msg = xmlStrcat(msg, BAD_CAST "the local "); 3138 else 3139 msg = xmlStrcat(msg, BAD_CAST "the "); 3140 3141 if (WXS_IS_ATOMIC(type)) 3142 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3143 else if (WXS_IS_LIST(type)) 3144 msg = xmlStrcat(msg, BAD_CAST "list type"); 3145 else if (WXS_IS_UNION(type)) 3146 msg = xmlStrcat(msg, BAD_CAST "union type"); 3147 3148 if (xmlSchemaIsGlobalItem(type)) { 3149 xmlChar *str = NULL; 3150 msg = xmlStrcat(msg, BAD_CAST " '"); 3151 if (type->builtInType != 0) { 3152 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3153 str = xmlStrdup(type->name); 3154 } else { 3155 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 3156 if (!str) 3157 str = xmlStrdup(qName); 3158 } 3159 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 3160 msg = xmlStrcat(msg, BAD_CAST "'."); 3161 FREE_AND_NULL(str); 3162 } 3163 } else { 3164 if (node->type == XML_ATTRIBUTE_NODE) 3165 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3166 else 3167 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3168 "valid."); 3169 } 3170 if (expected) { 3171 xmlChar *expectedEscaped = xmlCharStrdup(expected); 3172 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3173 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped)); 3174 FREE_AND_NULL(expectedEscaped); 3175 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3176 } else 3177 msg = xmlStrcat(msg, BAD_CAST "\n"); 3178 if (node->type == XML_ATTRIBUTE_NODE) 3179 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3180 else 3181 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3182 } else { 3183 msg = xmlStrcat(msg, BAD_CAST message); 3184 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3185 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3186 (const char*) msg, str1, str2, NULL, NULL, NULL); 3187 } 3188 /* Cleanup. */ 3189 FREE_AND_NULL(msg) 3190 } 3191 3192 /** 3193 * xmlSchemaPContentErr: 3194 * @ctxt: the schema parser context 3195 * @error: the error code 3196 * @onwerDes: the designation of the holder of the content 3197 * @ownerItem: the owner item of the holder of the content 3198 * @ownerElem: the node of the holder of the content 3199 * @child: the invalid child node 3200 * @message: the optional error message 3201 * @content: the optional string describing the correct content 3202 * 3203 * Reports an error concerning the content of a schema element. 3204 */ 3205 static void 3206 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3207 xmlParserErrors error, 3208 xmlSchemaBasicItemPtr ownerItem, 3209 xmlNodePtr ownerElem, 3210 xmlNodePtr child, 3211 const char *message, 3212 const char *content) 3213 { 3214 xmlChar *des = NULL; 3215 3216 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3217 if (message != NULL) 3218 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3219 "%s: %s.\n", 3220 BAD_CAST des, BAD_CAST message); 3221 else { 3222 if (content != NULL) { 3223 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3224 "%s: The content is not valid. Expected is %s.\n", 3225 BAD_CAST des, BAD_CAST content); 3226 } else { 3227 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3228 "%s: The content is not valid.\n", 3229 BAD_CAST des, NULL); 3230 } 3231 } 3232 FREE_AND_NULL(des) 3233 } 3234 3235 /************************************************************************ 3236 * * 3237 * Streamable error functions * 3238 * * 3239 ************************************************************************/ 3240 3241 3242 3243 3244 /************************************************************************ 3245 * * 3246 * Validation helper functions * 3247 * * 3248 ************************************************************************/ 3249 3250 3251 /************************************************************************ 3252 * * 3253 * Allocation functions * 3254 * * 3255 ************************************************************************/ 3256 3257 /** 3258 * xmlSchemaNewSchemaForParserCtxt: 3259 * @ctxt: a schema validation context 3260 * 3261 * Allocate a new Schema structure. 3262 * 3263 * Returns the newly allocated structure or NULL in case or error 3264 */ 3265 static xmlSchemaPtr 3266 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3267 { 3268 xmlSchemaPtr ret; 3269 3270 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3271 if (ret == NULL) { 3272 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3273 return (NULL); 3274 } 3275 memset(ret, 0, sizeof(xmlSchema)); 3276 ret->dict = ctxt->dict; 3277 xmlDictReference(ret->dict); 3278 3279 return (ret); 3280 } 3281 3282 /** 3283 * xmlSchemaNewFacet: 3284 * 3285 * Allocate a new Facet structure. 3286 * 3287 * Returns the newly allocated structure or NULL in case or error 3288 */ 3289 xmlSchemaFacetPtr 3290 xmlSchemaNewFacet(void) 3291 { 3292 xmlSchemaFacetPtr ret; 3293 3294 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3295 if (ret == NULL) { 3296 return (NULL); 3297 } 3298 memset(ret, 0, sizeof(xmlSchemaFacet)); 3299 3300 return (ret); 3301 } 3302 3303 /** 3304 * xmlSchemaNewAnnot: 3305 * @ctxt: a schema validation context 3306 * @node: a node 3307 * 3308 * Allocate a new annotation structure. 3309 * 3310 * Returns the newly allocated structure or NULL in case or error 3311 */ 3312 static xmlSchemaAnnotPtr 3313 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3314 { 3315 xmlSchemaAnnotPtr ret; 3316 3317 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3318 if (ret == NULL) { 3319 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3320 return (NULL); 3321 } 3322 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3323 ret->content = node; 3324 return (ret); 3325 } 3326 3327 static xmlSchemaItemListPtr 3328 xmlSchemaItemListCreate(void) 3329 { 3330 xmlSchemaItemListPtr ret; 3331 3332 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3333 if (ret == NULL) { 3334 xmlSchemaPErrMemory(NULL, 3335 "allocating an item list structure", NULL); 3336 return (NULL); 3337 } 3338 memset(ret, 0, sizeof(xmlSchemaItemList)); 3339 return (ret); 3340 } 3341 3342 static void 3343 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3344 { 3345 if (list->items != NULL) { 3346 xmlFree(list->items); 3347 list->items = NULL; 3348 } 3349 list->nbItems = 0; 3350 list->sizeItems = 0; 3351 } 3352 3353 static int 3354 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3355 { 3356 if (list->items == NULL) { 3357 list->items = (void **) xmlMalloc( 3358 20 * sizeof(void *)); 3359 if (list->items == NULL) { 3360 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3361 return(-1); 3362 } 3363 list->sizeItems = 20; 3364 } else if (list->sizeItems <= list->nbItems) { 3365 list->sizeItems *= 2; 3366 list->items = (void **) xmlRealloc(list->items, 3367 list->sizeItems * sizeof(void *)); 3368 if (list->items == NULL) { 3369 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3370 list->sizeItems = 0; 3371 return(-1); 3372 } 3373 } 3374 list->items[list->nbItems++] = item; 3375 return(0); 3376 } 3377 3378 static int 3379 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3380 int initialSize, 3381 void *item) 3382 { 3383 if (list->items == NULL) { 3384 if (initialSize <= 0) 3385 initialSize = 1; 3386 list->items = (void **) xmlMalloc( 3387 initialSize * sizeof(void *)); 3388 if (list->items == NULL) { 3389 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3390 return(-1); 3391 } 3392 list->sizeItems = initialSize; 3393 } else if (list->sizeItems <= list->nbItems) { 3394 list->sizeItems *= 2; 3395 list->items = (void **) xmlRealloc(list->items, 3396 list->sizeItems * sizeof(void *)); 3397 if (list->items == NULL) { 3398 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3399 list->sizeItems = 0; 3400 return(-1); 3401 } 3402 } 3403 list->items[list->nbItems++] = item; 3404 return(0); 3405 } 3406 3407 static int 3408 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3409 { 3410 if (list->items == NULL) { 3411 list->items = (void **) xmlMalloc( 3412 20 * sizeof(void *)); 3413 if (list->items == NULL) { 3414 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3415 return(-1); 3416 } 3417 list->sizeItems = 20; 3418 } else if (list->sizeItems <= list->nbItems) { 3419 list->sizeItems *= 2; 3420 list->items = (void **) xmlRealloc(list->items, 3421 list->sizeItems * sizeof(void *)); 3422 if (list->items == NULL) { 3423 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3424 list->sizeItems = 0; 3425 return(-1); 3426 } 3427 } 3428 /* 3429 * Just append if the index is greater/equal than the item count. 3430 */ 3431 if (idx >= list->nbItems) { 3432 list->items[list->nbItems++] = item; 3433 } else { 3434 int i; 3435 for (i = list->nbItems; i > idx; i--) 3436 list->items[i] = list->items[i-1]; 3437 list->items[idx] = item; 3438 list->nbItems++; 3439 } 3440 return(0); 3441 } 3442 3443 #if 0 /* enable if ever needed */ 3444 static int 3445 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3446 int initialSize, 3447 void *item, 3448 int idx) 3449 { 3450 if (list->items == NULL) { 3451 if (initialSize <= 0) 3452 initialSize = 1; 3453 list->items = (void **) xmlMalloc( 3454 initialSize * sizeof(void *)); 3455 if (list->items == NULL) { 3456 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3457 return(-1); 3458 } 3459 list->sizeItems = initialSize; 3460 } else if (list->sizeItems <= list->nbItems) { 3461 list->sizeItems *= 2; 3462 list->items = (void **) xmlRealloc(list->items, 3463 list->sizeItems * sizeof(void *)); 3464 if (list->items == NULL) { 3465 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3466 list->sizeItems = 0; 3467 return(-1); 3468 } 3469 } 3470 /* 3471 * Just append if the index is greater/equal than the item count. 3472 */ 3473 if (idx >= list->nbItems) { 3474 list->items[list->nbItems++] = item; 3475 } else { 3476 int i; 3477 for (i = list->nbItems; i > idx; i--) 3478 list->items[i] = list->items[i-1]; 3479 list->items[idx] = item; 3480 list->nbItems++; 3481 } 3482 return(0); 3483 } 3484 #endif 3485 3486 static int 3487 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3488 { 3489 int i; 3490 if ((list->items == NULL) || (idx >= list->nbItems)) { 3491 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3492 "index error.\n"); 3493 return(-1); 3494 } 3495 3496 if (list->nbItems == 1) { 3497 /* TODO: Really free the list? */ 3498 xmlFree(list->items); 3499 list->items = NULL; 3500 list->nbItems = 0; 3501 list->sizeItems = 0; 3502 } else if (list->nbItems -1 == idx) { 3503 list->nbItems--; 3504 } else { 3505 for (i = idx; i < list->nbItems -1; i++) 3506 list->items[i] = list->items[i+1]; 3507 list->nbItems--; 3508 } 3509 return(0); 3510 } 3511 3512 /** 3513 * xmlSchemaItemListFree: 3514 * @annot: a schema type structure 3515 * 3516 * Deallocate a annotation structure 3517 */ 3518 static void 3519 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3520 { 3521 if (list == NULL) 3522 return; 3523 if (list->items != NULL) 3524 xmlFree(list->items); 3525 xmlFree(list); 3526 } 3527 3528 static void 3529 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3530 { 3531 if (bucket == NULL) 3532 return; 3533 if (bucket->globals != NULL) { 3534 xmlSchemaComponentListFree(bucket->globals); 3535 xmlSchemaItemListFree(bucket->globals); 3536 } 3537 if (bucket->locals != NULL) { 3538 xmlSchemaComponentListFree(bucket->locals); 3539 xmlSchemaItemListFree(bucket->locals); 3540 } 3541 if (bucket->relations != NULL) { 3542 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3543 do { 3544 prev = cur; 3545 cur = cur->next; 3546 xmlFree(prev); 3547 } while (cur != NULL); 3548 } 3549 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3550 xmlFreeDoc(bucket->doc); 3551 } 3552 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3553 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3554 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3555 } 3556 xmlFree(bucket); 3557 } 3558 3559 static xmlSchemaBucketPtr 3560 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3561 int type, const xmlChar *targetNamespace) 3562 { 3563 xmlSchemaBucketPtr ret; 3564 int size; 3565 xmlSchemaPtr mainSchema; 3566 3567 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3568 PERROR_INT("xmlSchemaBucketCreate", 3569 "no main schema on constructor"); 3570 return(NULL); 3571 } 3572 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3573 /* Create the schema bucket. */ 3574 if (WXS_IS_BUCKET_INCREDEF(type)) 3575 size = sizeof(xmlSchemaInclude); 3576 else 3577 size = sizeof(xmlSchemaImport); 3578 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3579 if (ret == NULL) { 3580 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3581 return(NULL); 3582 } 3583 memset(ret, 0, size); 3584 ret->targetNamespace = targetNamespace; 3585 ret->type = type; 3586 ret->globals = xmlSchemaItemListCreate(); 3587 if (ret->globals == NULL) { 3588 xmlFree(ret); 3589 return(NULL); 3590 } 3591 ret->locals = xmlSchemaItemListCreate(); 3592 if (ret->locals == NULL) { 3593 xmlFree(ret); 3594 return(NULL); 3595 } 3596 /* 3597 * The following will assure that only the first bucket is marked as 3598 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3599 * For each following import buckets an xmlSchema will be created. 3600 * An xmlSchema will be created for every distinct targetNamespace. 3601 * We assign the targetNamespace to the schemata here. 3602 */ 3603 if (! WXS_HAS_BUCKETS(pctxt)) { 3604 if (WXS_IS_BUCKET_INCREDEF(type)) { 3605 PERROR_INT("xmlSchemaBucketCreate", 3606 "first bucket but it's an include or redefine"); 3607 xmlSchemaBucketFree(ret); 3608 return(NULL); 3609 } 3610 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3611 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3612 /* Point to the *main* schema. */ 3613 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3614 WXS_IMPBUCKET(ret)->schema = mainSchema; 3615 /* 3616 * Ensure that the main schema gets a targetNamespace. 3617 */ 3618 mainSchema->targetNamespace = targetNamespace; 3619 } else { 3620 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3621 PERROR_INT("xmlSchemaBucketCreate", 3622 "main bucket but it's not the first one"); 3623 xmlSchemaBucketFree(ret); 3624 return(NULL); 3625 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3626 /* 3627 * Create a schema for imports and assign the 3628 * targetNamespace. 3629 */ 3630 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3631 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3632 xmlSchemaBucketFree(ret); 3633 return(NULL); 3634 } 3635 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3636 } 3637 } 3638 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3639 int res; 3640 /* 3641 * Imports go into the "schemasImports" slot of the main *schema*. 3642 * Note that we create an import entry for the main schema as well; i.e., 3643 * even if there's only one schema, we'll get an import. 3644 */ 3645 if (mainSchema->schemasImports == NULL) { 3646 mainSchema->schemasImports = xmlHashCreateDict(5, 3647 WXS_CONSTRUCTOR(pctxt)->dict); 3648 if (mainSchema->schemasImports == NULL) { 3649 xmlSchemaBucketFree(ret); 3650 return(NULL); 3651 } 3652 } 3653 if (targetNamespace == NULL) 3654 res = xmlHashAddEntry(mainSchema->schemasImports, 3655 XML_SCHEMAS_NO_NAMESPACE, ret); 3656 else 3657 res = xmlHashAddEntry(mainSchema->schemasImports, 3658 targetNamespace, ret); 3659 if (res != 0) { 3660 PERROR_INT("xmlSchemaBucketCreate", 3661 "failed to add the schema bucket to the hash"); 3662 xmlSchemaBucketFree(ret); 3663 return(NULL); 3664 } 3665 } else { 3666 /* Set the @ownerImport of an include bucket. */ 3667 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3668 WXS_INCBUCKET(ret)->ownerImport = 3669 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3670 else 3671 WXS_INCBUCKET(ret)->ownerImport = 3672 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3673 3674 /* Includes got into the "includes" slot of the *main* schema. */ 3675 if (mainSchema->includes == NULL) { 3676 mainSchema->includes = xmlSchemaItemListCreate(); 3677 if (mainSchema->includes == NULL) { 3678 xmlSchemaBucketFree(ret); 3679 return(NULL); 3680 } 3681 } 3682 xmlSchemaItemListAdd(mainSchema->includes, ret); 3683 } 3684 /* 3685 * Add to list of all buckets; this is used for lookup 3686 * during schema construction time only. 3687 */ 3688 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3689 return(NULL); 3690 return(ret); 3691 } 3692 3693 static int 3694 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3695 { 3696 if (*list == NULL) { 3697 *list = xmlSchemaItemListCreate(); 3698 if (*list == NULL) 3699 return(-1); 3700 } 3701 xmlSchemaItemListAddSize(*list, initialSize, item); 3702 return(0); 3703 } 3704 3705 /** 3706 * xmlSchemaFreeAnnot: 3707 * @annot: a schema type structure 3708 * 3709 * Deallocate a annotation structure 3710 */ 3711 static void 3712 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3713 { 3714 if (annot == NULL) 3715 return; 3716 if (annot->next == NULL) { 3717 xmlFree(annot); 3718 } else { 3719 xmlSchemaAnnotPtr prev; 3720 3721 do { 3722 prev = annot; 3723 annot = annot->next; 3724 xmlFree(prev); 3725 } while (annot != NULL); 3726 } 3727 } 3728 3729 /** 3730 * xmlSchemaFreeNotation: 3731 * @schema: a schema notation structure 3732 * 3733 * Deallocate a Schema Notation structure. 3734 */ 3735 static void 3736 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3737 { 3738 if (nota == NULL) 3739 return; 3740 xmlFree(nota); 3741 } 3742 3743 /** 3744 * xmlSchemaFreeAttribute: 3745 * @attr: an attribute declaration 3746 * 3747 * Deallocates an attribute declaration structure. 3748 */ 3749 static void 3750 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3751 { 3752 if (attr == NULL) 3753 return; 3754 if (attr->annot != NULL) 3755 xmlSchemaFreeAnnot(attr->annot); 3756 if (attr->defVal != NULL) 3757 xmlSchemaFreeValue(attr->defVal); 3758 xmlFree(attr); 3759 } 3760 3761 /** 3762 * xmlSchemaFreeAttributeUse: 3763 * @use: an attribute use 3764 * 3765 * Deallocates an attribute use structure. 3766 */ 3767 static void 3768 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3769 { 3770 if (use == NULL) 3771 return; 3772 if (use->annot != NULL) 3773 xmlSchemaFreeAnnot(use->annot); 3774 if (use->defVal != NULL) 3775 xmlSchemaFreeValue(use->defVal); 3776 xmlFree(use); 3777 } 3778 3779 /** 3780 * xmlSchemaFreeAttributeUseProhib: 3781 * @prohib: an attribute use prohibition 3782 * 3783 * Deallocates an attribute use structure. 3784 */ 3785 static void 3786 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3787 { 3788 if (prohib == NULL) 3789 return; 3790 xmlFree(prohib); 3791 } 3792 3793 /** 3794 * xmlSchemaFreeWildcardNsSet: 3795 * set: a schema wildcard namespace 3796 * 3797 * Deallocates a list of wildcard constraint structures. 3798 */ 3799 static void 3800 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3801 { 3802 xmlSchemaWildcardNsPtr next; 3803 3804 while (set != NULL) { 3805 next = set->next; 3806 xmlFree(set); 3807 set = next; 3808 } 3809 } 3810 3811 /** 3812 * xmlSchemaFreeWildcard: 3813 * @wildcard: a wildcard structure 3814 * 3815 * Deallocates a wildcard structure. 3816 */ 3817 void 3818 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3819 { 3820 if (wildcard == NULL) 3821 return; 3822 if (wildcard->annot != NULL) 3823 xmlSchemaFreeAnnot(wildcard->annot); 3824 if (wildcard->nsSet != NULL) 3825 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3826 if (wildcard->negNsSet != NULL) 3827 xmlFree(wildcard->negNsSet); 3828 xmlFree(wildcard); 3829 } 3830 3831 /** 3832 * xmlSchemaFreeAttributeGroup: 3833 * @schema: a schema attribute group structure 3834 * 3835 * Deallocate a Schema Attribute Group structure. 3836 */ 3837 static void 3838 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3839 { 3840 if (attrGr == NULL) 3841 return; 3842 if (attrGr->annot != NULL) 3843 xmlSchemaFreeAnnot(attrGr->annot); 3844 if (attrGr->attrUses != NULL) 3845 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3846 xmlFree(attrGr); 3847 } 3848 3849 /** 3850 * xmlSchemaFreeQNameRef: 3851 * @item: a QName reference structure 3852 * 3853 * Deallocatea a QName reference structure. 3854 */ 3855 static void 3856 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3857 { 3858 xmlFree(item); 3859 } 3860 3861 /** 3862 * xmlSchemaFreeTypeLinkList: 3863 * @alink: a type link 3864 * 3865 * Deallocate a list of types. 3866 */ 3867 static void 3868 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3869 { 3870 xmlSchemaTypeLinkPtr next; 3871 3872 while (link != NULL) { 3873 next = link->next; 3874 xmlFree(link); 3875 link = next; 3876 } 3877 } 3878 3879 static void 3880 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3881 { 3882 xmlSchemaIDCStateObjPtr next; 3883 while (sto != NULL) { 3884 next = sto->next; 3885 if (sto->history != NULL) 3886 xmlFree(sto->history); 3887 if (sto->xpathCtxt != NULL) 3888 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3889 xmlFree(sto); 3890 sto = next; 3891 } 3892 } 3893 3894 /** 3895 * xmlSchemaFreeIDC: 3896 * @idc: a identity-constraint definition 3897 * 3898 * Deallocates an identity-constraint definition. 3899 */ 3900 static void 3901 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3902 { 3903 xmlSchemaIDCSelectPtr cur, prev; 3904 3905 if (idcDef == NULL) 3906 return; 3907 if (idcDef->annot != NULL) 3908 xmlSchemaFreeAnnot(idcDef->annot); 3909 /* Selector */ 3910 if (idcDef->selector != NULL) { 3911 if (idcDef->selector->xpathComp != NULL) 3912 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3913 xmlFree(idcDef->selector); 3914 } 3915 /* Fields */ 3916 if (idcDef->fields != NULL) { 3917 cur = idcDef->fields; 3918 do { 3919 prev = cur; 3920 cur = cur->next; 3921 if (prev->xpathComp != NULL) 3922 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3923 xmlFree(prev); 3924 } while (cur != NULL); 3925 } 3926 xmlFree(idcDef); 3927 } 3928 3929 /** 3930 * xmlSchemaFreeElement: 3931 * @schema: a schema element structure 3932 * 3933 * Deallocate a Schema Element structure. 3934 */ 3935 static void 3936 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3937 { 3938 if (elem == NULL) 3939 return; 3940 if (elem->annot != NULL) 3941 xmlSchemaFreeAnnot(elem->annot); 3942 if (elem->contModel != NULL) 3943 xmlRegFreeRegexp(elem->contModel); 3944 if (elem->defVal != NULL) 3945 xmlSchemaFreeValue(elem->defVal); 3946 xmlFree(elem); 3947 } 3948 3949 /** 3950 * xmlSchemaFreeFacet: 3951 * @facet: a schema facet structure 3952 * 3953 * Deallocate a Schema Facet structure. 3954 */ 3955 void 3956 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3957 { 3958 if (facet == NULL) 3959 return; 3960 if (facet->val != NULL) 3961 xmlSchemaFreeValue(facet->val); 3962 if (facet->regexp != NULL) 3963 xmlRegFreeRegexp(facet->regexp); 3964 if (facet->annot != NULL) 3965 xmlSchemaFreeAnnot(facet->annot); 3966 xmlFree(facet); 3967 } 3968 3969 /** 3970 * xmlSchemaFreeType: 3971 * @type: a schema type structure 3972 * 3973 * Deallocate a Schema Type structure. 3974 */ 3975 void 3976 xmlSchemaFreeType(xmlSchemaTypePtr type) 3977 { 3978 if (type == NULL) 3979 return; 3980 if (type->annot != NULL) 3981 xmlSchemaFreeAnnot(type->annot); 3982 if (type->facets != NULL) { 3983 xmlSchemaFacetPtr facet, next; 3984 3985 facet = type->facets; 3986 while (facet != NULL) { 3987 next = facet->next; 3988 xmlSchemaFreeFacet(facet); 3989 facet = next; 3990 } 3991 } 3992 if (type->attrUses != NULL) 3993 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 3994 if (type->memberTypes != NULL) 3995 xmlSchemaFreeTypeLinkList(type->memberTypes); 3996 if (type->facetSet != NULL) { 3997 xmlSchemaFacetLinkPtr next, link; 3998 3999 link = type->facetSet; 4000 do { 4001 next = link->next; 4002 xmlFree(link); 4003 link = next; 4004 } while (link != NULL); 4005 } 4006 if (type->contModel != NULL) 4007 xmlRegFreeRegexp(type->contModel); 4008 xmlFree(type); 4009 } 4010 4011 /** 4012 * xmlSchemaFreeModelGroupDef: 4013 * @item: a schema model group definition 4014 * 4015 * Deallocates a schema model group definition. 4016 */ 4017 static void 4018 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 4019 { 4020 if (item->annot != NULL) 4021 xmlSchemaFreeAnnot(item->annot); 4022 xmlFree(item); 4023 } 4024 4025 /** 4026 * xmlSchemaFreeModelGroup: 4027 * @item: a schema model group 4028 * 4029 * Deallocates a schema model group structure. 4030 */ 4031 static void 4032 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 4033 { 4034 if (item->annot != NULL) 4035 xmlSchemaFreeAnnot(item->annot); 4036 xmlFree(item); 4037 } 4038 4039 static void 4040 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4041 { 4042 if ((list == NULL) || (list->nbItems == 0)) 4043 return; 4044 { 4045 xmlSchemaTreeItemPtr item; 4046 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4047 int i; 4048 4049 for (i = 0; i < list->nbItems; i++) { 4050 item = items[i]; 4051 if (item == NULL) 4052 continue; 4053 switch (item->type) { 4054 case XML_SCHEMA_TYPE_SIMPLE: 4055 case XML_SCHEMA_TYPE_COMPLEX: 4056 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4057 break; 4058 case XML_SCHEMA_TYPE_ATTRIBUTE: 4059 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4060 break; 4061 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4062 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4063 break; 4064 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4065 xmlSchemaFreeAttributeUseProhib( 4066 (xmlSchemaAttributeUseProhibPtr) item); 4067 break; 4068 case XML_SCHEMA_TYPE_ELEMENT: 4069 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4070 break; 4071 case XML_SCHEMA_TYPE_PARTICLE: 4072 if (item->annot != NULL) 4073 xmlSchemaFreeAnnot(item->annot); 4074 xmlFree(item); 4075 break; 4076 case XML_SCHEMA_TYPE_SEQUENCE: 4077 case XML_SCHEMA_TYPE_CHOICE: 4078 case XML_SCHEMA_TYPE_ALL: 4079 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4080 break; 4081 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4082 xmlSchemaFreeAttributeGroup( 4083 (xmlSchemaAttributeGroupPtr) item); 4084 break; 4085 case XML_SCHEMA_TYPE_GROUP: 4086 xmlSchemaFreeModelGroupDef( 4087 (xmlSchemaModelGroupDefPtr) item); 4088 break; 4089 case XML_SCHEMA_TYPE_ANY: 4090 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4091 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4092 break; 4093 case XML_SCHEMA_TYPE_IDC_KEY: 4094 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4095 case XML_SCHEMA_TYPE_IDC_KEYREF: 4096 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4097 break; 4098 case XML_SCHEMA_TYPE_NOTATION: 4099 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4100 break; 4101 case XML_SCHEMA_EXTRA_QNAMEREF: 4102 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4103 break; 4104 default: { 4105 /* TODO: This should never be hit. */ 4106 xmlSchemaPSimpleInternalErr(NULL, 4107 "Internal error: xmlSchemaComponentListFree, " 4108 "unexpected component type '%s'\n", 4109 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4110 } 4111 break; 4112 } 4113 } 4114 list->nbItems = 0; 4115 } 4116 } 4117 4118 /** 4119 * xmlSchemaFree: 4120 * @schema: a schema structure 4121 * 4122 * Deallocate a Schema structure. 4123 */ 4124 void 4125 xmlSchemaFree(xmlSchemaPtr schema) 4126 { 4127 if (schema == NULL) 4128 return; 4129 /* @volatiles is not used anymore :-/ */ 4130 if (schema->volatiles != NULL) 4131 TODO 4132 /* 4133 * Note that those slots are not responsible for freeing 4134 * schema components anymore; this will now be done by 4135 * the schema buckets. 4136 */ 4137 if (schema->notaDecl != NULL) 4138 xmlHashFree(schema->notaDecl, NULL); 4139 if (schema->attrDecl != NULL) 4140 xmlHashFree(schema->attrDecl, NULL); 4141 if (schema->attrgrpDecl != NULL) 4142 xmlHashFree(schema->attrgrpDecl, NULL); 4143 if (schema->elemDecl != NULL) 4144 xmlHashFree(schema->elemDecl, NULL); 4145 if (schema->typeDecl != NULL) 4146 xmlHashFree(schema->typeDecl, NULL); 4147 if (schema->groupDecl != NULL) 4148 xmlHashFree(schema->groupDecl, NULL); 4149 if (schema->idcDef != NULL) 4150 xmlHashFree(schema->idcDef, NULL); 4151 4152 if (schema->schemasImports != NULL) 4153 xmlHashFree(schema->schemasImports, 4154 (xmlHashDeallocator) xmlSchemaBucketFree); 4155 if (schema->includes != NULL) { 4156 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4157 int i; 4158 for (i = 0; i < list->nbItems; i++) { 4159 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4160 } 4161 xmlSchemaItemListFree(list); 4162 } 4163 if (schema->annot != NULL) 4164 xmlSchemaFreeAnnot(schema->annot); 4165 /* Never free the doc here, since this will be done by the buckets. */ 4166 4167 xmlDictFree(schema->dict); 4168 xmlFree(schema); 4169 } 4170 4171 /************************************************************************ 4172 * * 4173 * Debug functions * 4174 * * 4175 ************************************************************************/ 4176 4177 #ifdef LIBXML_OUTPUT_ENABLED 4178 4179 static void 4180 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4181 4182 /** 4183 * xmlSchemaElementDump: 4184 * @elem: an element 4185 * @output: the file output 4186 * 4187 * Dump the element 4188 */ 4189 static void 4190 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, 4191 const xmlChar * name ATTRIBUTE_UNUSED, 4192 const xmlChar * namespace ATTRIBUTE_UNUSED, 4193 const xmlChar * context ATTRIBUTE_UNUSED) 4194 { 4195 if (elem == NULL) 4196 return; 4197 4198 4199 fprintf(output, "Element"); 4200 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4201 fprintf(output, " (global)"); 4202 fprintf(output, ": '%s' ", elem->name); 4203 if (namespace != NULL) 4204 fprintf(output, "ns '%s'", namespace); 4205 fprintf(output, "\n"); 4206 #if 0 4207 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4208 fprintf(output, " min %d ", elem->minOccurs); 4209 if (elem->maxOccurs >= UNBOUNDED) 4210 fprintf(output, "max: unbounded\n"); 4211 else if (elem->maxOccurs != 1) 4212 fprintf(output, "max: %d\n", elem->maxOccurs); 4213 else 4214 fprintf(output, "\n"); 4215 } 4216 #endif 4217 /* 4218 * Misc other properties. 4219 */ 4220 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4221 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4222 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4223 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4224 fprintf(output, " props: "); 4225 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4226 fprintf(output, "[fixed] "); 4227 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4228 fprintf(output, "[default] "); 4229 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4230 fprintf(output, "[abstract] "); 4231 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4232 fprintf(output, "[nillable] "); 4233 fprintf(output, "\n"); 4234 } 4235 /* 4236 * Default/fixed value. 4237 */ 4238 if (elem->value != NULL) 4239 fprintf(output, " value: '%s'\n", elem->value); 4240 /* 4241 * Type. 4242 */ 4243 if (elem->namedType != NULL) { 4244 fprintf(output, " type: '%s' ", elem->namedType); 4245 if (elem->namedTypeNs != NULL) 4246 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4247 else 4248 fprintf(output, "\n"); 4249 } else if (elem->subtypes != NULL) { 4250 /* 4251 * Dump local types. 4252 */ 4253 xmlSchemaTypeDump(elem->subtypes, output); 4254 } 4255 /* 4256 * Substitution group. 4257 */ 4258 if (elem->substGroup != NULL) { 4259 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4260 if (elem->substGroupNs != NULL) 4261 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4262 else 4263 fprintf(output, "\n"); 4264 } 4265 } 4266 4267 /** 4268 * xmlSchemaAnnotDump: 4269 * @output: the file output 4270 * @annot: a annotation 4271 * 4272 * Dump the annotation 4273 */ 4274 static void 4275 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4276 { 4277 xmlChar *content; 4278 4279 if (annot == NULL) 4280 return; 4281 4282 content = xmlNodeGetContent(annot->content); 4283 if (content != NULL) { 4284 fprintf(output, " Annot: %s\n", content); 4285 xmlFree(content); 4286 } else 4287 fprintf(output, " Annot: empty\n"); 4288 } 4289 4290 /** 4291 * xmlSchemaContentModelDump: 4292 * @particle: the schema particle 4293 * @output: the file output 4294 * @depth: the depth used for intentation 4295 * 4296 * Dump a SchemaType structure 4297 */ 4298 static void 4299 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4300 { 4301 xmlChar *str = NULL; 4302 xmlSchemaTreeItemPtr term; 4303 char shift[100]; 4304 int i; 4305 4306 if (particle == NULL) 4307 return; 4308 for (i = 0;((i < depth) && (i < 25));i++) 4309 shift[2 * i] = shift[2 * i + 1] = ' '; 4310 shift[2 * i] = shift[2 * i + 1] = 0; 4311 fprintf(output, "%s", shift); 4312 if (particle->children == NULL) { 4313 fprintf(output, "MISSING particle term\n"); 4314 return; 4315 } 4316 term = particle->children; 4317 if (term == NULL) { 4318 fprintf(output, "(NULL)"); 4319 } else { 4320 switch (term->type) { 4321 case XML_SCHEMA_TYPE_ELEMENT: 4322 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4323 ((xmlSchemaElementPtr)term)->targetNamespace, 4324 ((xmlSchemaElementPtr)term)->name)); 4325 FREE_AND_NULL(str); 4326 break; 4327 case XML_SCHEMA_TYPE_SEQUENCE: 4328 fprintf(output, "SEQUENCE"); 4329 break; 4330 case XML_SCHEMA_TYPE_CHOICE: 4331 fprintf(output, "CHOICE"); 4332 break; 4333 case XML_SCHEMA_TYPE_ALL: 4334 fprintf(output, "ALL"); 4335 break; 4336 case XML_SCHEMA_TYPE_ANY: 4337 fprintf(output, "ANY"); 4338 break; 4339 default: 4340 fprintf(output, "UNKNOWN\n"); 4341 return; 4342 } 4343 } 4344 if (particle->minOccurs != 1) 4345 fprintf(output, " min: %d", particle->minOccurs); 4346 if (particle->maxOccurs >= UNBOUNDED) 4347 fprintf(output, " max: unbounded"); 4348 else if (particle->maxOccurs != 1) 4349 fprintf(output, " max: %d", particle->maxOccurs); 4350 fprintf(output, "\n"); 4351 if (term && 4352 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4353 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4354 (term->type == XML_SCHEMA_TYPE_ALL)) && 4355 (term->children != NULL)) { 4356 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4357 output, depth +1); 4358 } 4359 if (particle->next != NULL) 4360 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4361 output, depth); 4362 } 4363 4364 /** 4365 * xmlSchemaAttrUsesDump: 4366 * @uses: attribute uses list 4367 * @output: the file output 4368 * 4369 * Dumps a list of attribute use components. 4370 */ 4371 static void 4372 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4373 { 4374 xmlSchemaAttributeUsePtr use; 4375 xmlSchemaAttributeUseProhibPtr prohib; 4376 xmlSchemaQNameRefPtr ref; 4377 const xmlChar *name, *tns; 4378 xmlChar *str = NULL; 4379 int i; 4380 4381 if ((uses == NULL) || (uses->nbItems == 0)) 4382 return; 4383 4384 fprintf(output, " attributes:\n"); 4385 for (i = 0; i < uses->nbItems; i++) { 4386 use = uses->items[i]; 4387 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4388 fprintf(output, " [prohibition] "); 4389 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4390 name = prohib->name; 4391 tns = prohib->targetNamespace; 4392 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4393 fprintf(output, " [reference] "); 4394 ref = (xmlSchemaQNameRefPtr) use; 4395 name = ref->name; 4396 tns = ref->targetNamespace; 4397 } else { 4398 fprintf(output, " [use] "); 4399 name = WXS_ATTRUSE_DECL_NAME(use); 4400 tns = WXS_ATTRUSE_DECL_TNS(use); 4401 } 4402 fprintf(output, "'%s'\n", 4403 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4404 FREE_AND_NULL(str); 4405 } 4406 } 4407 4408 /** 4409 * xmlSchemaTypeDump: 4410 * @output: the file output 4411 * @type: a type structure 4412 * 4413 * Dump a SchemaType structure 4414 */ 4415 static void 4416 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4417 { 4418 if (type == NULL) { 4419 fprintf(output, "Type: NULL\n"); 4420 return; 4421 } 4422 fprintf(output, "Type: "); 4423 if (type->name != NULL) 4424 fprintf(output, "'%s' ", type->name); 4425 else 4426 fprintf(output, "(no name) "); 4427 if (type->targetNamespace != NULL) 4428 fprintf(output, "ns '%s' ", type->targetNamespace); 4429 switch (type->type) { 4430 case XML_SCHEMA_TYPE_BASIC: 4431 fprintf(output, "[basic] "); 4432 break; 4433 case XML_SCHEMA_TYPE_SIMPLE: 4434 fprintf(output, "[simple] "); 4435 break; 4436 case XML_SCHEMA_TYPE_COMPLEX: 4437 fprintf(output, "[complex] "); 4438 break; 4439 case XML_SCHEMA_TYPE_SEQUENCE: 4440 fprintf(output, "[sequence] "); 4441 break; 4442 case XML_SCHEMA_TYPE_CHOICE: 4443 fprintf(output, "[choice] "); 4444 break; 4445 case XML_SCHEMA_TYPE_ALL: 4446 fprintf(output, "[all] "); 4447 break; 4448 case XML_SCHEMA_TYPE_UR: 4449 fprintf(output, "[ur] "); 4450 break; 4451 case XML_SCHEMA_TYPE_RESTRICTION: 4452 fprintf(output, "[restriction] "); 4453 break; 4454 case XML_SCHEMA_TYPE_EXTENSION: 4455 fprintf(output, "[extension] "); 4456 break; 4457 default: 4458 fprintf(output, "[unknown type %d] ", type->type); 4459 break; 4460 } 4461 fprintf(output, "content: "); 4462 switch (type->contentType) { 4463 case XML_SCHEMA_CONTENT_UNKNOWN: 4464 fprintf(output, "[unknown] "); 4465 break; 4466 case XML_SCHEMA_CONTENT_EMPTY: 4467 fprintf(output, "[empty] "); 4468 break; 4469 case XML_SCHEMA_CONTENT_ELEMENTS: 4470 fprintf(output, "[element] "); 4471 break; 4472 case XML_SCHEMA_CONTENT_MIXED: 4473 fprintf(output, "[mixed] "); 4474 break; 4475 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4476 /* not used. */ 4477 break; 4478 case XML_SCHEMA_CONTENT_BASIC: 4479 fprintf(output, "[basic] "); 4480 break; 4481 case XML_SCHEMA_CONTENT_SIMPLE: 4482 fprintf(output, "[simple] "); 4483 break; 4484 case XML_SCHEMA_CONTENT_ANY: 4485 fprintf(output, "[any] "); 4486 break; 4487 } 4488 fprintf(output, "\n"); 4489 if (type->base != NULL) { 4490 fprintf(output, " base type: '%s'", type->base); 4491 if (type->baseNs != NULL) 4492 fprintf(output, " ns '%s'\n", type->baseNs); 4493 else 4494 fprintf(output, "\n"); 4495 } 4496 if (type->attrUses != NULL) 4497 xmlSchemaAttrUsesDump(type->attrUses, output); 4498 if (type->annot != NULL) 4499 xmlSchemaAnnotDump(output, type->annot); 4500 #ifdef DUMP_CONTENT_MODEL 4501 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4502 (type->subtypes != NULL)) { 4503 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4504 output, 1); 4505 } 4506 #endif 4507 } 4508 4509 /** 4510 * xmlSchemaDump: 4511 * @output: the file output 4512 * @schema: a schema structure 4513 * 4514 * Dump a Schema structure. 4515 */ 4516 void 4517 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4518 { 4519 if (output == NULL) 4520 return; 4521 if (schema == NULL) { 4522 fprintf(output, "Schemas: NULL\n"); 4523 return; 4524 } 4525 fprintf(output, "Schemas: "); 4526 if (schema->name != NULL) 4527 fprintf(output, "%s, ", schema->name); 4528 else 4529 fprintf(output, "no name, "); 4530 if (schema->targetNamespace != NULL) 4531 fprintf(output, "%s", (const char *) schema->targetNamespace); 4532 else 4533 fprintf(output, "no target namespace"); 4534 fprintf(output, "\n"); 4535 if (schema->annot != NULL) 4536 xmlSchemaAnnotDump(output, schema->annot); 4537 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, 4538 output); 4539 xmlHashScanFull(schema->elemDecl, 4540 (xmlHashScannerFull) xmlSchemaElementDump, output); 4541 } 4542 4543 #ifdef DEBUG_IDC_NODE_TABLE 4544 /** 4545 * xmlSchemaDebugDumpIDCTable: 4546 * @vctxt: the WXS validation context 4547 * 4548 * Displays the current IDC table for debug purposes. 4549 */ 4550 static void 4551 xmlSchemaDebugDumpIDCTable(FILE * output, 4552 const xmlChar *namespaceName, 4553 const xmlChar *localName, 4554 xmlSchemaPSVIIDCBindingPtr bind) 4555 { 4556 xmlChar *str = NULL; 4557 const xmlChar *value; 4558 xmlSchemaPSVIIDCNodePtr tab; 4559 xmlSchemaPSVIIDCKeyPtr key; 4560 int i, j, res; 4561 4562 fprintf(output, "IDC: TABLES on '%s'\n", 4563 xmlSchemaFormatQName(&str, namespaceName, localName)); 4564 FREE_AND_NULL(str) 4565 4566 if (bind == NULL) 4567 return; 4568 do { 4569 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4570 xmlSchemaGetComponentQName(&str, 4571 bind->definition), bind->nbNodes); 4572 FREE_AND_NULL(str) 4573 for (i = 0; i < bind->nbNodes; i++) { 4574 tab = bind->nodeTable[i]; 4575 fprintf(output, " ( "); 4576 for (j = 0; j < bind->definition->nbFields; j++) { 4577 key = tab->keys[j]; 4578 if ((key != NULL) && (key->val != NULL)) { 4579 res = xmlSchemaGetCanonValue(key->val, &value); 4580 if (res >= 0) 4581 fprintf(output, "'%s' ", value); 4582 else 4583 fprintf(output, "CANON-VALUE-FAILED "); 4584 if (res == 0) 4585 FREE_AND_NULL(value) 4586 } else if (key != NULL) 4587 fprintf(output, "(no val), "); 4588 else 4589 fprintf(output, "(key missing), "); 4590 } 4591 fprintf(output, ")\n"); 4592 } 4593 if (bind->dupls && bind->dupls->nbItems) { 4594 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4595 for (i = 0; i < bind->dupls->nbItems; i++) { 4596 tab = bind->dupls->items[i]; 4597 fprintf(output, " ( "); 4598 for (j = 0; j < bind->definition->nbFields; j++) { 4599 key = tab->keys[j]; 4600 if ((key != NULL) && (key->val != NULL)) { 4601 res = xmlSchemaGetCanonValue(key->val, &value); 4602 if (res >= 0) 4603 fprintf(output, "'%s' ", value); 4604 else 4605 fprintf(output, "CANON-VALUE-FAILED "); 4606 if (res == 0) 4607 FREE_AND_NULL(value) 4608 } else if (key != NULL) 4609 fprintf(output, "(no val), "); 4610 else 4611 fprintf(output, "(key missing), "); 4612 } 4613 fprintf(output, ")\n"); 4614 } 4615 } 4616 bind = bind->next; 4617 } while (bind != NULL); 4618 } 4619 #endif /* DEBUG_IDC */ 4620 #endif /* LIBXML_OUTPUT_ENABLED */ 4621 4622 /************************************************************************ 4623 * * 4624 * Utilities * 4625 * * 4626 ************************************************************************/ 4627 4628 /** 4629 * xmlSchemaGetPropNode: 4630 * @node: the element node 4631 * @name: the name of the attribute 4632 * 4633 * Seeks an attribute with a name of @name in 4634 * no namespace. 4635 * 4636 * Returns the attribute or NULL if not present. 4637 */ 4638 static xmlAttrPtr 4639 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4640 { 4641 xmlAttrPtr prop; 4642 4643 if ((node == NULL) || (name == NULL)) 4644 return(NULL); 4645 prop = node->properties; 4646 while (prop != NULL) { 4647 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4648 return(prop); 4649 prop = prop->next; 4650 } 4651 return (NULL); 4652 } 4653 4654 /** 4655 * xmlSchemaGetPropNodeNs: 4656 * @node: the element node 4657 * @uri: the uri 4658 * @name: the name of the attribute 4659 * 4660 * Seeks an attribute with a local name of @name and 4661 * a namespace URI of @uri. 4662 * 4663 * Returns the attribute or NULL if not present. 4664 */ 4665 static xmlAttrPtr 4666 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4667 { 4668 xmlAttrPtr prop; 4669 4670 if ((node == NULL) || (name == NULL)) 4671 return(NULL); 4672 prop = node->properties; 4673 while (prop != NULL) { 4674 if ((prop->ns != NULL) && 4675 xmlStrEqual(prop->name, BAD_CAST name) && 4676 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4677 return(prop); 4678 prop = prop->next; 4679 } 4680 return (NULL); 4681 } 4682 4683 static const xmlChar * 4684 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4685 { 4686 xmlChar *val; 4687 const xmlChar *ret; 4688 4689 val = xmlNodeGetContent(node); 4690 if (val == NULL) 4691 val = xmlStrdup((xmlChar *)""); 4692 ret = xmlDictLookup(ctxt->dict, val, -1); 4693 xmlFree(val); 4694 return(ret); 4695 } 4696 4697 static const xmlChar * 4698 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4699 { 4700 return((const xmlChar*) xmlNodeGetContent(node)); 4701 } 4702 4703 /** 4704 * xmlSchemaGetProp: 4705 * @ctxt: the parser context 4706 * @node: the node 4707 * @name: the property name 4708 * 4709 * Read a attribute value and internalize the string 4710 * 4711 * Returns the string or NULL if not present. 4712 */ 4713 static const xmlChar * 4714 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4715 const char *name) 4716 { 4717 xmlChar *val; 4718 const xmlChar *ret; 4719 4720 val = xmlGetNoNsProp(node, BAD_CAST name); 4721 if (val == NULL) 4722 return(NULL); 4723 ret = xmlDictLookup(ctxt->dict, val, -1); 4724 xmlFree(val); 4725 return(ret); 4726 } 4727 4728 /************************************************************************ 4729 * * 4730 * Parsing functions * 4731 * * 4732 ************************************************************************/ 4733 4734 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4735 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4736 ret = xmlHashLookup(schema->slot, name); \ 4737 if (ret != NULL) goto exit; \ 4738 } \ 4739 if (xmlHashSize(schema->schemasImports) > 1) { \ 4740 xmlSchemaImportPtr import; \ 4741 if (nsName == NULL) \ 4742 import = xmlHashLookup(schema->schemasImports, \ 4743 XML_SCHEMAS_NO_NAMESPACE); \ 4744 else \ 4745 import = xmlHashLookup(schema->schemasImports, nsName); \ 4746 if (import == NULL) \ 4747 goto exit; \ 4748 ret = xmlHashLookup(import->schema->slot, name); \ 4749 } 4750 4751 /** 4752 * xmlSchemaGetElem: 4753 * @schema: the schema context 4754 * @name: the element name 4755 * @ns: the element namespace 4756 * 4757 * Lookup a global element declaration in the schema. 4758 * 4759 * Returns the element declaration or NULL if not found. 4760 */ 4761 static xmlSchemaElementPtr 4762 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4763 const xmlChar * nsName) 4764 { 4765 xmlSchemaElementPtr ret = NULL; 4766 4767 if ((name == NULL) || (schema == NULL)) 4768 return(NULL); 4769 if (schema != NULL) { 4770 WXS_FIND_GLOBAL_ITEM(elemDecl) 4771 } 4772 exit: 4773 #ifdef DEBUG 4774 if (ret == NULL) { 4775 if (nsName == NULL) 4776 fprintf(stderr, "Unable to lookup element decl. %s", name); 4777 else 4778 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4779 nsName); 4780 } 4781 #endif 4782 return (ret); 4783 } 4784 4785 /** 4786 * xmlSchemaGetType: 4787 * @schema: the main schema 4788 * @name: the type's name 4789 * nsName: the type's namespace 4790 * 4791 * Lookup a type in the schemas or the predefined types 4792 * 4793 * Returns the group definition or NULL if not found. 4794 */ 4795 static xmlSchemaTypePtr 4796 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4797 const xmlChar * nsName) 4798 { 4799 xmlSchemaTypePtr ret = NULL; 4800 4801 if (name == NULL) 4802 return (NULL); 4803 /* First try the built-in types. */ 4804 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4805 ret = xmlSchemaGetPredefinedType(name, nsName); 4806 if (ret != NULL) 4807 goto exit; 4808 /* 4809 * Note that we try the parsed schemas as well here 4810 * since one might have parsed the S4S, which contain more 4811 * than the built-in types. 4812 * TODO: Can we optimize this? 4813 */ 4814 } 4815 if (schema != NULL) { 4816 WXS_FIND_GLOBAL_ITEM(typeDecl) 4817 } 4818 exit: 4819 4820 #ifdef DEBUG 4821 if (ret == NULL) { 4822 if (nsName == NULL) 4823 fprintf(stderr, "Unable to lookup type %s", name); 4824 else 4825 fprintf(stderr, "Unable to lookup type %s:%s", name, 4826 nsName); 4827 } 4828 #endif 4829 return (ret); 4830 } 4831 4832 /** 4833 * xmlSchemaGetAttributeDecl: 4834 * @schema: the context of the schema 4835 * @name: the name of the attribute 4836 * @ns: the target namespace of the attribute 4837 * 4838 * Lookup a an attribute in the schema or imported schemas 4839 * 4840 * Returns the attribute declaration or NULL if not found. 4841 */ 4842 static xmlSchemaAttributePtr 4843 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4844 const xmlChar * nsName) 4845 { 4846 xmlSchemaAttributePtr ret = NULL; 4847 4848 if ((name == NULL) || (schema == NULL)) 4849 return (NULL); 4850 if (schema != NULL) { 4851 WXS_FIND_GLOBAL_ITEM(attrDecl) 4852 } 4853 exit: 4854 #ifdef DEBUG 4855 if (ret == NULL) { 4856 if (nsName == NULL) 4857 fprintf(stderr, "Unable to lookup attribute %s", name); 4858 else 4859 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4860 nsName); 4861 } 4862 #endif 4863 return (ret); 4864 } 4865 4866 /** 4867 * xmlSchemaGetAttributeGroup: 4868 * @schema: the context of the schema 4869 * @name: the name of the attribute group 4870 * @ns: the target namespace of the attribute group 4871 * 4872 * Lookup a an attribute group in the schema or imported schemas 4873 * 4874 * Returns the attribute group definition or NULL if not found. 4875 */ 4876 static xmlSchemaAttributeGroupPtr 4877 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4878 const xmlChar * nsName) 4879 { 4880 xmlSchemaAttributeGroupPtr ret = NULL; 4881 4882 if ((name == NULL) || (schema == NULL)) 4883 return (NULL); 4884 if (schema != NULL) { 4885 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4886 } 4887 exit: 4888 /* TODO: 4889 if ((ret != NULL) && (ret->redef != NULL)) { 4890 * Return the last redefinition. * 4891 ret = ret->redef; 4892 } 4893 */ 4894 #ifdef DEBUG 4895 if (ret == NULL) { 4896 if (nsName == NULL) 4897 fprintf(stderr, "Unable to lookup attribute group %s", name); 4898 else 4899 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4900 nsName); 4901 } 4902 #endif 4903 return (ret); 4904 } 4905 4906 /** 4907 * xmlSchemaGetGroup: 4908 * @schema: the context of the schema 4909 * @name: the name of the group 4910 * @ns: the target namespace of the group 4911 * 4912 * Lookup a group in the schema or imported schemas 4913 * 4914 * Returns the group definition or NULL if not found. 4915 */ 4916 static xmlSchemaModelGroupDefPtr 4917 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4918 const xmlChar * nsName) 4919 { 4920 xmlSchemaModelGroupDefPtr ret = NULL; 4921 4922 if ((name == NULL) || (schema == NULL)) 4923 return (NULL); 4924 if (schema != NULL) { 4925 WXS_FIND_GLOBAL_ITEM(groupDecl) 4926 } 4927 exit: 4928 4929 #ifdef DEBUG 4930 if (ret == NULL) { 4931 if (nsName == NULL) 4932 fprintf(stderr, "Unable to lookup group %s", name); 4933 else 4934 fprintf(stderr, "Unable to lookup group %s:%s", name, 4935 nsName); 4936 } 4937 #endif 4938 return (ret); 4939 } 4940 4941 static xmlSchemaNotationPtr 4942 xmlSchemaGetNotation(xmlSchemaPtr schema, 4943 const xmlChar *name, 4944 const xmlChar *nsName) 4945 { 4946 xmlSchemaNotationPtr ret = NULL; 4947 4948 if ((name == NULL) || (schema == NULL)) 4949 return (NULL); 4950 if (schema != NULL) { 4951 WXS_FIND_GLOBAL_ITEM(notaDecl) 4952 } 4953 exit: 4954 return (ret); 4955 } 4956 4957 static xmlSchemaIDCPtr 4958 xmlSchemaGetIDC(xmlSchemaPtr schema, 4959 const xmlChar *name, 4960 const xmlChar *nsName) 4961 { 4962 xmlSchemaIDCPtr ret = NULL; 4963 4964 if ((name == NULL) || (schema == NULL)) 4965 return (NULL); 4966 if (schema != NULL) { 4967 WXS_FIND_GLOBAL_ITEM(idcDef) 4968 } 4969 exit: 4970 return (ret); 4971 } 4972 4973 /** 4974 * xmlSchemaGetNamedComponent: 4975 * @schema: the schema 4976 * @name: the name of the group 4977 * @ns: the target namespace of the group 4978 * 4979 * Lookup a group in the schema or imported schemas 4980 * 4981 * Returns the group definition or NULL if not found. 4982 */ 4983 static xmlSchemaBasicItemPtr 4984 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 4985 xmlSchemaTypeType itemType, 4986 const xmlChar *name, 4987 const xmlChar *targetNs) 4988 { 4989 switch (itemType) { 4990 case XML_SCHEMA_TYPE_GROUP: 4991 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 4992 name, targetNs)); 4993 case XML_SCHEMA_TYPE_ELEMENT: 4994 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 4995 name, targetNs)); 4996 default: 4997 TODO 4998 return (NULL); 4999 } 5000 } 5001 5002 /************************************************************************ 5003 * * 5004 * Parsing functions * 5005 * * 5006 ************************************************************************/ 5007 5008 #define IS_BLANK_NODE(n) \ 5009 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 5010 5011 /** 5012 * xmlSchemaIsBlank: 5013 * @str: a string 5014 * @len: the length of the string or -1 5015 * 5016 * Check if a string is ignorable 5017 * 5018 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 5019 */ 5020 static int 5021 xmlSchemaIsBlank(xmlChar * str, int len) 5022 { 5023 if (str == NULL) 5024 return (1); 5025 if (len < 0) { 5026 while (*str != 0) { 5027 if (!(IS_BLANK_CH(*str))) 5028 return (0); 5029 str++; 5030 } 5031 } else while ((*str != 0) && (len != 0)) { 5032 if (!(IS_BLANK_CH(*str))) 5033 return (0); 5034 str++; 5035 len--; 5036 } 5037 5038 return (1); 5039 } 5040 5041 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5042 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5043 /* 5044 * xmlSchemaFindRedefCompInGraph: 5045 * ATTENTION TODO: This uses pointer comp. for strings. 5046 */ 5047 static xmlSchemaBasicItemPtr 5048 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5049 xmlSchemaTypeType type, 5050 const xmlChar *name, 5051 const xmlChar *nsName) 5052 { 5053 xmlSchemaBasicItemPtr ret; 5054 int i; 5055 5056 if ((bucket == NULL) || (name == NULL)) 5057 return(NULL); 5058 if ((bucket->globals == NULL) || 5059 (bucket->globals->nbItems == 0)) 5060 goto subschemas; 5061 /* 5062 * Search in global components. 5063 */ 5064 for (i = 0; i < bucket->globals->nbItems; i++) { 5065 ret = bucket->globals->items[i]; 5066 if (ret->type == type) { 5067 switch (type) { 5068 case XML_SCHEMA_TYPE_COMPLEX: 5069 case XML_SCHEMA_TYPE_SIMPLE: 5070 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5071 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5072 nsName)) 5073 { 5074 return(ret); 5075 } 5076 break; 5077 case XML_SCHEMA_TYPE_GROUP: 5078 if ((WXS_COMP_NAME(ret, 5079 xmlSchemaModelGroupDefPtr) == name) && 5080 (WXS_COMP_TNS(ret, 5081 xmlSchemaModelGroupDefPtr) == nsName)) 5082 { 5083 return(ret); 5084 } 5085 break; 5086 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5087 if ((WXS_COMP_NAME(ret, 5088 xmlSchemaAttributeGroupPtr) == name) && 5089 (WXS_COMP_TNS(ret, 5090 xmlSchemaAttributeGroupPtr) == nsName)) 5091 { 5092 return(ret); 5093 } 5094 break; 5095 default: 5096 /* Should not be hit. */ 5097 return(NULL); 5098 } 5099 } 5100 } 5101 subschemas: 5102 /* 5103 * Process imported/included schemas. 5104 */ 5105 if (bucket->relations != NULL) { 5106 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5107 5108 /* 5109 * TODO: Marking the bucket will not avoid multiple searches 5110 * in the same schema, but avoids at least circularity. 5111 */ 5112 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5113 do { 5114 if ((rel->bucket != NULL) && 5115 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5116 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5117 type, name, nsName); 5118 if (ret != NULL) 5119 return(ret); 5120 } 5121 rel = rel->next; 5122 } while (rel != NULL); 5123 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5124 } 5125 return(NULL); 5126 } 5127 5128 /** 5129 * xmlSchemaAddNotation: 5130 * @ctxt: a schema parser context 5131 * @schema: the schema being built 5132 * @name: the item name 5133 * 5134 * Add an XML schema annotation declaration 5135 * *WARNING* this interface is highly subject to change 5136 * 5137 * Returns the new struture or NULL in case of error 5138 */ 5139 static xmlSchemaNotationPtr 5140 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5141 const xmlChar *name, const xmlChar *nsName, 5142 xmlNodePtr node ATTRIBUTE_UNUSED) 5143 { 5144 xmlSchemaNotationPtr ret = NULL; 5145 5146 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5147 return (NULL); 5148 5149 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5150 if (ret == NULL) { 5151 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5152 return (NULL); 5153 } 5154 memset(ret, 0, sizeof(xmlSchemaNotation)); 5155 ret->type = XML_SCHEMA_TYPE_NOTATION; 5156 ret->name = name; 5157 ret->targetNamespace = nsName; 5158 /* TODO: do we need the node to be set? 5159 * ret->node = node;*/ 5160 WXS_ADD_GLOBAL(ctxt, ret); 5161 return (ret); 5162 } 5163 5164 /** 5165 * xmlSchemaAddAttribute: 5166 * @ctxt: a schema parser context 5167 * @schema: the schema being built 5168 * @name: the item name 5169 * @namespace: the namespace 5170 * 5171 * Add an XML schema Attrribute declaration 5172 * *WARNING* this interface is highly subject to change 5173 * 5174 * Returns the new struture or NULL in case of error 5175 */ 5176 static xmlSchemaAttributePtr 5177 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5178 const xmlChar * name, const xmlChar * nsName, 5179 xmlNodePtr node, int topLevel) 5180 { 5181 xmlSchemaAttributePtr ret = NULL; 5182 5183 if ((ctxt == NULL) || (schema == NULL)) 5184 return (NULL); 5185 5186 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5187 if (ret == NULL) { 5188 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5189 return (NULL); 5190 } 5191 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5192 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5193 ret->node = node; 5194 ret->name = name; 5195 ret->targetNamespace = nsName; 5196 5197 if (topLevel) 5198 WXS_ADD_GLOBAL(ctxt, ret); 5199 else 5200 WXS_ADD_LOCAL(ctxt, ret); 5201 WXS_ADD_PENDING(ctxt, ret); 5202 return (ret); 5203 } 5204 5205 /** 5206 * xmlSchemaAddAttributeUse: 5207 * @ctxt: a schema parser context 5208 * @schema: the schema being built 5209 * @name: the item name 5210 * @namespace: the namespace 5211 * 5212 * Add an XML schema Attrribute declaration 5213 * *WARNING* this interface is highly subject to change 5214 * 5215 * Returns the new struture or NULL in case of error 5216 */ 5217 static xmlSchemaAttributeUsePtr 5218 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5219 xmlNodePtr node) 5220 { 5221 xmlSchemaAttributeUsePtr ret = NULL; 5222 5223 if (pctxt == NULL) 5224 return (NULL); 5225 5226 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5227 if (ret == NULL) { 5228 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5229 return (NULL); 5230 } 5231 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5232 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5233 ret->node = node; 5234 5235 WXS_ADD_LOCAL(pctxt, ret); 5236 return (ret); 5237 } 5238 5239 /* 5240 * xmlSchemaAddRedef: 5241 * 5242 * Adds a redefinition information. This is used at a later stage to: 5243 * resolve references to the redefined components and to check constraints. 5244 */ 5245 static xmlSchemaRedefPtr 5246 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5247 xmlSchemaBucketPtr targetBucket, 5248 void *item, 5249 const xmlChar *refName, 5250 const xmlChar *refTargetNs) 5251 { 5252 xmlSchemaRedefPtr ret; 5253 5254 ret = (xmlSchemaRedefPtr) 5255 xmlMalloc(sizeof(xmlSchemaRedef)); 5256 if (ret == NULL) { 5257 xmlSchemaPErrMemory(pctxt, 5258 "allocating redefinition info", NULL); 5259 return (NULL); 5260 } 5261 memset(ret, 0, sizeof(xmlSchemaRedef)); 5262 ret->item = item; 5263 ret->targetBucket = targetBucket; 5264 ret->refName = refName; 5265 ret->refTargetNs = refTargetNs; 5266 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5267 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5268 else 5269 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5270 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5271 5272 return (ret); 5273 } 5274 5275 /** 5276 * xmlSchemaAddAttributeGroupDefinition: 5277 * @ctxt: a schema parser context 5278 * @schema: the schema being built 5279 * @name: the item name 5280 * @nsName: the target namespace 5281 * @node: the corresponding node 5282 * 5283 * Add an XML schema Attrribute Group definition. 5284 * 5285 * Returns the new struture or NULL in case of error 5286 */ 5287 static xmlSchemaAttributeGroupPtr 5288 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5289 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5290 const xmlChar *name, 5291 const xmlChar *nsName, 5292 xmlNodePtr node) 5293 { 5294 xmlSchemaAttributeGroupPtr ret = NULL; 5295 5296 if ((pctxt == NULL) || (name == NULL)) 5297 return (NULL); 5298 5299 ret = (xmlSchemaAttributeGroupPtr) 5300 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5301 if (ret == NULL) { 5302 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5303 return (NULL); 5304 } 5305 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5306 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5307 ret->name = name; 5308 ret->targetNamespace = nsName; 5309 ret->node = node; 5310 5311 /* TODO: Remove the flag. */ 5312 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5313 if (pctxt->isRedefine) { 5314 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5315 ret, name, nsName); 5316 if (pctxt->redef == NULL) { 5317 xmlFree(ret); 5318 return(NULL); 5319 } 5320 pctxt->redefCounter = 0; 5321 } 5322 WXS_ADD_GLOBAL(pctxt, ret); 5323 WXS_ADD_PENDING(pctxt, ret); 5324 return (ret); 5325 } 5326 5327 /** 5328 * xmlSchemaAddElement: 5329 * @ctxt: a schema parser context 5330 * @schema: the schema being built 5331 * @name: the type name 5332 * @namespace: the type namespace 5333 * 5334 * Add an XML schema Element declaration 5335 * *WARNING* this interface is highly subject to change 5336 * 5337 * Returns the new struture or NULL in case of error 5338 */ 5339 static xmlSchemaElementPtr 5340 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5341 const xmlChar * name, const xmlChar * nsName, 5342 xmlNodePtr node, int topLevel) 5343 { 5344 xmlSchemaElementPtr ret = NULL; 5345 5346 if ((ctxt == NULL) || (name == NULL)) 5347 return (NULL); 5348 5349 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5350 if (ret == NULL) { 5351 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5352 return (NULL); 5353 } 5354 memset(ret, 0, sizeof(xmlSchemaElement)); 5355 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5356 ret->name = name; 5357 ret->targetNamespace = nsName; 5358 ret->node = node; 5359 5360 if (topLevel) 5361 WXS_ADD_GLOBAL(ctxt, ret); 5362 else 5363 WXS_ADD_LOCAL(ctxt, ret); 5364 WXS_ADD_PENDING(ctxt, ret); 5365 return (ret); 5366 } 5367 5368 /** 5369 * xmlSchemaAddType: 5370 * @ctxt: a schema parser context 5371 * @schema: the schema being built 5372 * @name: the item name 5373 * @namespace: the namespace 5374 * 5375 * Add an XML schema item 5376 * *WARNING* this interface is highly subject to change 5377 * 5378 * Returns the new struture or NULL in case of error 5379 */ 5380 static xmlSchemaTypePtr 5381 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5382 xmlSchemaTypeType type, 5383 const xmlChar * name, const xmlChar * nsName, 5384 xmlNodePtr node, int topLevel) 5385 { 5386 xmlSchemaTypePtr ret = NULL; 5387 5388 if ((ctxt == NULL) || (schema == NULL)) 5389 return (NULL); 5390 5391 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5392 if (ret == NULL) { 5393 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5394 return (NULL); 5395 } 5396 memset(ret, 0, sizeof(xmlSchemaType)); 5397 ret->type = type; 5398 ret->name = name; 5399 ret->targetNamespace = nsName; 5400 ret->node = node; 5401 if (topLevel) { 5402 if (ctxt->isRedefine) { 5403 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5404 ret, name, nsName); 5405 if (ctxt->redef == NULL) { 5406 xmlFree(ret); 5407 return(NULL); 5408 } 5409 ctxt->redefCounter = 0; 5410 } 5411 WXS_ADD_GLOBAL(ctxt, ret); 5412 } else 5413 WXS_ADD_LOCAL(ctxt, ret); 5414 WXS_ADD_PENDING(ctxt, ret); 5415 return (ret); 5416 } 5417 5418 static xmlSchemaQNameRefPtr 5419 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5420 xmlSchemaTypeType refType, 5421 const xmlChar *refName, 5422 const xmlChar *refNs) 5423 { 5424 xmlSchemaQNameRefPtr ret; 5425 5426 ret = (xmlSchemaQNameRefPtr) 5427 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5428 if (ret == NULL) { 5429 xmlSchemaPErrMemory(pctxt, 5430 "allocating QName reference item", NULL); 5431 return (NULL); 5432 } 5433 ret->node = NULL; 5434 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5435 ret->name = refName; 5436 ret->targetNamespace = refNs; 5437 ret->item = NULL; 5438 ret->itemType = refType; 5439 /* 5440 * Store the reference item in the schema. 5441 */ 5442 WXS_ADD_LOCAL(pctxt, ret); 5443 return (ret); 5444 } 5445 5446 static xmlSchemaAttributeUseProhibPtr 5447 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5448 { 5449 xmlSchemaAttributeUseProhibPtr ret; 5450 5451 ret = (xmlSchemaAttributeUseProhibPtr) 5452 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5453 if (ret == NULL) { 5454 xmlSchemaPErrMemory(pctxt, 5455 "allocating attribute use prohibition", NULL); 5456 return (NULL); 5457 } 5458 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5459 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5460 WXS_ADD_LOCAL(pctxt, ret); 5461 return (ret); 5462 } 5463 5464 5465 /** 5466 * xmlSchemaAddModelGroup: 5467 * @ctxt: a schema parser context 5468 * @schema: the schema being built 5469 * @type: the "compositor" type of the model group 5470 * @node: the node in the schema doc 5471 * 5472 * Adds a schema model group 5473 * *WARNING* this interface is highly subject to change 5474 * 5475 * Returns the new struture or NULL in case of error 5476 */ 5477 static xmlSchemaModelGroupPtr 5478 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5479 xmlSchemaPtr schema, 5480 xmlSchemaTypeType type, 5481 xmlNodePtr node) 5482 { 5483 xmlSchemaModelGroupPtr ret = NULL; 5484 5485 if ((ctxt == NULL) || (schema == NULL)) 5486 return (NULL); 5487 5488 ret = (xmlSchemaModelGroupPtr) 5489 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5490 if (ret == NULL) { 5491 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5492 NULL); 5493 return (NULL); 5494 } 5495 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5496 ret->type = type; 5497 ret->node = node; 5498 WXS_ADD_LOCAL(ctxt, ret); 5499 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5500 (type == XML_SCHEMA_TYPE_CHOICE)) 5501 WXS_ADD_PENDING(ctxt, ret); 5502 return (ret); 5503 } 5504 5505 5506 /** 5507 * xmlSchemaAddParticle: 5508 * @ctxt: a schema parser context 5509 * @schema: the schema being built 5510 * @node: the corresponding node in the schema doc 5511 * @min: the minOccurs 5512 * @max: the maxOccurs 5513 * 5514 * Adds an XML schema particle component. 5515 * *WARNING* this interface is highly subject to change 5516 * 5517 * Returns the new struture or NULL in case of error 5518 */ 5519 static xmlSchemaParticlePtr 5520 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5521 xmlNodePtr node, int min, int max) 5522 { 5523 xmlSchemaParticlePtr ret = NULL; 5524 if (ctxt == NULL) 5525 return (NULL); 5526 5527 #ifdef DEBUG 5528 fprintf(stderr, "Adding particle component\n"); 5529 #endif 5530 ret = (xmlSchemaParticlePtr) 5531 xmlMalloc(sizeof(xmlSchemaParticle)); 5532 if (ret == NULL) { 5533 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5534 NULL); 5535 return (NULL); 5536 } 5537 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5538 ret->annot = NULL; 5539 ret->node = node; 5540 ret->minOccurs = min; 5541 ret->maxOccurs = max; 5542 ret->next = NULL; 5543 ret->children = NULL; 5544 5545 WXS_ADD_LOCAL(ctxt, ret); 5546 /* 5547 * Note that addition to pending components will be done locally 5548 * to the specific parsing function, since the most particles 5549 * need not to be fixed up (i.e. the reference to be resolved). 5550 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5551 */ 5552 return (ret); 5553 } 5554 5555 /** 5556 * xmlSchemaAddModelGroupDefinition: 5557 * @ctxt: a schema validation context 5558 * @schema: the schema being built 5559 * @name: the group name 5560 * 5561 * Add an XML schema Group definition 5562 * 5563 * Returns the new struture or NULL in case of error 5564 */ 5565 static xmlSchemaModelGroupDefPtr 5566 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5567 xmlSchemaPtr schema, 5568 const xmlChar *name, 5569 const xmlChar *nsName, 5570 xmlNodePtr node) 5571 { 5572 xmlSchemaModelGroupDefPtr ret = NULL; 5573 5574 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5575 return (NULL); 5576 5577 ret = (xmlSchemaModelGroupDefPtr) 5578 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5579 if (ret == NULL) { 5580 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5581 return (NULL); 5582 } 5583 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5584 ret->name = name; 5585 ret->type = XML_SCHEMA_TYPE_GROUP; 5586 ret->node = node; 5587 ret->targetNamespace = nsName; 5588 5589 if (ctxt->isRedefine) { 5590 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5591 ret, name, nsName); 5592 if (ctxt->redef == NULL) { 5593 xmlFree(ret); 5594 return(NULL); 5595 } 5596 ctxt->redefCounter = 0; 5597 } 5598 WXS_ADD_GLOBAL(ctxt, ret); 5599 WXS_ADD_PENDING(ctxt, ret); 5600 return (ret); 5601 } 5602 5603 /** 5604 * xmlSchemaNewWildcardNs: 5605 * @ctxt: a schema validation context 5606 * 5607 * Creates a new wildcard namespace constraint. 5608 * 5609 * Returns the new struture or NULL in case of error 5610 */ 5611 static xmlSchemaWildcardNsPtr 5612 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5613 { 5614 xmlSchemaWildcardNsPtr ret; 5615 5616 ret = (xmlSchemaWildcardNsPtr) 5617 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5618 if (ret == NULL) { 5619 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5620 return (NULL); 5621 } 5622 ret->value = NULL; 5623 ret->next = NULL; 5624 return (ret); 5625 } 5626 5627 static xmlSchemaIDCPtr 5628 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5629 const xmlChar *name, const xmlChar *nsName, 5630 int category, xmlNodePtr node) 5631 { 5632 xmlSchemaIDCPtr ret = NULL; 5633 5634 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5635 return (NULL); 5636 5637 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5638 if (ret == NULL) { 5639 xmlSchemaPErrMemory(ctxt, 5640 "allocating an identity-constraint definition", NULL); 5641 return (NULL); 5642 } 5643 memset(ret, 0, sizeof(xmlSchemaIDC)); 5644 /* The target namespace of the parent element declaration. */ 5645 ret->targetNamespace = nsName; 5646 ret->name = name; 5647 ret->type = category; 5648 ret->node = node; 5649 5650 WXS_ADD_GLOBAL(ctxt, ret); 5651 /* 5652 * Only keyrefs need to be fixup up. 5653 */ 5654 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5655 WXS_ADD_PENDING(ctxt, ret); 5656 return (ret); 5657 } 5658 5659 /** 5660 * xmlSchemaAddWildcard: 5661 * @ctxt: a schema validation context 5662 * @schema: a schema 5663 * 5664 * Adds a wildcard. 5665 * It corresponds to a xsd:anyAttribute and xsd:any. 5666 * 5667 * Returns the new struture or NULL in case of error 5668 */ 5669 static xmlSchemaWildcardPtr 5670 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5671 xmlSchemaTypeType type, xmlNodePtr node) 5672 { 5673 xmlSchemaWildcardPtr ret = NULL; 5674 5675 if ((ctxt == NULL) || (schema == NULL)) 5676 return (NULL); 5677 5678 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5679 if (ret == NULL) { 5680 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5681 return (NULL); 5682 } 5683 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5684 ret->type = type; 5685 ret->node = node; 5686 WXS_ADD_LOCAL(ctxt, ret); 5687 return (ret); 5688 } 5689 5690 static void 5691 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5692 { 5693 if (group == NULL) 5694 return; 5695 if (group->members != NULL) 5696 xmlSchemaItemListFree(group->members); 5697 xmlFree(group); 5698 } 5699 5700 static xmlSchemaSubstGroupPtr 5701 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5702 xmlSchemaElementPtr head) 5703 { 5704 xmlSchemaSubstGroupPtr ret; 5705 5706 /* Init subst group hash. */ 5707 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5708 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5709 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5710 return(NULL); 5711 } 5712 /* Create a new substitution group. */ 5713 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5714 if (ret == NULL) { 5715 xmlSchemaPErrMemory(NULL, 5716 "allocating a substitution group container", NULL); 5717 return(NULL); 5718 } 5719 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5720 ret->head = head; 5721 /* Create list of members. */ 5722 ret->members = xmlSchemaItemListCreate(); 5723 if (ret->members == NULL) { 5724 xmlSchemaSubstGroupFree(ret); 5725 return(NULL); 5726 } 5727 /* Add subst group to hash. */ 5728 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5729 head->name, head->targetNamespace, ret) != 0) { 5730 PERROR_INT("xmlSchemaSubstGroupAdd", 5731 "failed to add a new substitution container"); 5732 xmlSchemaSubstGroupFree(ret); 5733 return(NULL); 5734 } 5735 return(ret); 5736 } 5737 5738 static xmlSchemaSubstGroupPtr 5739 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5740 xmlSchemaElementPtr head) 5741 { 5742 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5743 return(NULL); 5744 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5745 head->name, head->targetNamespace)); 5746 5747 } 5748 5749 /** 5750 * xmlSchemaAddElementSubstitutionMember: 5751 * @pctxt: a schema parser context 5752 * @head: the head of the substitution group 5753 * @member: the new member of the substitution group 5754 * 5755 * Allocate a new annotation structure. 5756 * 5757 * Returns the newly allocated structure or NULL in case or error 5758 */ 5759 static int 5760 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5761 xmlSchemaElementPtr head, 5762 xmlSchemaElementPtr member) 5763 { 5764 xmlSchemaSubstGroupPtr substGroup = NULL; 5765 5766 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5767 return (-1); 5768 5769 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5770 if (substGroup == NULL) 5771 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5772 if (substGroup == NULL) 5773 return(-1); 5774 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5775 return(-1); 5776 return(0); 5777 } 5778 5779 /************************************************************************ 5780 * * 5781 * Utilities for parsing * 5782 * * 5783 ************************************************************************/ 5784 5785 /** 5786 * xmlSchemaPValAttrNodeQNameValue: 5787 * @ctxt: a schema parser context 5788 * @schema: the schema context 5789 * @ownerDes: the designation of the parent element 5790 * @ownerItem: the parent as a schema object 5791 * @value: the QName value 5792 * @local: the resulting local part if found, the attribute value otherwise 5793 * @uri: the resulting namespace URI if found 5794 * 5795 * Extracts the local name and the URI of a QName value and validates it. 5796 * This one is intended to be used on attribute values that 5797 * should resolve to schema components. 5798 * 5799 * Returns 0, in case the QName is valid, a positive error code 5800 * if not valid and -1 if an internal error occurs. 5801 */ 5802 static int 5803 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5804 xmlSchemaPtr schema, 5805 xmlSchemaBasicItemPtr ownerItem, 5806 xmlAttrPtr attr, 5807 const xmlChar *value, 5808 const xmlChar **uri, 5809 const xmlChar **local) 5810 { 5811 const xmlChar *pref; 5812 xmlNsPtr ns; 5813 int len, ret; 5814 5815 *uri = NULL; 5816 *local = NULL; 5817 ret = xmlValidateQName(value, 1); 5818 if (ret > 0) { 5819 xmlSchemaPSimpleTypeErr(ctxt, 5820 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5821 ownerItem, (xmlNodePtr) attr, 5822 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5823 NULL, value, NULL, NULL, NULL); 5824 *local = value; 5825 return (ctxt->err); 5826 } else if (ret < 0) 5827 return (-1); 5828 5829 if (!strchr((char *) value, ':')) { 5830 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5831 if (ns) 5832 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5833 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5834 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5835 * parser context. */ 5836 /* 5837 * This one takes care of included schemas with no 5838 * target namespace. 5839 */ 5840 *uri = ctxt->targetNamespace; 5841 } 5842 *local = xmlDictLookup(ctxt->dict, value, -1); 5843 return (0); 5844 } 5845 /* 5846 * At this point xmlSplitQName3 has to return a local name. 5847 */ 5848 *local = xmlSplitQName3(value, &len); 5849 *local = xmlDictLookup(ctxt->dict, *local, -1); 5850 pref = xmlDictLookup(ctxt->dict, value, len); 5851 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5852 if (ns == NULL) { 5853 xmlSchemaPSimpleTypeErr(ctxt, 5854 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5855 ownerItem, (xmlNodePtr) attr, 5856 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5857 "The value '%s' of simple type 'xs:QName' has no " 5858 "corresponding namespace declaration in scope", value, NULL); 5859 return (ctxt->err); 5860 } else { 5861 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5862 } 5863 return (0); 5864 } 5865 5866 /** 5867 * xmlSchemaPValAttrNodeQName: 5868 * @ctxt: a schema parser context 5869 * @schema: the schema context 5870 * @ownerDes: the designation of the owner element 5871 * @ownerItem: the owner as a schema object 5872 * @attr: the attribute node 5873 * @local: the resulting local part if found, the attribute value otherwise 5874 * @uri: the resulting namespace URI if found 5875 * 5876 * Extracts and validates the QName of an attribute value. 5877 * This one is intended to be used on attribute values that 5878 * should resolve to schema components. 5879 * 5880 * Returns 0, in case the QName is valid, a positive error code 5881 * if not valid and -1 if an internal error occurs. 5882 */ 5883 static int 5884 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5885 xmlSchemaPtr schema, 5886 xmlSchemaBasicItemPtr ownerItem, 5887 xmlAttrPtr attr, 5888 const xmlChar **uri, 5889 const xmlChar **local) 5890 { 5891 const xmlChar *value; 5892 5893 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5894 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5895 ownerItem, attr, value, uri, local)); 5896 } 5897 5898 /** 5899 * xmlSchemaPValAttrQName: 5900 * @ctxt: a schema parser context 5901 * @schema: the schema context 5902 * @ownerDes: the designation of the parent element 5903 * @ownerItem: the owner as a schema object 5904 * @ownerElem: the parent node of the attribute 5905 * @name: the name of the attribute 5906 * @local: the resulting local part if found, the attribute value otherwise 5907 * @uri: the resulting namespace URI if found 5908 * 5909 * Extracts and validates the QName of an attribute value. 5910 * 5911 * Returns 0, in case the QName is valid, a positive error code 5912 * if not valid and -1 if an internal error occurs. 5913 */ 5914 static int 5915 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5916 xmlSchemaPtr schema, 5917 xmlSchemaBasicItemPtr ownerItem, 5918 xmlNodePtr ownerElem, 5919 const char *name, 5920 const xmlChar **uri, 5921 const xmlChar **local) 5922 { 5923 xmlAttrPtr attr; 5924 5925 attr = xmlSchemaGetPropNode(ownerElem, name); 5926 if (attr == NULL) { 5927 *local = NULL; 5928 *uri = NULL; 5929 return (0); 5930 } 5931 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5932 ownerItem, attr, uri, local)); 5933 } 5934 5935 /** 5936 * xmlSchemaPValAttrID: 5937 * @ctxt: a schema parser context 5938 * @schema: the schema context 5939 * @ownerDes: the designation of the parent element 5940 * @ownerItem: the owner as a schema object 5941 * @ownerElem: the parent node of the attribute 5942 * @name: the name of the attribute 5943 * 5944 * Extracts and validates the ID of an attribute value. 5945 * 5946 * Returns 0, in case the ID is valid, a positive error code 5947 * if not valid and -1 if an internal error occurs. 5948 */ 5949 static int 5950 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5951 { 5952 int ret; 5953 const xmlChar *value; 5954 5955 if (attr == NULL) 5956 return(0); 5957 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5958 ret = xmlValidateNCName(value, 1); 5959 if (ret == 0) { 5960 /* 5961 * NOTE: the IDness might have already be declared in the DTD 5962 */ 5963 if (attr->atype != XML_ATTRIBUTE_ID) { 5964 xmlIDPtr res; 5965 xmlChar *strip; 5966 5967 /* 5968 * TODO: Use xmlSchemaStrip here; it's not exported at this 5969 * moment. 5970 */ 5971 strip = xmlSchemaCollapseString(value); 5972 if (strip != NULL) { 5973 xmlFree((xmlChar *) value); 5974 value = strip; 5975 } 5976 res = xmlAddID(NULL, attr->doc, value, attr); 5977 if (res == NULL) { 5978 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5979 xmlSchemaPSimpleTypeErr(ctxt, 5980 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5981 NULL, (xmlNodePtr) attr, 5982 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5983 NULL, NULL, "Duplicate value '%s' of simple " 5984 "type 'xs:ID'", value, NULL); 5985 } else 5986 attr->atype = XML_ATTRIBUTE_ID; 5987 } 5988 } else if (ret > 0) { 5989 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 5990 xmlSchemaPSimpleTypeErr(ctxt, 5991 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5992 NULL, (xmlNodePtr) attr, 5993 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 5994 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 5995 "not a valid 'xs:NCName'", 5996 value, NULL); 5997 } 5998 if (value != NULL) 5999 xmlFree((xmlChar *)value); 6000 6001 return (ret); 6002 } 6003 6004 static int 6005 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 6006 xmlNodePtr ownerElem, 6007 const xmlChar *name) 6008 { 6009 xmlAttrPtr attr; 6010 6011 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 6012 if (attr == NULL) 6013 return(0); 6014 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 6015 6016 } 6017 6018 /** 6019 * xmlGetMaxOccurs: 6020 * @ctxt: a schema validation context 6021 * @node: a subtree containing XML Schema informations 6022 * 6023 * Get the maxOccurs property 6024 * 6025 * Returns the default if not found, or the value 6026 */ 6027 static int 6028 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6029 int min, int max, int def, const char *expected) 6030 { 6031 const xmlChar *val, *cur; 6032 int ret = 0; 6033 xmlAttrPtr attr; 6034 6035 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6036 if (attr == NULL) 6037 return (def); 6038 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6039 6040 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6041 if (max != UNBOUNDED) { 6042 xmlSchemaPSimpleTypeErr(ctxt, 6043 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6044 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6045 NULL, (xmlNodePtr) attr, NULL, expected, 6046 val, NULL, NULL, NULL); 6047 return (def); 6048 } else 6049 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6050 } 6051 6052 cur = val; 6053 while (IS_BLANK_CH(*cur)) 6054 cur++; 6055 if (*cur == 0) { 6056 xmlSchemaPSimpleTypeErr(ctxt, 6057 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6058 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6059 NULL, (xmlNodePtr) attr, NULL, expected, 6060 val, NULL, NULL, NULL); 6061 return (def); 6062 } 6063 while ((*cur >= '0') && (*cur <= '9')) { 6064 ret = ret * 10 + (*cur - '0'); 6065 cur++; 6066 } 6067 while (IS_BLANK_CH(*cur)) 6068 cur++; 6069 /* 6070 * TODO: Restrict the maximal value to Integer. 6071 */ 6072 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6073 xmlSchemaPSimpleTypeErr(ctxt, 6074 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6075 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6076 NULL, (xmlNodePtr) attr, NULL, expected, 6077 val, NULL, NULL, NULL); 6078 return (def); 6079 } 6080 return (ret); 6081 } 6082 6083 /** 6084 * xmlGetMinOccurs: 6085 * @ctxt: a schema validation context 6086 * @node: a subtree containing XML Schema informations 6087 * 6088 * Get the minOccurs property 6089 * 6090 * Returns the default if not found, or the value 6091 */ 6092 static int 6093 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6094 int min, int max, int def, const char *expected) 6095 { 6096 const xmlChar *val, *cur; 6097 int ret = 0; 6098 xmlAttrPtr attr; 6099 6100 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6101 if (attr == NULL) 6102 return (def); 6103 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6104 cur = val; 6105 while (IS_BLANK_CH(*cur)) 6106 cur++; 6107 if (*cur == 0) { 6108 xmlSchemaPSimpleTypeErr(ctxt, 6109 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6110 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6111 NULL, (xmlNodePtr) attr, NULL, expected, 6112 val, NULL, NULL, NULL); 6113 return (def); 6114 } 6115 while ((*cur >= '0') && (*cur <= '9')) { 6116 ret = ret * 10 + (*cur - '0'); 6117 cur++; 6118 } 6119 while (IS_BLANK_CH(*cur)) 6120 cur++; 6121 /* 6122 * TODO: Restrict the maximal value to Integer. 6123 */ 6124 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6125 xmlSchemaPSimpleTypeErr(ctxt, 6126 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6127 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6128 NULL, (xmlNodePtr) attr, NULL, expected, 6129 val, NULL, NULL, NULL); 6130 return (def); 6131 } 6132 return (ret); 6133 } 6134 6135 /** 6136 * xmlSchemaPGetBoolNodeValue: 6137 * @ctxt: a schema validation context 6138 * @ownerDes: owner designation 6139 * @ownerItem: the owner as a schema item 6140 * @node: the node holding the value 6141 * 6142 * Converts a boolean string value into 1 or 0. 6143 * 6144 * Returns 0 or 1. 6145 */ 6146 static int 6147 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6148 xmlSchemaBasicItemPtr ownerItem, 6149 xmlNodePtr node) 6150 { 6151 xmlChar *value = NULL; 6152 int res = 0; 6153 6154 value = xmlNodeGetContent(node); 6155 /* 6156 * 3.2.2.1 Lexical representation 6157 * An instance of a datatype that is defined as `boolean` 6158 * can have the following legal literals {true, false, 1, 0}. 6159 */ 6160 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6161 res = 1; 6162 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6163 res = 0; 6164 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6165 res = 1; 6166 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6167 res = 0; 6168 else { 6169 xmlSchemaPSimpleTypeErr(ctxt, 6170 XML_SCHEMAP_INVALID_BOOLEAN, 6171 ownerItem, node, 6172 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6173 NULL, BAD_CAST value, 6174 NULL, NULL, NULL); 6175 } 6176 if (value != NULL) 6177 xmlFree(value); 6178 return (res); 6179 } 6180 6181 /** 6182 * xmlGetBooleanProp: 6183 * @ctxt: a schema validation context 6184 * @node: a subtree containing XML Schema informations 6185 * @name: the attribute name 6186 * @def: the default value 6187 * 6188 * Evaluate if a boolean property is set 6189 * 6190 * Returns the default if not found, 0 if found to be false, 6191 * 1 if found to be true 6192 */ 6193 static int 6194 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6195 xmlNodePtr node, 6196 const char *name, int def) 6197 { 6198 const xmlChar *val; 6199 6200 val = xmlSchemaGetProp(ctxt, node, name); 6201 if (val == NULL) 6202 return (def); 6203 /* 6204 * 3.2.2.1 Lexical representation 6205 * An instance of a datatype that is defined as `boolean` 6206 * can have the following legal literals {true, false, 1, 0}. 6207 */ 6208 if (xmlStrEqual(val, BAD_CAST "true")) 6209 def = 1; 6210 else if (xmlStrEqual(val, BAD_CAST "false")) 6211 def = 0; 6212 else if (xmlStrEqual(val, BAD_CAST "1")) 6213 def = 1; 6214 else if (xmlStrEqual(val, BAD_CAST "0")) 6215 def = 0; 6216 else { 6217 xmlSchemaPSimpleTypeErr(ctxt, 6218 XML_SCHEMAP_INVALID_BOOLEAN, 6219 NULL, 6220 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6221 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6222 NULL, val, NULL, NULL, NULL); 6223 } 6224 return (def); 6225 } 6226 6227 /************************************************************************ 6228 * * 6229 * Shema extraction from an Infoset * 6230 * * 6231 ************************************************************************/ 6232 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6233 ctxt, xmlSchemaPtr schema, 6234 xmlNodePtr node, 6235 int topLevel); 6236 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6237 ctxt, 6238 xmlSchemaPtr schema, 6239 xmlNodePtr node, 6240 int topLevel); 6241 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6242 ctxt, 6243 xmlSchemaPtr schema, 6244 xmlNodePtr node, 6245 xmlSchemaTypeType parentType); 6246 static xmlSchemaBasicItemPtr 6247 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6248 xmlSchemaPtr schema, 6249 xmlNodePtr node, 6250 xmlSchemaItemListPtr uses, 6251 int parentType); 6252 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6253 xmlSchemaPtr schema, 6254 xmlNodePtr node); 6255 static xmlSchemaWildcardPtr 6256 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6257 xmlSchemaPtr schema, xmlNodePtr node); 6258 6259 /** 6260 * xmlSchemaPValAttrNodeValue: 6261 * 6262 * @ctxt: a schema parser context 6263 * @ownerDes: the designation of the parent element 6264 * @ownerItem: the schema object owner if existent 6265 * @attr: the schema attribute node being validated 6266 * @value: the value 6267 * @type: the built-in type to be validated against 6268 * 6269 * Validates a value against the given built-in type. 6270 * This one is intended to be used internally for validation 6271 * of schema attribute values during parsing of the schema. 6272 * 6273 * Returns 0 if the value is valid, a positive error code 6274 * number otherwise and -1 in case of an internal or API error. 6275 */ 6276 static int 6277 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6278 xmlSchemaBasicItemPtr ownerItem, 6279 xmlAttrPtr attr, 6280 const xmlChar *value, 6281 xmlSchemaTypePtr type) 6282 { 6283 6284 int ret = 0; 6285 6286 /* 6287 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6288 * one is really meant to be used internally, so better not. 6289 */ 6290 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6291 return (-1); 6292 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6293 PERROR_INT("xmlSchemaPValAttrNodeValue", 6294 "the given type is not a built-in type"); 6295 return (-1); 6296 } 6297 switch (type->builtInType) { 6298 case XML_SCHEMAS_NCNAME: 6299 case XML_SCHEMAS_QNAME: 6300 case XML_SCHEMAS_ANYURI: 6301 case XML_SCHEMAS_TOKEN: 6302 case XML_SCHEMAS_LANGUAGE: 6303 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6304 (xmlNodePtr) attr); 6305 break; 6306 default: { 6307 PERROR_INT("xmlSchemaPValAttrNodeValue", 6308 "validation using the given type is not supported while " 6309 "parsing a schema"); 6310 return (-1); 6311 } 6312 } 6313 /* 6314 * TODO: Should we use the S4S error codes instead? 6315 */ 6316 if (ret < 0) { 6317 PERROR_INT("xmlSchemaPValAttrNodeValue", 6318 "failed to validate a schema attribute value"); 6319 return (-1); 6320 } else if (ret > 0) { 6321 if (WXS_IS_LIST(type)) 6322 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6323 else 6324 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6325 xmlSchemaPSimpleTypeErr(pctxt, 6326 ret, ownerItem, (xmlNodePtr) attr, 6327 type, NULL, value, NULL, NULL, NULL); 6328 } 6329 return (ret); 6330 } 6331 6332 /** 6333 * xmlSchemaPValAttrNode: 6334 * 6335 * @ctxt: a schema parser context 6336 * @ownerDes: the designation of the parent element 6337 * @ownerItem: the schema object owner if existent 6338 * @attr: the schema attribute node being validated 6339 * @type: the built-in type to be validated against 6340 * @value: the resulting value if any 6341 * 6342 * Extracts and validates a value against the given built-in type. 6343 * This one is intended to be used internally for validation 6344 * of schema attribute values during parsing of the schema. 6345 * 6346 * Returns 0 if the value is valid, a positive error code 6347 * number otherwise and -1 in case of an internal or API error. 6348 */ 6349 static int 6350 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6351 xmlSchemaBasicItemPtr ownerItem, 6352 xmlAttrPtr attr, 6353 xmlSchemaTypePtr type, 6354 const xmlChar **value) 6355 { 6356 const xmlChar *val; 6357 6358 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6359 return (-1); 6360 6361 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6362 if (value != NULL) 6363 *value = val; 6364 6365 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6366 val, type)); 6367 } 6368 6369 /** 6370 * xmlSchemaPValAttr: 6371 * 6372 * @ctxt: a schema parser context 6373 * @node: the element node of the attribute 6374 * @ownerDes: the designation of the parent element 6375 * @ownerItem: the schema object owner if existent 6376 * @ownerElem: the owner element node 6377 * @name: the name of the schema attribute node 6378 * @type: the built-in type to be validated against 6379 * @value: the resulting value if any 6380 * 6381 * Extracts and validates a value against the given built-in type. 6382 * This one is intended to be used internally for validation 6383 * of schema attribute values during parsing of the schema. 6384 * 6385 * Returns 0 if the value is valid, a positive error code 6386 * number otherwise and -1 in case of an internal or API error. 6387 */ 6388 static int 6389 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6390 xmlSchemaBasicItemPtr ownerItem, 6391 xmlNodePtr ownerElem, 6392 const char *name, 6393 xmlSchemaTypePtr type, 6394 const xmlChar **value) 6395 { 6396 xmlAttrPtr attr; 6397 6398 if ((ctxt == NULL) || (type == NULL)) { 6399 if (value != NULL) 6400 *value = NULL; 6401 return (-1); 6402 } 6403 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6404 if (value != NULL) 6405 *value = NULL; 6406 xmlSchemaPErr(ctxt, ownerElem, 6407 XML_SCHEMAP_INTERNAL, 6408 "Internal error: xmlSchemaPValAttr, the given " 6409 "type '%s' is not a built-in type.\n", 6410 type->name, NULL); 6411 return (-1); 6412 } 6413 attr = xmlSchemaGetPropNode(ownerElem, name); 6414 if (attr == NULL) { 6415 if (value != NULL) 6416 *value = NULL; 6417 return (0); 6418 } 6419 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6420 type, value)); 6421 } 6422 6423 static int 6424 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6425 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6426 xmlNodePtr node, 6427 xmlAttrPtr attr, 6428 const xmlChar *namespaceName) 6429 { 6430 /* TODO: Pointer comparison instead? */ 6431 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6432 return (0); 6433 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6434 return (0); 6435 /* 6436 * Check if the referenced namespace was <import>ed. 6437 */ 6438 if (WXS_BUCKET(pctxt)->relations != NULL) { 6439 xmlSchemaSchemaRelationPtr rel; 6440 6441 rel = WXS_BUCKET(pctxt)->relations; 6442 do { 6443 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6444 xmlStrEqual(namespaceName, rel->importNamespace)) 6445 return (0); 6446 rel = rel->next; 6447 } while (rel != NULL); 6448 } 6449 /* 6450 * No matching <import>ed namespace found. 6451 */ 6452 { 6453 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6454 6455 if (namespaceName == NULL) 6456 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6457 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6458 "References from this schema to components in no " 6459 "namespace are not allowed, since not indicated by an " 6460 "import statement", NULL, NULL); 6461 else 6462 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6463 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6464 "References from this schema to components in the " 6465 "namespace '%s' are not allowed, since not indicated by an " 6466 "import statement", namespaceName, NULL); 6467 } 6468 return (XML_SCHEMAP_SRC_RESOLVE); 6469 } 6470 6471 /** 6472 * xmlSchemaParseLocalAttributes: 6473 * @ctxt: a schema validation context 6474 * @schema: the schema being built 6475 * @node: a subtree containing XML Schema informations 6476 * @type: the hosting type where the attributes will be anchored 6477 * 6478 * Parses attribute uses and attribute declarations and 6479 * attribute group references. 6480 */ 6481 static int 6482 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6483 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6484 int parentType, int *hasRefs) 6485 { 6486 void *item; 6487 6488 while ((IS_SCHEMA((*child), "attribute")) || 6489 (IS_SCHEMA((*child), "attributeGroup"))) { 6490 if (IS_SCHEMA((*child), "attribute")) { 6491 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6492 *list, parentType); 6493 } else { 6494 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6495 if ((item != NULL) && (hasRefs != NULL)) 6496 *hasRefs = 1; 6497 } 6498 if (item != NULL) { 6499 if (*list == NULL) { 6500 /* TODO: Customize grow factor. */ 6501 *list = xmlSchemaItemListCreate(); 6502 if (*list == NULL) 6503 return(-1); 6504 } 6505 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6506 return(-1); 6507 } 6508 *child = (*child)->next; 6509 } 6510 return (0); 6511 } 6512 6513 /** 6514 * xmlSchemaParseAnnotation: 6515 * @ctxt: a schema validation context 6516 * @schema: the schema being built 6517 * @node: a subtree containing XML Schema informations 6518 * 6519 * parse a XML schema Attrribute declaration 6520 * *WARNING* this interface is highly subject to change 6521 * 6522 * Returns -1 in case of error, 0 if the declaration is improper and 6523 * 1 in case of success. 6524 */ 6525 static xmlSchemaAnnotPtr 6526 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6527 { 6528 xmlSchemaAnnotPtr ret; 6529 xmlNodePtr child = NULL; 6530 xmlAttrPtr attr; 6531 int barked = 0; 6532 6533 /* 6534 * INFO: S4S completed. 6535 */ 6536 /* 6537 * id = ID 6538 * {any attributes with non-schema namespace . . .}> 6539 * Content: (appinfo | documentation)* 6540 */ 6541 if ((ctxt == NULL) || (node == NULL)) 6542 return (NULL); 6543 if (needed) 6544 ret = xmlSchemaNewAnnot(ctxt, node); 6545 else 6546 ret = NULL; 6547 attr = node->properties; 6548 while (attr != NULL) { 6549 if (((attr->ns == NULL) && 6550 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6551 ((attr->ns != NULL) && 6552 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6553 6554 xmlSchemaPIllegalAttrErr(ctxt, 6555 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6556 } 6557 attr = attr->next; 6558 } 6559 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6560 /* 6561 * And now for the children... 6562 */ 6563 child = node->children; 6564 while (child != NULL) { 6565 if (IS_SCHEMA(child, "appinfo")) { 6566 /* TODO: make available the content of "appinfo". */ 6567 /* 6568 * source = anyURI 6569 * {any attributes with non-schema namespace . . .}> 6570 * Content: ({any})* 6571 */ 6572 attr = child->properties; 6573 while (attr != NULL) { 6574 if (((attr->ns == NULL) && 6575 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6576 ((attr->ns != NULL) && 6577 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6578 6579 xmlSchemaPIllegalAttrErr(ctxt, 6580 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6581 } 6582 attr = attr->next; 6583 } 6584 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6585 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6586 child = child->next; 6587 } else if (IS_SCHEMA(child, "documentation")) { 6588 /* TODO: make available the content of "documentation". */ 6589 /* 6590 * source = anyURI 6591 * {any attributes with non-schema namespace . . .}> 6592 * Content: ({any})* 6593 */ 6594 attr = child->properties; 6595 while (attr != NULL) { 6596 if (attr->ns == NULL) { 6597 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6598 xmlSchemaPIllegalAttrErr(ctxt, 6599 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6600 } 6601 } else { 6602 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6603 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6604 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6605 6606 xmlSchemaPIllegalAttrErr(ctxt, 6607 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6608 } 6609 } 6610 attr = attr->next; 6611 } 6612 /* 6613 * Attribute "xml:lang". 6614 */ 6615 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6616 if (attr != NULL) 6617 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6618 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6619 child = child->next; 6620 } else { 6621 if (!barked) 6622 xmlSchemaPContentErr(ctxt, 6623 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6624 NULL, node, child, NULL, "(appinfo | documentation)*"); 6625 barked = 1; 6626 child = child->next; 6627 } 6628 } 6629 6630 return (ret); 6631 } 6632 6633 /** 6634 * xmlSchemaParseFacet: 6635 * @ctxt: a schema validation context 6636 * @schema: the schema being built 6637 * @node: a subtree containing XML Schema informations 6638 * 6639 * parse a XML schema Facet declaration 6640 * *WARNING* this interface is highly subject to change 6641 * 6642 * Returns the new type structure or NULL in case of error 6643 */ 6644 static xmlSchemaFacetPtr 6645 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6646 xmlNodePtr node) 6647 { 6648 xmlSchemaFacetPtr facet; 6649 xmlNodePtr child = NULL; 6650 const xmlChar *value; 6651 6652 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6653 return (NULL); 6654 6655 facet = xmlSchemaNewFacet(); 6656 if (facet == NULL) { 6657 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6658 return (NULL); 6659 } 6660 facet->node = node; 6661 value = xmlSchemaGetProp(ctxt, node, "value"); 6662 if (value == NULL) { 6663 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6664 "Facet %s has no value\n", node->name, NULL); 6665 xmlSchemaFreeFacet(facet); 6666 return (NULL); 6667 } 6668 if (IS_SCHEMA(node, "minInclusive")) { 6669 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6670 } else if (IS_SCHEMA(node, "minExclusive")) { 6671 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6672 } else if (IS_SCHEMA(node, "maxInclusive")) { 6673 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6674 } else if (IS_SCHEMA(node, "maxExclusive")) { 6675 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6676 } else if (IS_SCHEMA(node, "totalDigits")) { 6677 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6678 } else if (IS_SCHEMA(node, "fractionDigits")) { 6679 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6680 } else if (IS_SCHEMA(node, "pattern")) { 6681 facet->type = XML_SCHEMA_FACET_PATTERN; 6682 } else if (IS_SCHEMA(node, "enumeration")) { 6683 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6684 } else if (IS_SCHEMA(node, "whiteSpace")) { 6685 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6686 } else if (IS_SCHEMA(node, "length")) { 6687 facet->type = XML_SCHEMA_FACET_LENGTH; 6688 } else if (IS_SCHEMA(node, "maxLength")) { 6689 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6690 } else if (IS_SCHEMA(node, "minLength")) { 6691 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6692 } else { 6693 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6694 "Unknown facet type %s\n", node->name, NULL); 6695 xmlSchemaFreeFacet(facet); 6696 return (NULL); 6697 } 6698 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6699 facet->value = value; 6700 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6701 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6702 const xmlChar *fixed; 6703 6704 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6705 if (fixed != NULL) { 6706 if (xmlStrEqual(fixed, BAD_CAST "true")) 6707 facet->fixed = 1; 6708 } 6709 } 6710 child = node->children; 6711 6712 if (IS_SCHEMA(child, "annotation")) { 6713 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6714 child = child->next; 6715 } 6716 if (child != NULL) { 6717 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6718 "Facet %s has unexpected child content\n", 6719 node->name, NULL); 6720 } 6721 return (facet); 6722 } 6723 6724 /** 6725 * xmlSchemaParseWildcardNs: 6726 * @ctxt: a schema parser context 6727 * @wildc: the wildcard, already created 6728 * @node: a subtree containing XML Schema informations 6729 * 6730 * Parses the attribute "processContents" and "namespace" 6731 * of a xsd:anyAttribute and xsd:any. 6732 * *WARNING* this interface is highly subject to change 6733 * 6734 * Returns 0 if everything goes fine, a positive error code 6735 * if something is not valid and -1 if an internal error occurs. 6736 */ 6737 static int 6738 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6739 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6740 xmlSchemaWildcardPtr wildc, 6741 xmlNodePtr node) 6742 { 6743 const xmlChar *pc, *ns, *dictnsItem; 6744 int ret = 0; 6745 xmlChar *nsItem; 6746 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6747 xmlAttrPtr attr; 6748 6749 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6750 if ((pc == NULL) 6751 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6752 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6753 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6754 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6755 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6756 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6757 } else { 6758 xmlSchemaPSimpleTypeErr(ctxt, 6759 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6760 NULL, node, 6761 NULL, "(strict | skip | lax)", pc, 6762 NULL, NULL, NULL); 6763 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6764 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6765 } 6766 /* 6767 * Build the namespace constraints. 6768 */ 6769 attr = xmlSchemaGetPropNode(node, "namespace"); 6770 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6771 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6772 wildc->any = 1; 6773 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6774 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6775 if (wildc->negNsSet == NULL) { 6776 return (-1); 6777 } 6778 wildc->negNsSet->value = ctxt->targetNamespace; 6779 } else { 6780 const xmlChar *end, *cur; 6781 6782 cur = ns; 6783 do { 6784 while (IS_BLANK_CH(*cur)) 6785 cur++; 6786 end = cur; 6787 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6788 end++; 6789 if (end == cur) 6790 break; 6791 nsItem = xmlStrndup(cur, end - cur); 6792 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6793 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6794 xmlSchemaPSimpleTypeErr(ctxt, 6795 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6796 NULL, (xmlNodePtr) attr, 6797 NULL, 6798 "((##any | ##other) | List of (xs:anyURI | " 6799 "(##targetNamespace | ##local)))", 6800 nsItem, NULL, NULL, NULL); 6801 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6802 } else { 6803 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6804 dictnsItem = ctxt->targetNamespace; 6805 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6806 dictnsItem = NULL; 6807 } else { 6808 /* 6809 * Validate the item (anyURI). 6810 */ 6811 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6812 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6813 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6814 } 6815 /* 6816 * Avoid dublicate namespaces. 6817 */ 6818 tmp = wildc->nsSet; 6819 while (tmp != NULL) { 6820 if (dictnsItem == tmp->value) 6821 break; 6822 tmp = tmp->next; 6823 } 6824 if (tmp == NULL) { 6825 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6826 if (tmp == NULL) { 6827 xmlFree(nsItem); 6828 return (-1); 6829 } 6830 tmp->value = dictnsItem; 6831 tmp->next = NULL; 6832 if (wildc->nsSet == NULL) 6833 wildc->nsSet = tmp; 6834 else if (lastNs != NULL) 6835 lastNs->next = tmp; 6836 lastNs = tmp; 6837 } 6838 6839 } 6840 xmlFree(nsItem); 6841 cur = end; 6842 } while (*cur != 0); 6843 } 6844 return (ret); 6845 } 6846 6847 static int 6848 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6849 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6850 xmlNodePtr node, 6851 int minOccurs, 6852 int maxOccurs) { 6853 6854 if ((maxOccurs == 0) && ( minOccurs == 0)) 6855 return (0); 6856 if (maxOccurs != UNBOUNDED) { 6857 /* 6858 * TODO: Maybe we should better not create the particle, 6859 * if min/max is invalid, since it could confuse the build of the 6860 * content model. 6861 */ 6862 /* 6863 * 3.9.6 Schema Component Constraint: Particle Correct 6864 * 6865 */ 6866 if (maxOccurs < 1) { 6867 /* 6868 * 2.2 {max occurs} must be greater than or equal to 1. 6869 */ 6870 xmlSchemaPCustomAttrErr(ctxt, 6871 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6872 NULL, NULL, 6873 xmlSchemaGetPropNode(node, "maxOccurs"), 6874 "The value must be greater than or equal to 1"); 6875 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6876 } else if (minOccurs > maxOccurs) { 6877 /* 6878 * 2.1 {min occurs} must not be greater than {max occurs}. 6879 */ 6880 xmlSchemaPCustomAttrErr(ctxt, 6881 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6882 NULL, NULL, 6883 xmlSchemaGetPropNode(node, "minOccurs"), 6884 "The value must not be greater than the value of 'maxOccurs'"); 6885 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6886 } 6887 } 6888 return (0); 6889 } 6890 6891 /** 6892 * xmlSchemaParseAny: 6893 * @ctxt: a schema validation context 6894 * @schema: the schema being built 6895 * @node: a subtree containing XML Schema informations 6896 * 6897 * Parsea a XML schema <any> element. A particle and wildcard 6898 * will be created (except if minOccurs==maxOccurs==0, in this case 6899 * nothing will be created). 6900 * *WARNING* this interface is highly subject to change 6901 * 6902 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6903 */ 6904 static xmlSchemaParticlePtr 6905 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6906 xmlNodePtr node) 6907 { 6908 xmlSchemaParticlePtr particle; 6909 xmlNodePtr child = NULL; 6910 xmlSchemaWildcardPtr wild; 6911 int min, max; 6912 xmlAttrPtr attr; 6913 xmlSchemaAnnotPtr annot = NULL; 6914 6915 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6916 return (NULL); 6917 /* 6918 * Check for illegal attributes. 6919 */ 6920 attr = node->properties; 6921 while (attr != NULL) { 6922 if (attr->ns == NULL) { 6923 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6924 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6925 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6926 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6927 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6928 xmlSchemaPIllegalAttrErr(ctxt, 6929 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6930 } 6931 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6932 xmlSchemaPIllegalAttrErr(ctxt, 6933 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6934 } 6935 attr = attr->next; 6936 } 6937 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6938 /* 6939 * minOccurs/maxOccurs. 6940 */ 6941 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6942 "(xs:nonNegativeInteger | unbounded)"); 6943 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6944 "xs:nonNegativeInteger"); 6945 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6946 /* 6947 * Create & parse the wildcard. 6948 */ 6949 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6950 if (wild == NULL) 6951 return (NULL); 6952 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6953 /* 6954 * And now for the children... 6955 */ 6956 child = node->children; 6957 if (IS_SCHEMA(child, "annotation")) { 6958 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6959 child = child->next; 6960 } 6961 if (child != NULL) { 6962 xmlSchemaPContentErr(ctxt, 6963 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6964 NULL, node, child, 6965 NULL, "(annotation?)"); 6966 } 6967 /* 6968 * No component if minOccurs==maxOccurs==0. 6969 */ 6970 if ((min == 0) && (max == 0)) { 6971 /* Don't free the wildcard, since it's already on the list. */ 6972 return (NULL); 6973 } 6974 /* 6975 * Create the particle. 6976 */ 6977 particle = xmlSchemaAddParticle(ctxt, node, min, max); 6978 if (particle == NULL) 6979 return (NULL); 6980 particle->annot = annot; 6981 particle->children = (xmlSchemaTreeItemPtr) wild; 6982 6983 return (particle); 6984 } 6985 6986 /** 6987 * xmlSchemaParseNotation: 6988 * @ctxt: a schema validation context 6989 * @schema: the schema being built 6990 * @node: a subtree containing XML Schema informations 6991 * 6992 * parse a XML schema Notation declaration 6993 * 6994 * Returns the new structure or NULL in case of error 6995 */ 6996 static xmlSchemaNotationPtr 6997 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6998 xmlNodePtr node) 6999 { 7000 const xmlChar *name; 7001 xmlSchemaNotationPtr ret; 7002 xmlNodePtr child = NULL; 7003 7004 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7005 return (NULL); 7006 name = xmlSchemaGetProp(ctxt, node, "name"); 7007 if (name == NULL) { 7008 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 7009 "Notation has no name\n", NULL, NULL); 7010 return (NULL); 7011 } 7012 ret = xmlSchemaAddNotation(ctxt, schema, name, 7013 ctxt->targetNamespace, node); 7014 if (ret == NULL) 7015 return (NULL); 7016 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7017 7018 child = node->children; 7019 if (IS_SCHEMA(child, "annotation")) { 7020 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7021 child = child->next; 7022 } 7023 if (child != NULL) { 7024 xmlSchemaPContentErr(ctxt, 7025 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7026 NULL, node, child, 7027 NULL, "(annotation?)"); 7028 } 7029 7030 return (ret); 7031 } 7032 7033 /** 7034 * xmlSchemaParseAnyAttribute: 7035 * @ctxt: a schema validation context 7036 * @schema: the schema being built 7037 * @node: a subtree containing XML Schema informations 7038 * 7039 * parse a XML schema AnyAttrribute declaration 7040 * *WARNING* this interface is highly subject to change 7041 * 7042 * Returns a wildcard or NULL. 7043 */ 7044 static xmlSchemaWildcardPtr 7045 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7046 xmlSchemaPtr schema, xmlNodePtr node) 7047 { 7048 xmlSchemaWildcardPtr ret; 7049 xmlNodePtr child = NULL; 7050 xmlAttrPtr attr; 7051 7052 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7053 return (NULL); 7054 7055 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7056 node); 7057 if (ret == NULL) { 7058 return (NULL); 7059 } 7060 /* 7061 * Check for illegal attributes. 7062 */ 7063 attr = node->properties; 7064 while (attr != NULL) { 7065 if (attr->ns == NULL) { 7066 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7067 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7068 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7069 xmlSchemaPIllegalAttrErr(ctxt, 7070 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7071 } 7072 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7073 xmlSchemaPIllegalAttrErr(ctxt, 7074 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7075 } 7076 attr = attr->next; 7077 } 7078 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7079 /* 7080 * Parse the namespace list. 7081 */ 7082 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7083 return (NULL); 7084 /* 7085 * And now for the children... 7086 */ 7087 child = node->children; 7088 if (IS_SCHEMA(child, "annotation")) { 7089 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7090 child = child->next; 7091 } 7092 if (child != NULL) { 7093 xmlSchemaPContentErr(ctxt, 7094 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7095 NULL, node, child, 7096 NULL, "(annotation?)"); 7097 } 7098 7099 return (ret); 7100 } 7101 7102 7103 /** 7104 * xmlSchemaParseAttribute: 7105 * @ctxt: a schema validation context 7106 * @schema: the schema being built 7107 * @node: a subtree containing XML Schema informations 7108 * 7109 * parse a XML schema Attrribute declaration 7110 * *WARNING* this interface is highly subject to change 7111 * 7112 * Returns the attribute declaration. 7113 */ 7114 static xmlSchemaBasicItemPtr 7115 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7116 xmlSchemaPtr schema, 7117 xmlNodePtr node, 7118 xmlSchemaItemListPtr uses, 7119 int parentType) 7120 { 7121 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7122 xmlSchemaAttributeUsePtr use = NULL; 7123 xmlNodePtr child = NULL; 7124 xmlAttrPtr attr; 7125 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7126 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7127 int nberrors, hasForm = 0, defValueType = 0; 7128 7129 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7130 #define WXS_ATTR_DEF_VAL_FIXED 2 7131 7132 /* 7133 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7134 */ 7135 7136 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7137 return (NULL); 7138 attr = xmlSchemaGetPropNode(node, "ref"); 7139 if (attr != NULL) { 7140 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7141 NULL, attr, &tmpNs, &tmpName) != 0) { 7142 return (NULL); 7143 } 7144 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7145 return(NULL); 7146 isRef = 1; 7147 } 7148 nberrors = pctxt->nberrors; 7149 /* 7150 * Check for illegal attributes. 7151 */ 7152 attr = node->properties; 7153 while (attr != NULL) { 7154 if (attr->ns == NULL) { 7155 if (isRef) { 7156 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7157 xmlSchemaPValAttrNodeID(pctxt, attr); 7158 goto attr_next; 7159 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7160 goto attr_next; 7161 } 7162 } else { 7163 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7164 goto attr_next; 7165 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7166 xmlSchemaPValAttrNodeID(pctxt, attr); 7167 goto attr_next; 7168 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7169 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7170 attr, &tmpNs, &tmpName); 7171 goto attr_next; 7172 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7173 /* 7174 * Evaluate the target namespace 7175 */ 7176 hasForm = 1; 7177 attrValue = xmlSchemaGetNodeContent(pctxt, 7178 (xmlNodePtr) attr); 7179 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7180 ns = pctxt->targetNamespace; 7181 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7182 { 7183 xmlSchemaPSimpleTypeErr(pctxt, 7184 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7185 NULL, (xmlNodePtr) attr, 7186 NULL, "(qualified | unqualified)", 7187 attrValue, NULL, NULL, NULL); 7188 } 7189 goto attr_next; 7190 } 7191 } 7192 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7193 7194 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7195 /* TODO: Maybe we need to normalize the value beforehand. */ 7196 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7197 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7198 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7199 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7200 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7201 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7202 else { 7203 xmlSchemaPSimpleTypeErr(pctxt, 7204 XML_SCHEMAP_INVALID_ATTR_USE, 7205 NULL, (xmlNodePtr) attr, 7206 NULL, "(optional | prohibited | required)", 7207 attrValue, NULL, NULL, NULL); 7208 } 7209 goto attr_next; 7210 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7211 /* 7212 * 3.2.3 : 1 7213 * default and fixed must not both be present. 7214 */ 7215 if (defValue) { 7216 xmlSchemaPMutualExclAttrErr(pctxt, 7217 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7218 NULL, attr, "default", "fixed"); 7219 } else { 7220 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7221 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7222 } 7223 goto attr_next; 7224 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7225 /* 7226 * 3.2.3 : 1 7227 * default and fixed must not both be present. 7228 */ 7229 if (defValue) { 7230 xmlSchemaPMutualExclAttrErr(pctxt, 7231 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7232 NULL, attr, "default", "fixed"); 7233 } else { 7234 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7235 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7236 } 7237 goto attr_next; 7238 } 7239 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7240 goto attr_next; 7241 7242 xmlSchemaPIllegalAttrErr(pctxt, 7243 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7244 7245 attr_next: 7246 attr = attr->next; 7247 } 7248 /* 7249 * 3.2.3 : 2 7250 * If default and use are both present, use must have 7251 * the actual value optional. 7252 */ 7253 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7254 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7255 xmlSchemaPSimpleTypeErr(pctxt, 7256 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7257 NULL, node, NULL, 7258 "(optional | prohibited | required)", NULL, 7259 "The value of the attribute 'use' must be 'optional' " 7260 "if the attribute 'default' is present", 7261 NULL, NULL); 7262 } 7263 /* 7264 * We want correct attributes. 7265 */ 7266 if (nberrors != pctxt->nberrors) 7267 return(NULL); 7268 if (! isRef) { 7269 xmlSchemaAttributePtr attrDecl; 7270 7271 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7272 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7273 ns = pctxt->targetNamespace; 7274 /* 7275 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7276 * TODO: Move this to the component layer. 7277 */ 7278 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7279 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7280 XML_SCHEMAP_NO_XSI, 7281 node, NULL, 7282 "The target namespace must not match '%s'", 7283 xmlSchemaInstanceNs, NULL); 7284 } 7285 attr = xmlSchemaGetPropNode(node, "name"); 7286 if (attr == NULL) { 7287 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7288 NULL, node, "name", NULL); 7289 return (NULL); 7290 } 7291 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7292 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7293 return (NULL); 7294 } 7295 /* 7296 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7297 * TODO: Move this to the component layer. 7298 */ 7299 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7300 xmlSchemaPSimpleTypeErr(pctxt, 7301 XML_SCHEMAP_NO_XMLNS, 7302 NULL, (xmlNodePtr) attr, 7303 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7304 "The value of the attribute must not match 'xmlns'", 7305 NULL, NULL); 7306 return (NULL); 7307 } 7308 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7309 goto check_children; 7310 /* 7311 * Create the attribute use component. 7312 */ 7313 use = xmlSchemaAddAttributeUse(pctxt, node); 7314 if (use == NULL) 7315 return(NULL); 7316 use->occurs = occurs; 7317 /* 7318 * Create the attribute declaration. 7319 */ 7320 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7321 if (attrDecl == NULL) 7322 return (NULL); 7323 if (tmpName != NULL) { 7324 attrDecl->typeName = tmpName; 7325 attrDecl->typeNs = tmpNs; 7326 } 7327 use->attrDecl = attrDecl; 7328 /* 7329 * Value constraint. 7330 */ 7331 if (defValue != NULL) { 7332 attrDecl->defValue = defValue; 7333 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7334 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7335 } 7336 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7337 xmlSchemaQNameRefPtr ref; 7338 7339 /* 7340 * Create the attribute use component. 7341 */ 7342 use = xmlSchemaAddAttributeUse(pctxt, node); 7343 if (use == NULL) 7344 return(NULL); 7345 /* 7346 * We need to resolve the reference at later stage. 7347 */ 7348 WXS_ADD_PENDING(pctxt, use); 7349 use->occurs = occurs; 7350 /* 7351 * Create a QName reference to the attribute declaration. 7352 */ 7353 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7354 tmpName, tmpNs); 7355 if (ref == NULL) 7356 return(NULL); 7357 /* 7358 * Assign the reference. This will be substituted for the 7359 * referenced attribute declaration when the QName is resolved. 7360 */ 7361 use->attrDecl = WXS_ATTR_CAST ref; 7362 /* 7363 * Value constraint. 7364 */ 7365 if (defValue != NULL) 7366 use->defValue = defValue; 7367 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7368 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7369 } 7370 7371 check_children: 7372 /* 7373 * And now for the children... 7374 */ 7375 child = node->children; 7376 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7377 xmlSchemaAttributeUseProhibPtr prohib; 7378 7379 if (IS_SCHEMA(child, "annotation")) { 7380 xmlSchemaParseAnnotation(pctxt, child, 0); 7381 child = child->next; 7382 } 7383 if (child != NULL) { 7384 xmlSchemaPContentErr(pctxt, 7385 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7386 NULL, node, child, NULL, 7387 "(annotation?)"); 7388 } 7389 /* 7390 * Check for pointlessness of attribute prohibitions. 7391 */ 7392 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7393 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7394 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7395 node, NULL, 7396 "Skipping attribute use prohibition, since it is " 7397 "pointless inside an <attributeGroup>", 7398 NULL, NULL, NULL); 7399 return(NULL); 7400 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7401 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7402 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7403 node, NULL, 7404 "Skipping attribute use prohibition, since it is " 7405 "pointless when extending a type", 7406 NULL, NULL, NULL); 7407 return(NULL); 7408 } 7409 if (! isRef) { 7410 tmpName = name; 7411 tmpNs = ns; 7412 } 7413 /* 7414 * Check for duplicate attribute prohibitions. 7415 */ 7416 if (uses) { 7417 int i; 7418 7419 for (i = 0; i < uses->nbItems; i++) { 7420 use = uses->items[i]; 7421 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7422 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7423 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7424 { 7425 xmlChar *str = NULL; 7426 7427 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7428 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7429 node, NULL, 7430 "Skipping duplicate attribute use prohibition '%s'", 7431 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7432 NULL, NULL); 7433 FREE_AND_NULL(str) 7434 return(NULL); 7435 } 7436 } 7437 } 7438 /* 7439 * Create the attribute prohibition helper component. 7440 */ 7441 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7442 if (prohib == NULL) 7443 return(NULL); 7444 prohib->node = node; 7445 prohib->name = tmpName; 7446 prohib->targetNamespace = tmpNs; 7447 if (isRef) { 7448 /* 7449 * We need at least to resolve to the attribute declaration. 7450 */ 7451 WXS_ADD_PENDING(pctxt, prohib); 7452 } 7453 return(WXS_BASIC_CAST prohib); 7454 } else { 7455 if (IS_SCHEMA(child, "annotation")) { 7456 /* 7457 * TODO: Should this go into the attr decl? 7458 */ 7459 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7460 child = child->next; 7461 } 7462 if (isRef) { 7463 if (child != NULL) { 7464 if (IS_SCHEMA(child, "simpleType")) 7465 /* 7466 * 3.2.3 : 3.2 7467 * If ref is present, then all of <simpleType>, 7468 * form and type must be absent. 7469 */ 7470 xmlSchemaPContentErr(pctxt, 7471 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7472 NULL, node, child, NULL, 7473 "(annotation?)"); 7474 else 7475 xmlSchemaPContentErr(pctxt, 7476 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7477 NULL, node, child, NULL, 7478 "(annotation?)"); 7479 } 7480 } else { 7481 if (IS_SCHEMA(child, "simpleType")) { 7482 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7483 /* 7484 * 3.2.3 : 4 7485 * type and <simpleType> must not both be present. 7486 */ 7487 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7488 NULL, node, child, 7489 "The attribute 'type' and the <simpleType> child " 7490 "are mutually exclusive", NULL); 7491 } else 7492 WXS_ATTRUSE_TYPEDEF(use) = 7493 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7494 child = child->next; 7495 } 7496 if (child != NULL) 7497 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7498 NULL, node, child, NULL, 7499 "(annotation?, simpleType?)"); 7500 } 7501 } 7502 return (WXS_BASIC_CAST use); 7503 } 7504 7505 7506 static xmlSchemaAttributePtr 7507 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7508 xmlSchemaPtr schema, 7509 xmlNodePtr node) 7510 { 7511 const xmlChar *attrValue; 7512 xmlSchemaAttributePtr ret; 7513 xmlNodePtr child = NULL; 7514 xmlAttrPtr attr; 7515 7516 /* 7517 * Note that the w3c spec assumes the schema to be validated with schema 7518 * for schemas beforehand. 7519 * 7520 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7521 */ 7522 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7523 return (NULL); 7524 /* 7525 * 3.2.3 : 3.1 7526 * One of ref or name must be present, but not both 7527 */ 7528 attr = xmlSchemaGetPropNode(node, "name"); 7529 if (attr == NULL) { 7530 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7531 NULL, node, "name", NULL); 7532 return (NULL); 7533 } 7534 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7535 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7536 return (NULL); 7537 } 7538 /* 7539 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7540 * TODO: Move this to the component layer. 7541 */ 7542 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7543 xmlSchemaPSimpleTypeErr(pctxt, 7544 XML_SCHEMAP_NO_XMLNS, 7545 NULL, (xmlNodePtr) attr, 7546 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7547 "The value of the attribute must not match 'xmlns'", 7548 NULL, NULL); 7549 return (NULL); 7550 } 7551 /* 7552 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7553 * TODO: Move this to the component layer. 7554 * Or better leave it here and add it to the component layer 7555 * if we have a schema construction API. 7556 */ 7557 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7558 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7559 XML_SCHEMAP_NO_XSI, node, NULL, 7560 "The target namespace must not match '%s'", 7561 xmlSchemaInstanceNs, NULL); 7562 } 7563 7564 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7565 pctxt->targetNamespace, node, 1); 7566 if (ret == NULL) 7567 return (NULL); 7568 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7569 7570 /* 7571 * Check for illegal attributes. 7572 */ 7573 attr = node->properties; 7574 while (attr != NULL) { 7575 if (attr->ns == NULL) { 7576 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7577 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7578 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7579 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7580 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7581 { 7582 xmlSchemaPIllegalAttrErr(pctxt, 7583 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7584 } 7585 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7586 xmlSchemaPIllegalAttrErr(pctxt, 7587 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7588 } 7589 attr = attr->next; 7590 } 7591 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7592 node, "type", &ret->typeNs, &ret->typeName); 7593 7594 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7595 /* 7596 * Attribute "fixed". 7597 */ 7598 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7599 if (ret->defValue != NULL) 7600 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7601 /* 7602 * Attribute "default". 7603 */ 7604 attr = xmlSchemaGetPropNode(node, "default"); 7605 if (attr != NULL) { 7606 /* 7607 * 3.2.3 : 1 7608 * default and fixed must not both be present. 7609 */ 7610 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7611 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7612 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7613 } else 7614 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7615 } 7616 /* 7617 * And now for the children... 7618 */ 7619 child = node->children; 7620 if (IS_SCHEMA(child, "annotation")) { 7621 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7622 child = child->next; 7623 } 7624 if (IS_SCHEMA(child, "simpleType")) { 7625 if (ret->typeName != NULL) { 7626 /* 7627 * 3.2.3 : 4 7628 * type and <simpleType> must not both be present. 7629 */ 7630 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7631 NULL, node, child, 7632 "The attribute 'type' and the <simpleType> child " 7633 "are mutually exclusive", NULL); 7634 } else 7635 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7636 child = child->next; 7637 } 7638 if (child != NULL) 7639 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7640 NULL, node, child, NULL, 7641 "(annotation?, simpleType?)"); 7642 7643 return (ret); 7644 } 7645 7646 /** 7647 * xmlSchemaParseAttributeGroupRef: 7648 * @ctxt: a schema validation context 7649 * @schema: the schema being built 7650 * @node: a subtree containing XML Schema informations 7651 * 7652 * Parse an attribute group definition reference. 7653 * Note that a reference to an attribute group does not 7654 * correspond to any component at all. 7655 * *WARNING* this interface is highly subject to change 7656 * 7657 * Returns the attribute group or NULL in case of error. 7658 */ 7659 static xmlSchemaQNameRefPtr 7660 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7661 xmlSchemaPtr schema, 7662 xmlNodePtr node) 7663 { 7664 xmlSchemaQNameRefPtr ret; 7665 xmlNodePtr child = NULL; 7666 xmlAttrPtr attr; 7667 const xmlChar *refNs = NULL, *ref = NULL; 7668 7669 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7670 return (NULL); 7671 7672 attr = xmlSchemaGetPropNode(node, "ref"); 7673 if (attr == NULL) { 7674 xmlSchemaPMissingAttrErr(pctxt, 7675 XML_SCHEMAP_S4S_ATTR_MISSING, 7676 NULL, node, "ref", NULL); 7677 return (NULL); 7678 } 7679 xmlSchemaPValAttrNodeQName(pctxt, schema, 7680 NULL, attr, &refNs, &ref); 7681 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7682 return(NULL); 7683 7684 /* 7685 * Check for illegal attributes. 7686 */ 7687 attr = node->properties; 7688 while (attr != NULL) { 7689 if (attr->ns == NULL) { 7690 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7691 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7692 { 7693 xmlSchemaPIllegalAttrErr(pctxt, 7694 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7695 } 7696 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7697 xmlSchemaPIllegalAttrErr(pctxt, 7698 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7699 } 7700 attr = attr->next; 7701 } 7702 /* Attribute ID */ 7703 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7704 7705 /* 7706 * And now for the children... 7707 */ 7708 child = node->children; 7709 if (IS_SCHEMA(child, "annotation")) { 7710 /* 7711 * TODO: We do not have a place to store the annotation, do we? 7712 */ 7713 xmlSchemaParseAnnotation(pctxt, child, 0); 7714 child = child->next; 7715 } 7716 if (child != NULL) { 7717 xmlSchemaPContentErr(pctxt, 7718 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7719 NULL, node, child, NULL, 7720 "(annotation?)"); 7721 } 7722 7723 /* 7724 * Handle attribute group redefinitions. 7725 */ 7726 if (pctxt->isRedefine && pctxt->redef && 7727 (pctxt->redef->item->type == 7728 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7729 (ref == pctxt->redef->refName) && 7730 (refNs == pctxt->redef->refTargetNs)) 7731 { 7732 /* 7733 * SPEC src-redefine: 7734 * (7.1) "If it has an <attributeGroup> among its contents 7735 * the `actual value` of whose ref [attribute] is the same 7736 * as the `actual value` of its own name attribute plus 7737 * target namespace, then it must have exactly one such group." 7738 */ 7739 if (pctxt->redefCounter != 0) { 7740 xmlChar *str = NULL; 7741 7742 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7743 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7744 "The redefining attribute group definition " 7745 "'%s' must not contain more than one " 7746 "reference to the redefined definition", 7747 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7748 FREE_AND_NULL(str); 7749 return(NULL); 7750 } 7751 pctxt->redefCounter++; 7752 /* 7753 * URGENT TODO: How to ensure that the reference will not be 7754 * handled by the normal component resolution mechanism? 7755 */ 7756 ret = xmlSchemaNewQNameRef(pctxt, 7757 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7758 if (ret == NULL) 7759 return(NULL); 7760 ret->node = node; 7761 pctxt->redef->reference = WXS_BASIC_CAST ret; 7762 } else { 7763 /* 7764 * Create a QName-reference helper component. We will substitute this 7765 * component for the attribute uses of the referenced attribute group 7766 * definition. 7767 */ 7768 ret = xmlSchemaNewQNameRef(pctxt, 7769 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7770 if (ret == NULL) 7771 return(NULL); 7772 ret->node = node; 7773 /* Add to pending items, to be able to resolve the reference. */ 7774 WXS_ADD_PENDING(pctxt, ret); 7775 } 7776 return (ret); 7777 } 7778 7779 /** 7780 * xmlSchemaParseAttributeGroupDefinition: 7781 * @pctxt: a schema validation context 7782 * @schema: the schema being built 7783 * @node: a subtree containing XML Schema informations 7784 * 7785 * parse a XML schema Attribute Group declaration 7786 * *WARNING* this interface is highly subject to change 7787 * 7788 * Returns the attribute group definition or NULL in case of error. 7789 */ 7790 static xmlSchemaAttributeGroupPtr 7791 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7792 xmlSchemaPtr schema, 7793 xmlNodePtr node) 7794 { 7795 const xmlChar *name; 7796 xmlSchemaAttributeGroupPtr ret; 7797 xmlNodePtr child = NULL; 7798 xmlAttrPtr attr; 7799 int hasRefs = 0; 7800 7801 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7802 return (NULL); 7803 7804 attr = xmlSchemaGetPropNode(node, "name"); 7805 if (attr == NULL) { 7806 xmlSchemaPMissingAttrErr(pctxt, 7807 XML_SCHEMAP_S4S_ATTR_MISSING, 7808 NULL, node, "name", NULL); 7809 return (NULL); 7810 } 7811 /* 7812 * The name is crucial, exit if invalid. 7813 */ 7814 if (xmlSchemaPValAttrNode(pctxt, 7815 NULL, attr, 7816 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7817 return (NULL); 7818 } 7819 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7820 name, pctxt->targetNamespace, node); 7821 if (ret == NULL) 7822 return (NULL); 7823 /* 7824 * Check for illegal attributes. 7825 */ 7826 attr = node->properties; 7827 while (attr != NULL) { 7828 if (attr->ns == NULL) { 7829 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7830 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7831 { 7832 xmlSchemaPIllegalAttrErr(pctxt, 7833 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7834 } 7835 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7836 xmlSchemaPIllegalAttrErr(pctxt, 7837 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7838 } 7839 attr = attr->next; 7840 } 7841 /* Attribute ID */ 7842 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7843 /* 7844 * And now for the children... 7845 */ 7846 child = node->children; 7847 if (IS_SCHEMA(child, "annotation")) { 7848 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7849 child = child->next; 7850 } 7851 /* 7852 * Parse contained attribute decls/refs. 7853 */ 7854 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7855 (xmlSchemaItemListPtr *) &(ret->attrUses), 7856 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7857 return(NULL); 7858 if (hasRefs) 7859 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7860 /* 7861 * Parse the attribute wildcard. 7862 */ 7863 if (IS_SCHEMA(child, "anyAttribute")) { 7864 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7865 schema, child); 7866 child = child->next; 7867 } 7868 if (child != NULL) { 7869 xmlSchemaPContentErr(pctxt, 7870 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7871 NULL, node, child, NULL, 7872 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7873 } 7874 return (ret); 7875 } 7876 7877 /** 7878 * xmlSchemaPValAttrFormDefault: 7879 * @value: the value 7880 * @flags: the flags to be modified 7881 * @flagQualified: the specific flag for "qualified" 7882 * 7883 * Returns 0 if the value is valid, 1 otherwise. 7884 */ 7885 static int 7886 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7887 int *flags, 7888 int flagQualified) 7889 { 7890 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7891 if ((*flags & flagQualified) == 0) 7892 *flags |= flagQualified; 7893 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7894 return (1); 7895 7896 return (0); 7897 } 7898 7899 /** 7900 * xmlSchemaPValAttrBlockFinal: 7901 * @value: the value 7902 * @flags: the flags to be modified 7903 * @flagAll: the specific flag for "#all" 7904 * @flagExtension: the specific flag for "extension" 7905 * @flagRestriction: the specific flag for "restriction" 7906 * @flagSubstitution: the specific flag for "substitution" 7907 * @flagList: the specific flag for "list" 7908 * @flagUnion: the specific flag for "union" 7909 * 7910 * Validates the value of the attribute "final" and "block". The value 7911 * is converted into the specified flag values and returned in @flags. 7912 * 7913 * Returns 0 if the value is valid, 1 otherwise. 7914 */ 7915 7916 static int 7917 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7918 int *flags, 7919 int flagAll, 7920 int flagExtension, 7921 int flagRestriction, 7922 int flagSubstitution, 7923 int flagList, 7924 int flagUnion) 7925 { 7926 int ret = 0; 7927 7928 /* 7929 * TODO: This does not check for dublicate entries. 7930 */ 7931 if ((flags == NULL) || (value == NULL)) 7932 return (-1); 7933 if (value[0] == 0) 7934 return (0); 7935 if (xmlStrEqual(value, BAD_CAST "#all")) { 7936 if (flagAll != -1) 7937 *flags |= flagAll; 7938 else { 7939 if (flagExtension != -1) 7940 *flags |= flagExtension; 7941 if (flagRestriction != -1) 7942 *flags |= flagRestriction; 7943 if (flagSubstitution != -1) 7944 *flags |= flagSubstitution; 7945 if (flagList != -1) 7946 *flags |= flagList; 7947 if (flagUnion != -1) 7948 *flags |= flagUnion; 7949 } 7950 } else { 7951 const xmlChar *end, *cur = value; 7952 xmlChar *item; 7953 7954 do { 7955 while (IS_BLANK_CH(*cur)) 7956 cur++; 7957 end = cur; 7958 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7959 end++; 7960 if (end == cur) 7961 break; 7962 item = xmlStrndup(cur, end - cur); 7963 if (xmlStrEqual(item, BAD_CAST "extension")) { 7964 if (flagExtension != -1) { 7965 if ((*flags & flagExtension) == 0) 7966 *flags |= flagExtension; 7967 } else 7968 ret = 1; 7969 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7970 if (flagRestriction != -1) { 7971 if ((*flags & flagRestriction) == 0) 7972 *flags |= flagRestriction; 7973 } else 7974 ret = 1; 7975 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 7976 if (flagSubstitution != -1) { 7977 if ((*flags & flagSubstitution) == 0) 7978 *flags |= flagSubstitution; 7979 } else 7980 ret = 1; 7981 } else if (xmlStrEqual(item, BAD_CAST "list")) { 7982 if (flagList != -1) { 7983 if ((*flags & flagList) == 0) 7984 *flags |= flagList; 7985 } else 7986 ret = 1; 7987 } else if (xmlStrEqual(item, BAD_CAST "union")) { 7988 if (flagUnion != -1) { 7989 if ((*flags & flagUnion) == 0) 7990 *flags |= flagUnion; 7991 } else 7992 ret = 1; 7993 } else 7994 ret = 1; 7995 if (item != NULL) 7996 xmlFree(item); 7997 cur = end; 7998 } while ((ret == 0) && (*cur != 0)); 7999 } 8000 8001 return (ret); 8002 } 8003 8004 static int 8005 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 8006 xmlSchemaIDCPtr idc, 8007 xmlSchemaIDCSelectPtr selector, 8008 xmlAttrPtr attr, 8009 int isField) 8010 { 8011 xmlNodePtr node; 8012 8013 /* 8014 * c-selector-xpath: 8015 * Schema Component Constraint: Selector Value OK 8016 * 8017 * TODO: 1 The {selector} must be a valid XPath expression, as defined 8018 * in [XPath]. 8019 */ 8020 if (selector == NULL) { 8021 xmlSchemaPErr(ctxt, idc->node, 8022 XML_SCHEMAP_INTERNAL, 8023 "Internal error: xmlSchemaCheckCSelectorXPath, " 8024 "the selector is not specified.\n", NULL, NULL); 8025 return (-1); 8026 } 8027 if (attr == NULL) 8028 node = idc->node; 8029 else 8030 node = (xmlNodePtr) attr; 8031 if (selector->xpath == NULL) { 8032 xmlSchemaPCustomErr(ctxt, 8033 /* TODO: Adjust error code. */ 8034 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8035 NULL, node, 8036 "The XPath expression of the selector is not valid", NULL); 8037 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8038 } else { 8039 const xmlChar **nsArray = NULL; 8040 xmlNsPtr *nsList = NULL; 8041 /* 8042 * Compile the XPath expression. 8043 */ 8044 /* 8045 * TODO: We need the array of in-scope namespaces for compilation. 8046 * TODO: Call xmlPatterncompile with different options for selector/ 8047 * field. 8048 */ 8049 if (attr == NULL) 8050 nsList = NULL; 8051 else 8052 nsList = xmlGetNsList(attr->doc, attr->parent); 8053 /* 8054 * Build an array of prefixes and namespaces. 8055 */ 8056 if (nsList != NULL) { 8057 int i, count = 0; 8058 8059 for (i = 0; nsList[i] != NULL; i++) 8060 count++; 8061 8062 nsArray = (const xmlChar **) xmlMalloc( 8063 (count * 2 + 1) * sizeof(const xmlChar *)); 8064 if (nsArray == NULL) { 8065 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8066 NULL); 8067 xmlFree(nsList); 8068 return (-1); 8069 } 8070 for (i = 0; i < count; i++) { 8071 nsArray[2 * i] = nsList[i]->href; 8072 nsArray[2 * i + 1] = nsList[i]->prefix; 8073 } 8074 nsArray[count * 2] = NULL; 8075 xmlFree(nsList); 8076 } 8077 /* 8078 * TODO: Differentiate between "selector" and "field". 8079 */ 8080 if (isField) 8081 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8082 NULL, XML_PATTERN_XSFIELD, nsArray); 8083 else 8084 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8085 NULL, XML_PATTERN_XSSEL, nsArray); 8086 if (nsArray != NULL) 8087 xmlFree((xmlChar **) nsArray); 8088 8089 if (selector->xpathComp == NULL) { 8090 xmlSchemaPCustomErr(ctxt, 8091 /* TODO: Adjust error code? */ 8092 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8093 NULL, node, 8094 "The XPath expression '%s' could not be " 8095 "compiled", selector->xpath); 8096 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8097 } 8098 } 8099 return (0); 8100 } 8101 8102 #define ADD_ANNOTATION(annot) \ 8103 xmlSchemaAnnotPtr cur = item->annot; \ 8104 if (item->annot == NULL) { \ 8105 item->annot = annot; \ 8106 return (annot); \ 8107 } \ 8108 cur = item->annot; \ 8109 if (cur->next != NULL) { \ 8110 cur = cur->next; \ 8111 } \ 8112 cur->next = annot; 8113 8114 /** 8115 * xmlSchemaAssignAnnotation: 8116 * @item: the schema component 8117 * @annot: the annotation 8118 * 8119 * Adds the annotation to the given schema component. 8120 * 8121 * Returns the given annotaion. 8122 */ 8123 static xmlSchemaAnnotPtr 8124 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8125 xmlSchemaAnnotPtr annot) 8126 { 8127 if ((annItem == NULL) || (annot == NULL)) 8128 return (NULL); 8129 switch (annItem->type) { 8130 case XML_SCHEMA_TYPE_ELEMENT: { 8131 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8132 ADD_ANNOTATION(annot) 8133 } 8134 break; 8135 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8136 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8137 ADD_ANNOTATION(annot) 8138 } 8139 break; 8140 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8141 case XML_SCHEMA_TYPE_ANY: { 8142 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8143 ADD_ANNOTATION(annot) 8144 } 8145 break; 8146 case XML_SCHEMA_TYPE_PARTICLE: 8147 case XML_SCHEMA_TYPE_IDC_KEY: 8148 case XML_SCHEMA_TYPE_IDC_KEYREF: 8149 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8150 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8151 ADD_ANNOTATION(annot) 8152 } 8153 break; 8154 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8155 xmlSchemaAttributeGroupPtr item = 8156 (xmlSchemaAttributeGroupPtr) annItem; 8157 ADD_ANNOTATION(annot) 8158 } 8159 break; 8160 case XML_SCHEMA_TYPE_NOTATION: { 8161 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8162 ADD_ANNOTATION(annot) 8163 } 8164 break; 8165 case XML_SCHEMA_FACET_MININCLUSIVE: 8166 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8167 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8168 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8169 case XML_SCHEMA_FACET_TOTALDIGITS: 8170 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8171 case XML_SCHEMA_FACET_PATTERN: 8172 case XML_SCHEMA_FACET_ENUMERATION: 8173 case XML_SCHEMA_FACET_WHITESPACE: 8174 case XML_SCHEMA_FACET_LENGTH: 8175 case XML_SCHEMA_FACET_MAXLENGTH: 8176 case XML_SCHEMA_FACET_MINLENGTH: { 8177 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8178 ADD_ANNOTATION(annot) 8179 } 8180 break; 8181 case XML_SCHEMA_TYPE_SIMPLE: 8182 case XML_SCHEMA_TYPE_COMPLEX: { 8183 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8184 ADD_ANNOTATION(annot) 8185 } 8186 break; 8187 case XML_SCHEMA_TYPE_GROUP: { 8188 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8189 ADD_ANNOTATION(annot) 8190 } 8191 break; 8192 case XML_SCHEMA_TYPE_SEQUENCE: 8193 case XML_SCHEMA_TYPE_CHOICE: 8194 case XML_SCHEMA_TYPE_ALL: { 8195 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8196 ADD_ANNOTATION(annot) 8197 } 8198 break; 8199 default: 8200 xmlSchemaPCustomErr(NULL, 8201 XML_SCHEMAP_INTERNAL, 8202 NULL, NULL, 8203 "Internal error: xmlSchemaAddAnnotation, " 8204 "The item is not a annotated schema component", NULL); 8205 break; 8206 } 8207 return (annot); 8208 } 8209 8210 /** 8211 * xmlSchemaParseIDCSelectorAndField: 8212 * @ctxt: a schema validation context 8213 * @schema: the schema being built 8214 * @node: a subtree containing XML Schema informations 8215 * 8216 * Parses a XML Schema identity-contraint definition's 8217 * <selector> and <field> elements. 8218 * 8219 * Returns the parsed identity-constraint definition. 8220 */ 8221 static xmlSchemaIDCSelectPtr 8222 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8223 xmlSchemaIDCPtr idc, 8224 xmlNodePtr node, 8225 int isField) 8226 { 8227 xmlSchemaIDCSelectPtr item; 8228 xmlNodePtr child = NULL; 8229 xmlAttrPtr attr; 8230 8231 /* 8232 * Check for illegal attributes. 8233 */ 8234 attr = node->properties; 8235 while (attr != NULL) { 8236 if (attr->ns == NULL) { 8237 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8238 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8239 xmlSchemaPIllegalAttrErr(ctxt, 8240 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8241 } 8242 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8243 xmlSchemaPIllegalAttrErr(ctxt, 8244 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8245 } 8246 attr = attr->next; 8247 } 8248 /* 8249 * Create the item. 8250 */ 8251 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8252 if (item == NULL) { 8253 xmlSchemaPErrMemory(ctxt, 8254 "allocating a 'selector' of an identity-constraint definition", 8255 NULL); 8256 return (NULL); 8257 } 8258 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8259 /* 8260 * Attribute "xpath" (mandatory). 8261 */ 8262 attr = xmlSchemaGetPropNode(node, "xpath"); 8263 if (attr == NULL) { 8264 xmlSchemaPMissingAttrErr(ctxt, 8265 XML_SCHEMAP_S4S_ATTR_MISSING, 8266 NULL, node, 8267 "name", NULL); 8268 } else { 8269 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8270 /* 8271 * URGENT TODO: "field"s have an other syntax than "selector"s. 8272 */ 8273 8274 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8275 isField) == -1) { 8276 xmlSchemaPErr(ctxt, 8277 (xmlNodePtr) attr, 8278 XML_SCHEMAP_INTERNAL, 8279 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8280 "validating the XPath expression of a IDC selector.\n", 8281 NULL, NULL); 8282 } 8283 8284 } 8285 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8286 /* 8287 * And now for the children... 8288 */ 8289 child = node->children; 8290 if (IS_SCHEMA(child, "annotation")) { 8291 /* 8292 * Add the annotation to the parent IDC. 8293 */ 8294 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8295 xmlSchemaParseAnnotation(ctxt, child, 1)); 8296 child = child->next; 8297 } 8298 if (child != NULL) { 8299 xmlSchemaPContentErr(ctxt, 8300 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8301 NULL, node, child, 8302 NULL, "(annotation?)"); 8303 } 8304 8305 return (item); 8306 } 8307 8308 /** 8309 * xmlSchemaParseIDC: 8310 * @ctxt: a schema validation context 8311 * @schema: the schema being built 8312 * @node: a subtree containing XML Schema informations 8313 * 8314 * Parses a XML Schema identity-contraint definition. 8315 * 8316 * Returns the parsed identity-constraint definition. 8317 */ 8318 static xmlSchemaIDCPtr 8319 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8320 xmlSchemaPtr schema, 8321 xmlNodePtr node, 8322 xmlSchemaTypeType idcCategory, 8323 const xmlChar *targetNamespace) 8324 { 8325 xmlSchemaIDCPtr item = NULL; 8326 xmlNodePtr child = NULL; 8327 xmlAttrPtr attr; 8328 const xmlChar *name = NULL; 8329 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8330 8331 /* 8332 * Check for illegal attributes. 8333 */ 8334 attr = node->properties; 8335 while (attr != NULL) { 8336 if (attr->ns == NULL) { 8337 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8338 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8339 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8340 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8341 xmlSchemaPIllegalAttrErr(ctxt, 8342 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8343 } 8344 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8345 xmlSchemaPIllegalAttrErr(ctxt, 8346 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8347 } 8348 attr = attr->next; 8349 } 8350 /* 8351 * Attribute "name" (mandatory). 8352 */ 8353 attr = xmlSchemaGetPropNode(node, "name"); 8354 if (attr == NULL) { 8355 xmlSchemaPMissingAttrErr(ctxt, 8356 XML_SCHEMAP_S4S_ATTR_MISSING, 8357 NULL, node, 8358 "name", NULL); 8359 return (NULL); 8360 } else if (xmlSchemaPValAttrNode(ctxt, 8361 NULL, attr, 8362 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8363 return (NULL); 8364 } 8365 /* Create the component. */ 8366 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8367 idcCategory, node); 8368 if (item == NULL) 8369 return(NULL); 8370 8371 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8372 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8373 /* 8374 * Attribute "refer" (mandatory). 8375 */ 8376 attr = xmlSchemaGetPropNode(node, "refer"); 8377 if (attr == NULL) { 8378 xmlSchemaPMissingAttrErr(ctxt, 8379 XML_SCHEMAP_S4S_ATTR_MISSING, 8380 NULL, node, 8381 "refer", NULL); 8382 } else { 8383 /* 8384 * Create a reference item. 8385 */ 8386 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8387 NULL, NULL); 8388 if (item->ref == NULL) 8389 return (NULL); 8390 xmlSchemaPValAttrNodeQName(ctxt, schema, 8391 NULL, attr, 8392 &(item->ref->targetNamespace), 8393 &(item->ref->name)); 8394 xmlSchemaCheckReference(ctxt, schema, node, attr, 8395 item->ref->targetNamespace); 8396 } 8397 } 8398 /* 8399 * And now for the children... 8400 */ 8401 child = node->children; 8402 if (IS_SCHEMA(child, "annotation")) { 8403 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8404 child = child->next; 8405 } 8406 if (child == NULL) { 8407 xmlSchemaPContentErr(ctxt, 8408 XML_SCHEMAP_S4S_ELEM_MISSING, 8409 NULL, node, child, 8410 "A child element is missing", 8411 "(annotation?, (selector, field+))"); 8412 } 8413 /* 8414 * Child element <selector>. 8415 */ 8416 if (IS_SCHEMA(child, "selector")) { 8417 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8418 item, child, 0); 8419 child = child->next; 8420 /* 8421 * Child elements <field>. 8422 */ 8423 if (IS_SCHEMA(child, "field")) { 8424 do { 8425 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8426 item, child, 1); 8427 if (field != NULL) { 8428 field->index = item->nbFields; 8429 item->nbFields++; 8430 if (lastField != NULL) 8431 lastField->next = field; 8432 else 8433 item->fields = field; 8434 lastField = field; 8435 } 8436 child = child->next; 8437 } while (IS_SCHEMA(child, "field")); 8438 } else { 8439 xmlSchemaPContentErr(ctxt, 8440 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8441 NULL, node, child, 8442 NULL, "(annotation?, (selector, field+))"); 8443 } 8444 } 8445 if (child != NULL) { 8446 xmlSchemaPContentErr(ctxt, 8447 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8448 NULL, node, child, 8449 NULL, "(annotation?, (selector, field+))"); 8450 } 8451 8452 return (item); 8453 } 8454 8455 /** 8456 * xmlSchemaParseElement: 8457 * @ctxt: a schema validation context 8458 * @schema: the schema being built 8459 * @node: a subtree containing XML Schema informations 8460 * @topLevel: indicates if this is global declaration 8461 * 8462 * Parses a XML schema element declaration. 8463 * *WARNING* this interface is highly subject to change 8464 * 8465 * Returns the element declaration or a particle; NULL in case 8466 * of an error or if the particle has minOccurs==maxOccurs==0. 8467 */ 8468 static xmlSchemaBasicItemPtr 8469 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8470 xmlNodePtr node, int *isElemRef, int topLevel) 8471 { 8472 xmlSchemaElementPtr decl = NULL; 8473 xmlSchemaParticlePtr particle = NULL; 8474 xmlSchemaAnnotPtr annot = NULL; 8475 xmlNodePtr child = NULL; 8476 xmlAttrPtr attr, nameAttr; 8477 int min, max, isRef = 0; 8478 xmlChar *des = NULL; 8479 8480 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8481 /* TODO: Complete implementation of 3.3.6 */ 8482 8483 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8484 return (NULL); 8485 8486 if (isElemRef != NULL) 8487 *isElemRef = 0; 8488 /* 8489 * If we get a "ref" attribute on a local <element> we will assume it's 8490 * a reference - even if there's a "name" attribute; this seems to be more 8491 * robust. 8492 */ 8493 nameAttr = xmlSchemaGetPropNode(node, "name"); 8494 attr = xmlSchemaGetPropNode(node, "ref"); 8495 if ((topLevel) || (attr == NULL)) { 8496 if (nameAttr == NULL) { 8497 xmlSchemaPMissingAttrErr(ctxt, 8498 XML_SCHEMAP_S4S_ATTR_MISSING, 8499 NULL, node, "name", NULL); 8500 return (NULL); 8501 } 8502 } else 8503 isRef = 1; 8504 8505 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8506 child = node->children; 8507 if (IS_SCHEMA(child, "annotation")) { 8508 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8509 child = child->next; 8510 } 8511 /* 8512 * Skip particle part if a global declaration. 8513 */ 8514 if (topLevel) 8515 goto declaration_part; 8516 /* 8517 * The particle part ================================================== 8518 */ 8519 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8520 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8521 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8522 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8523 if (particle == NULL) 8524 goto return_null; 8525 8526 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8527 8528 if (isRef) { 8529 const xmlChar *refNs = NULL, *ref = NULL; 8530 xmlSchemaQNameRefPtr refer = NULL; 8531 /* 8532 * The reference part ============================================= 8533 */ 8534 if (isElemRef != NULL) 8535 *isElemRef = 1; 8536 8537 xmlSchemaPValAttrNodeQName(ctxt, schema, 8538 NULL, attr, &refNs, &ref); 8539 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8540 /* 8541 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8542 */ 8543 if (nameAttr != NULL) { 8544 xmlSchemaPMutualExclAttrErr(ctxt, 8545 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8546 } 8547 /* 8548 * Check for illegal attributes. 8549 */ 8550 attr = node->properties; 8551 while (attr != NULL) { 8552 if (attr->ns == NULL) { 8553 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8554 xmlStrEqual(attr->name, BAD_CAST "name") || 8555 xmlStrEqual(attr->name, BAD_CAST "id") || 8556 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8557 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8558 { 8559 attr = attr->next; 8560 continue; 8561 } else { 8562 /* SPEC (3.3.3 : 2.2) */ 8563 xmlSchemaPCustomAttrErr(ctxt, 8564 XML_SCHEMAP_SRC_ELEMENT_2_2, 8565 NULL, NULL, attr, 8566 "Only the attributes 'minOccurs', 'maxOccurs' and " 8567 "'id' are allowed in addition to 'ref'"); 8568 break; 8569 } 8570 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8571 xmlSchemaPIllegalAttrErr(ctxt, 8572 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8573 } 8574 attr = attr->next; 8575 } 8576 /* 8577 * No children except <annotation> expected. 8578 */ 8579 if (child != NULL) { 8580 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8581 NULL, node, child, NULL, "(annotation?)"); 8582 } 8583 if ((min == 0) && (max == 0)) 8584 goto return_null; 8585 /* 8586 * Create the reference item and attach it to the particle. 8587 */ 8588 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8589 ref, refNs); 8590 if (refer == NULL) 8591 goto return_null; 8592 particle->children = (xmlSchemaTreeItemPtr) refer; 8593 particle->annot = annot; 8594 /* 8595 * Add the particle to pending components, since the reference 8596 * need to be resolved. 8597 */ 8598 WXS_ADD_PENDING(ctxt, particle); 8599 return ((xmlSchemaBasicItemPtr) particle); 8600 } 8601 /* 8602 * The declaration part =============================================== 8603 */ 8604 declaration_part: 8605 { 8606 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8607 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8608 8609 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8610 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8611 goto return_null; 8612 /* 8613 * Evaluate the target namespace. 8614 */ 8615 if (topLevel) { 8616 ns = ctxt->targetNamespace; 8617 } else { 8618 attr = xmlSchemaGetPropNode(node, "form"); 8619 if (attr != NULL) { 8620 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8621 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8622 ns = ctxt->targetNamespace; 8623 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8624 xmlSchemaPSimpleTypeErr(ctxt, 8625 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8626 NULL, (xmlNodePtr) attr, 8627 NULL, "(qualified | unqualified)", 8628 attrValue, NULL, NULL, NULL); 8629 } 8630 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8631 ns = ctxt->targetNamespace; 8632 } 8633 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8634 if (decl == NULL) { 8635 goto return_null; 8636 } 8637 /* 8638 * Check for illegal attributes. 8639 */ 8640 attr = node->properties; 8641 while (attr != NULL) { 8642 if (attr->ns == NULL) { 8643 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8644 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8645 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8646 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8647 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8648 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8649 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8650 { 8651 if (topLevel == 0) { 8652 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8653 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8654 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8655 { 8656 xmlSchemaPIllegalAttrErr(ctxt, 8657 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8658 } 8659 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8660 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8661 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8662 8663 xmlSchemaPIllegalAttrErr(ctxt, 8664 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8665 } 8666 } 8667 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8668 8669 xmlSchemaPIllegalAttrErr(ctxt, 8670 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8671 } 8672 attr = attr->next; 8673 } 8674 /* 8675 * Extract/validate attributes. 8676 */ 8677 if (topLevel) { 8678 /* 8679 * Process top attributes of global element declarations here. 8680 */ 8681 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8682 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8683 xmlSchemaPValAttrQName(ctxt, schema, 8684 NULL, node, "substitutionGroup", 8685 &(decl->substGroupNs), &(decl->substGroup)); 8686 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8687 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8688 /* 8689 * Attribute "final". 8690 */ 8691 attr = xmlSchemaGetPropNode(node, "final"); 8692 if (attr == NULL) { 8693 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8694 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8695 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8696 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8697 } else { 8698 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8699 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8700 -1, 8701 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8702 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8703 xmlSchemaPSimpleTypeErr(ctxt, 8704 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8705 NULL, (xmlNodePtr) attr, 8706 NULL, "(#all | List of (extension | restriction))", 8707 attrValue, NULL, NULL, NULL); 8708 } 8709 } 8710 } 8711 /* 8712 * Attribute "block". 8713 */ 8714 attr = xmlSchemaGetPropNode(node, "block"); 8715 if (attr == NULL) { 8716 /* 8717 * Apply default "block" values. 8718 */ 8719 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8720 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8721 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8722 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8723 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8724 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8725 } else { 8726 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8727 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8728 -1, 8729 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8730 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8731 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8732 xmlSchemaPSimpleTypeErr(ctxt, 8733 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8734 NULL, (xmlNodePtr) attr, 8735 NULL, "(#all | List of (extension | " 8736 "restriction | substitution))", attrValue, 8737 NULL, NULL, NULL); 8738 } 8739 } 8740 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8741 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8742 8743 attr = xmlSchemaGetPropNode(node, "type"); 8744 if (attr != NULL) { 8745 xmlSchemaPValAttrNodeQName(ctxt, schema, 8746 NULL, attr, 8747 &(decl->namedTypeNs), &(decl->namedType)); 8748 xmlSchemaCheckReference(ctxt, schema, node, 8749 attr, decl->namedTypeNs); 8750 } 8751 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8752 attr = xmlSchemaGetPropNode(node, "fixed"); 8753 if (attr != NULL) { 8754 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8755 if (decl->value != NULL) { 8756 /* 8757 * 3.3.3 : 1 8758 * default and fixed must not both be present. 8759 */ 8760 xmlSchemaPMutualExclAttrErr(ctxt, 8761 XML_SCHEMAP_SRC_ELEMENT_1, 8762 NULL, attr, "default", "fixed"); 8763 } else { 8764 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8765 decl->value = fixed; 8766 } 8767 } 8768 /* 8769 * And now for the children... 8770 */ 8771 if (IS_SCHEMA(child, "complexType")) { 8772 /* 8773 * 3.3.3 : 3 8774 * "type" and either <simpleType> or <complexType> are mutually 8775 * exclusive 8776 */ 8777 if (decl->namedType != NULL) { 8778 xmlSchemaPContentErr(ctxt, 8779 XML_SCHEMAP_SRC_ELEMENT_3, 8780 NULL, node, child, 8781 "The attribute 'type' and the <complexType> child are " 8782 "mutually exclusive", NULL); 8783 } else 8784 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8785 child = child->next; 8786 } else if (IS_SCHEMA(child, "simpleType")) { 8787 /* 8788 * 3.3.3 : 3 8789 * "type" and either <simpleType> or <complexType> are 8790 * mutually exclusive 8791 */ 8792 if (decl->namedType != NULL) { 8793 xmlSchemaPContentErr(ctxt, 8794 XML_SCHEMAP_SRC_ELEMENT_3, 8795 NULL, node, child, 8796 "The attribute 'type' and the <simpleType> child are " 8797 "mutually exclusive", NULL); 8798 } else 8799 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8800 child = child->next; 8801 } 8802 while ((IS_SCHEMA(child, "unique")) || 8803 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8804 if (IS_SCHEMA(child, "unique")) { 8805 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8806 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8807 } else if (IS_SCHEMA(child, "key")) { 8808 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8809 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8810 } else if (IS_SCHEMA(child, "keyref")) { 8811 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8812 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8813 } 8814 if (lastIDC != NULL) 8815 lastIDC->next = curIDC; 8816 else 8817 decl->idcs = (void *) curIDC; 8818 lastIDC = curIDC; 8819 child = child->next; 8820 } 8821 if (child != NULL) { 8822 xmlSchemaPContentErr(ctxt, 8823 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8824 NULL, node, child, 8825 NULL, "(annotation?, ((simpleType | complexType)?, " 8826 "(unique | key | keyref)*))"); 8827 } 8828 decl->annot = annot; 8829 } 8830 /* 8831 * NOTE: Element Declaration Representation OK 4. will be checked at a 8832 * different layer. 8833 */ 8834 FREE_AND_NULL(des) 8835 if (topLevel) 8836 return ((xmlSchemaBasicItemPtr) decl); 8837 else { 8838 particle->children = (xmlSchemaTreeItemPtr) decl; 8839 return ((xmlSchemaBasicItemPtr) particle); 8840 } 8841 8842 return_null: 8843 FREE_AND_NULL(des); 8844 if (annot != NULL) { 8845 if (particle != NULL) 8846 particle->annot = NULL; 8847 if (decl != NULL) 8848 decl->annot = NULL; 8849 xmlSchemaFreeAnnot(annot); 8850 } 8851 return (NULL); 8852 } 8853 8854 /** 8855 * xmlSchemaParseUnion: 8856 * @ctxt: a schema validation context 8857 * @schema: the schema being built 8858 * @node: a subtree containing XML Schema informations 8859 * 8860 * parse a XML schema Union definition 8861 * *WARNING* this interface is highly subject to change 8862 * 8863 * Returns -1 in case of internal error, 0 in case of success and a positive 8864 * error code otherwise. 8865 */ 8866 static int 8867 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8868 xmlNodePtr node) 8869 { 8870 xmlSchemaTypePtr type; 8871 xmlNodePtr child = NULL; 8872 xmlAttrPtr attr; 8873 const xmlChar *cur = NULL; 8874 8875 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8876 return (-1); 8877 /* Not a component, don't create it. */ 8878 type = ctxt->ctxtType; 8879 /* 8880 * Mark the simple type as being of variety "union". 8881 */ 8882 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8883 /* 8884 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8885 * then the `simple ur-type definition`." 8886 */ 8887 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8888 /* 8889 * Check for illegal attributes. 8890 */ 8891 attr = node->properties; 8892 while (attr != NULL) { 8893 if (attr->ns == NULL) { 8894 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8895 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8896 xmlSchemaPIllegalAttrErr(ctxt, 8897 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8898 } 8899 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8900 xmlSchemaPIllegalAttrErr(ctxt, 8901 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8902 } 8903 attr = attr->next; 8904 } 8905 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8906 /* 8907 * Attribute "memberTypes". This is a list of QNames. 8908 * TODO: Check the value to contain anything. 8909 */ 8910 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8911 if (attr != NULL) { 8912 const xmlChar *end; 8913 xmlChar *tmp; 8914 const xmlChar *localName, *nsName; 8915 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8916 xmlSchemaQNameRefPtr ref; 8917 8918 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8919 type->base = cur; 8920 do { 8921 while (IS_BLANK_CH(*cur)) 8922 cur++; 8923 end = cur; 8924 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8925 end++; 8926 if (end == cur) 8927 break; 8928 tmp = xmlStrndup(cur, end - cur); 8929 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8930 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8931 /* 8932 * Create the member type link. 8933 */ 8934 link = (xmlSchemaTypeLinkPtr) 8935 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8936 if (link == NULL) { 8937 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8938 "allocating a type link", NULL); 8939 return (-1); 8940 } 8941 link->type = NULL; 8942 link->next = NULL; 8943 if (lastLink == NULL) 8944 type->memberTypes = link; 8945 else 8946 lastLink->next = link; 8947 lastLink = link; 8948 /* 8949 * Create a reference item. 8950 */ 8951 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8952 localName, nsName); 8953 if (ref == NULL) { 8954 FREE_AND_NULL(tmp) 8955 return (-1); 8956 } 8957 /* 8958 * Assign the reference to the link, it will be resolved 8959 * later during fixup of the union simple type. 8960 */ 8961 link->type = (xmlSchemaTypePtr) ref; 8962 } 8963 FREE_AND_NULL(tmp) 8964 cur = end; 8965 } while (*cur != 0); 8966 8967 } 8968 /* 8969 * And now for the children... 8970 */ 8971 child = node->children; 8972 if (IS_SCHEMA(child, "annotation")) { 8973 /* 8974 * Add the annotation to the simple type ancestor. 8975 */ 8976 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 8977 xmlSchemaParseAnnotation(ctxt, child, 1)); 8978 child = child->next; 8979 } 8980 if (IS_SCHEMA(child, "simpleType")) { 8981 xmlSchemaTypePtr subtype, last = NULL; 8982 8983 /* 8984 * Anchor the member types in the "subtypes" field of the 8985 * simple type. 8986 */ 8987 while (IS_SCHEMA(child, "simpleType")) { 8988 subtype = (xmlSchemaTypePtr) 8989 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8990 if (subtype != NULL) { 8991 if (last == NULL) { 8992 type->subtypes = subtype; 8993 last = subtype; 8994 } else { 8995 last->next = subtype; 8996 last = subtype; 8997 } 8998 last->next = NULL; 8999 } 9000 child = child->next; 9001 } 9002 } 9003 if (child != NULL) { 9004 xmlSchemaPContentErr(ctxt, 9005 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9006 NULL, node, child, NULL, "(annotation?, simpleType*)"); 9007 } 9008 if ((attr == NULL) && (type->subtypes == NULL)) { 9009 /* 9010 * src-union-memberTypes-or-simpleTypes 9011 * Either the memberTypes [attribute] of the <union> element must 9012 * be non-empty or there must be at least one simpleType [child]. 9013 */ 9014 xmlSchemaPCustomErr(ctxt, 9015 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 9016 NULL, node, 9017 "Either the attribute 'memberTypes' or " 9018 "at least one <simpleType> child must be present", NULL); 9019 } 9020 return (0); 9021 } 9022 9023 /** 9024 * xmlSchemaParseList: 9025 * @ctxt: a schema validation context 9026 * @schema: the schema being built 9027 * @node: a subtree containing XML Schema informations 9028 * 9029 * parse a XML schema List definition 9030 * *WARNING* this interface is highly subject to change 9031 * 9032 * Returns -1 in case of error, 0 if the declaration is improper and 9033 * 1 in case of success. 9034 */ 9035 static xmlSchemaTypePtr 9036 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9037 xmlNodePtr node) 9038 { 9039 xmlSchemaTypePtr type; 9040 xmlNodePtr child = NULL; 9041 xmlAttrPtr attr; 9042 9043 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9044 return (NULL); 9045 /* Not a component, don't create it. */ 9046 type = ctxt->ctxtType; 9047 /* 9048 * Mark the type as being of variety "list". 9049 */ 9050 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9051 /* 9052 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9053 * then the `simple ur-type definition`." 9054 */ 9055 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9056 /* 9057 * Check for illegal attributes. 9058 */ 9059 attr = node->properties; 9060 while (attr != NULL) { 9061 if (attr->ns == NULL) { 9062 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9063 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9064 xmlSchemaPIllegalAttrErr(ctxt, 9065 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9066 } 9067 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9068 xmlSchemaPIllegalAttrErr(ctxt, 9069 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9070 } 9071 attr = attr->next; 9072 } 9073 9074 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9075 9076 /* 9077 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9078 * fields for holding the reference to the itemType. 9079 * 9080 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9081 * the "ref" fields. 9082 */ 9083 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9084 node, "itemType", &(type->baseNs), &(type->base)); 9085 /* 9086 * And now for the children... 9087 */ 9088 child = node->children; 9089 if (IS_SCHEMA(child, "annotation")) { 9090 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9091 xmlSchemaParseAnnotation(ctxt, child, 1)); 9092 child = child->next; 9093 } 9094 if (IS_SCHEMA(child, "simpleType")) { 9095 /* 9096 * src-list-itemType-or-simpleType 9097 * Either the itemType [attribute] or the <simpleType> [child] of 9098 * the <list> element must be present, but not both. 9099 */ 9100 if (type->base != NULL) { 9101 xmlSchemaPCustomErr(ctxt, 9102 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9103 NULL, node, 9104 "The attribute 'itemType' and the <simpleType> child " 9105 "are mutually exclusive", NULL); 9106 } else { 9107 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9108 } 9109 child = child->next; 9110 } else if (type->base == NULL) { 9111 xmlSchemaPCustomErr(ctxt, 9112 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9113 NULL, node, 9114 "Either the attribute 'itemType' or the <simpleType> child " 9115 "must be present", NULL); 9116 } 9117 if (child != NULL) { 9118 xmlSchemaPContentErr(ctxt, 9119 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9120 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9121 } 9122 if ((type->base == NULL) && 9123 (type->subtypes == NULL) && 9124 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9125 xmlSchemaPCustomErr(ctxt, 9126 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9127 NULL, node, 9128 "Either the attribute 'itemType' or the <simpleType> child " 9129 "must be present", NULL); 9130 } 9131 return (NULL); 9132 } 9133 9134 /** 9135 * xmlSchemaParseSimpleType: 9136 * @ctxt: a schema validation context 9137 * @schema: the schema being built 9138 * @node: a subtree containing XML Schema informations 9139 * 9140 * parse a XML schema Simple Type definition 9141 * *WARNING* this interface is highly subject to change 9142 * 9143 * Returns -1 in case of error, 0 if the declaration is improper and 9144 * 1 in case of success. 9145 */ 9146 static xmlSchemaTypePtr 9147 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9148 xmlNodePtr node, int topLevel) 9149 { 9150 xmlSchemaTypePtr type, oldCtxtType; 9151 xmlNodePtr child = NULL; 9152 const xmlChar *attrValue = NULL; 9153 xmlAttrPtr attr; 9154 int hasRestriction = 0; 9155 9156 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9157 return (NULL); 9158 9159 if (topLevel) { 9160 attr = xmlSchemaGetPropNode(node, "name"); 9161 if (attr == NULL) { 9162 xmlSchemaPMissingAttrErr(ctxt, 9163 XML_SCHEMAP_S4S_ATTR_MISSING, 9164 NULL, node, 9165 "name", NULL); 9166 return (NULL); 9167 } else { 9168 if (xmlSchemaPValAttrNode(ctxt, 9169 NULL, attr, 9170 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9171 return (NULL); 9172 /* 9173 * Skip built-in types. 9174 */ 9175 if (ctxt->isS4S) { 9176 xmlSchemaTypePtr biType; 9177 9178 if (ctxt->isRedefine) { 9179 /* 9180 * REDEFINE: Disallow redefinition of built-in-types. 9181 * TODO: It seems that the spec does not say anything 9182 * about this case. 9183 */ 9184 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9185 NULL, node, 9186 "Redefinition of built-in simple types is not " 9187 "supported", NULL); 9188 return(NULL); 9189 } 9190 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9191 if (biType != NULL) 9192 return (biType); 9193 } 9194 } 9195 } 9196 /* 9197 * TargetNamespace: 9198 * SPEC "The `actual value` of the targetNamespace [attribute] 9199 * of the <schema> ancestor element information item if present, 9200 * otherwise `absent`. 9201 */ 9202 if (topLevel == 0) { 9203 #ifdef ENABLE_NAMED_LOCALS 9204 char buf[40]; 9205 #endif 9206 /* 9207 * Parse as local simple type definition. 9208 */ 9209 #ifdef ENABLE_NAMED_LOCALS 9210 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9211 type = xmlSchemaAddType(ctxt, schema, 9212 XML_SCHEMA_TYPE_SIMPLE, 9213 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9214 ctxt->targetNamespace, node, 0); 9215 #else 9216 type = xmlSchemaAddType(ctxt, schema, 9217 XML_SCHEMA_TYPE_SIMPLE, 9218 NULL, ctxt->targetNamespace, node, 0); 9219 #endif 9220 if (type == NULL) 9221 return (NULL); 9222 type->type = XML_SCHEMA_TYPE_SIMPLE; 9223 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9224 /* 9225 * Check for illegal attributes. 9226 */ 9227 attr = node->properties; 9228 while (attr != NULL) { 9229 if (attr->ns == NULL) { 9230 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9231 xmlSchemaPIllegalAttrErr(ctxt, 9232 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9233 } 9234 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9235 xmlSchemaPIllegalAttrErr(ctxt, 9236 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9237 } 9238 attr = attr->next; 9239 } 9240 } else { 9241 /* 9242 * Parse as global simple type definition. 9243 * 9244 * Note that attrValue is the value of the attribute "name" here. 9245 */ 9246 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9247 attrValue, ctxt->targetNamespace, node, 1); 9248 if (type == NULL) 9249 return (NULL); 9250 type->type = XML_SCHEMA_TYPE_SIMPLE; 9251 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9252 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9253 /* 9254 * Check for illegal attributes. 9255 */ 9256 attr = node->properties; 9257 while (attr != NULL) { 9258 if (attr->ns == NULL) { 9259 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9260 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9261 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9262 xmlSchemaPIllegalAttrErr(ctxt, 9263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9264 } 9265 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9266 xmlSchemaPIllegalAttrErr(ctxt, 9267 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9268 } 9269 attr = attr->next; 9270 } 9271 /* 9272 * Attribute "final". 9273 */ 9274 attr = xmlSchemaGetPropNode(node, "final"); 9275 if (attr == NULL) { 9276 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9277 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9278 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9279 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9280 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9281 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9282 } else { 9283 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9284 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9285 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9286 XML_SCHEMAS_TYPE_FINAL_LIST, 9287 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9288 9289 xmlSchemaPSimpleTypeErr(ctxt, 9290 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9291 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9292 NULL, "(#all | List of (list | union | restriction)", 9293 attrValue, NULL, NULL, NULL); 9294 } 9295 } 9296 } 9297 type->targetNamespace = ctxt->targetNamespace; 9298 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9299 /* 9300 * And now for the children... 9301 */ 9302 oldCtxtType = ctxt->ctxtType; 9303 9304 ctxt->ctxtType = type; 9305 9306 child = node->children; 9307 if (IS_SCHEMA(child, "annotation")) { 9308 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9309 child = child->next; 9310 } 9311 if (child == NULL) { 9312 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9313 NULL, node, child, NULL, 9314 "(annotation?, (restriction | list | union))"); 9315 } else if (IS_SCHEMA(child, "restriction")) { 9316 xmlSchemaParseRestriction(ctxt, schema, child, 9317 XML_SCHEMA_TYPE_SIMPLE); 9318 hasRestriction = 1; 9319 child = child->next; 9320 } else if (IS_SCHEMA(child, "list")) { 9321 xmlSchemaParseList(ctxt, schema, child); 9322 child = child->next; 9323 } else if (IS_SCHEMA(child, "union")) { 9324 xmlSchemaParseUnion(ctxt, schema, child); 9325 child = child->next; 9326 } 9327 if (child != NULL) { 9328 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9329 NULL, node, child, NULL, 9330 "(annotation?, (restriction | list | union))"); 9331 } 9332 /* 9333 * REDEFINE: SPEC src-redefine (5) 9334 * "Within the [children], each <simpleType> must have a 9335 * <restriction> among its [children] ... the `actual value` of whose 9336 * base [attribute] must be the same as the `actual value` of its own 9337 * name attribute plus target namespace;" 9338 */ 9339 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9340 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9341 NULL, node, "This is a redefinition, thus the " 9342 "<simpleType> must have a <restriction> child", NULL); 9343 } 9344 9345 ctxt->ctxtType = oldCtxtType; 9346 return (type); 9347 } 9348 9349 /** 9350 * xmlSchemaParseModelGroupDefRef: 9351 * @ctxt: the parser context 9352 * @schema: the schema being built 9353 * @node: the node 9354 * 9355 * Parses a reference to a model group definition. 9356 * 9357 * We will return a particle component with a qname-component or 9358 * NULL in case of an error. 9359 */ 9360 static xmlSchemaTreeItemPtr 9361 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9362 xmlSchemaPtr schema, 9363 xmlNodePtr node) 9364 { 9365 xmlSchemaParticlePtr item; 9366 xmlNodePtr child = NULL; 9367 xmlAttrPtr attr; 9368 const xmlChar *ref = NULL, *refNs = NULL; 9369 int min, max; 9370 9371 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9372 return (NULL); 9373 9374 attr = xmlSchemaGetPropNode(node, "ref"); 9375 if (attr == NULL) { 9376 xmlSchemaPMissingAttrErr(ctxt, 9377 XML_SCHEMAP_S4S_ATTR_MISSING, 9378 NULL, node, "ref", NULL); 9379 return (NULL); 9380 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9381 attr, &refNs, &ref) != 0) { 9382 return (NULL); 9383 } 9384 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9385 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9386 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9387 "(xs:nonNegativeInteger | unbounded)"); 9388 /* 9389 * Check for illegal attributes. 9390 */ 9391 attr = node->properties; 9392 while (attr != NULL) { 9393 if (attr->ns == NULL) { 9394 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9395 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9396 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9397 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9398 xmlSchemaPIllegalAttrErr(ctxt, 9399 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9400 } 9401 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9402 xmlSchemaPIllegalAttrErr(ctxt, 9403 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9404 } 9405 attr = attr->next; 9406 } 9407 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9408 item = xmlSchemaAddParticle(ctxt, node, min, max); 9409 if (item == NULL) 9410 return (NULL); 9411 /* 9412 * Create a qname-reference and set as the term; it will be substituted 9413 * for the model group after the reference has been resolved. 9414 */ 9415 item->children = (xmlSchemaTreeItemPtr) 9416 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9417 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9418 /* 9419 * And now for the children... 9420 */ 9421 child = node->children; 9422 /* TODO: Is annotation even allowed for a model group reference? */ 9423 if (IS_SCHEMA(child, "annotation")) { 9424 /* 9425 * TODO: What to do exactly with the annotation? 9426 */ 9427 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9428 child = child->next; 9429 } 9430 if (child != NULL) { 9431 xmlSchemaPContentErr(ctxt, 9432 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9433 NULL, node, child, NULL, 9434 "(annotation?)"); 9435 } 9436 /* 9437 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9438 */ 9439 if ((min == 0) && (max == 0)) 9440 return (NULL); 9441 9442 return ((xmlSchemaTreeItemPtr) item); 9443 } 9444 9445 /** 9446 * xmlSchemaParseModelGroupDefinition: 9447 * @ctxt: a schema validation context 9448 * @schema: the schema being built 9449 * @node: a subtree containing XML Schema informations 9450 * 9451 * Parses a XML schema model group definition. 9452 * 9453 * Note that the contraint src-redefine (6.2) can't be applied until 9454 * references have been resolved. So we will do this at the 9455 * component fixup level. 9456 * 9457 * *WARNING* this interface is highly subject to change 9458 * 9459 * Returns -1 in case of error, 0 if the declaration is improper and 9460 * 1 in case of success. 9461 */ 9462 static xmlSchemaModelGroupDefPtr 9463 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9464 xmlSchemaPtr schema, 9465 xmlNodePtr node) 9466 { 9467 xmlSchemaModelGroupDefPtr item; 9468 xmlNodePtr child = NULL; 9469 xmlAttrPtr attr; 9470 const xmlChar *name; 9471 9472 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9473 return (NULL); 9474 9475 attr = xmlSchemaGetPropNode(node, "name"); 9476 if (attr == NULL) { 9477 xmlSchemaPMissingAttrErr(ctxt, 9478 XML_SCHEMAP_S4S_ATTR_MISSING, 9479 NULL, node, 9480 "name", NULL); 9481 return (NULL); 9482 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9483 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9484 return (NULL); 9485 } 9486 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9487 ctxt->targetNamespace, node); 9488 if (item == NULL) 9489 return (NULL); 9490 /* 9491 * Check for illegal attributes. 9492 */ 9493 attr = node->properties; 9494 while (attr != NULL) { 9495 if (attr->ns == NULL) { 9496 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9497 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9498 xmlSchemaPIllegalAttrErr(ctxt, 9499 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9500 } 9501 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9502 xmlSchemaPIllegalAttrErr(ctxt, 9503 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9504 } 9505 attr = attr->next; 9506 } 9507 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9508 /* 9509 * And now for the children... 9510 */ 9511 child = node->children; 9512 if (IS_SCHEMA(child, "annotation")) { 9513 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9514 child = child->next; 9515 } 9516 if (IS_SCHEMA(child, "all")) { 9517 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9518 XML_SCHEMA_TYPE_ALL, 0); 9519 child = child->next; 9520 } else if (IS_SCHEMA(child, "choice")) { 9521 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9522 XML_SCHEMA_TYPE_CHOICE, 0); 9523 child = child->next; 9524 } else if (IS_SCHEMA(child, "sequence")) { 9525 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9526 XML_SCHEMA_TYPE_SEQUENCE, 0); 9527 child = child->next; 9528 } 9529 9530 9531 9532 if (child != NULL) { 9533 xmlSchemaPContentErr(ctxt, 9534 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9535 NULL, node, child, NULL, 9536 "(annotation?, (all | choice | sequence)?)"); 9537 } 9538 return (item); 9539 } 9540 9541 /** 9542 * xmlSchemaCleanupDoc: 9543 * @ctxt: a schema validation context 9544 * @node: the root of the document. 9545 * 9546 * removes unwanted nodes in a schemas document tree 9547 */ 9548 static void 9549 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9550 { 9551 xmlNodePtr delete, cur; 9552 9553 if ((ctxt == NULL) || (root == NULL)) return; 9554 9555 /* 9556 * Remove all the blank text nodes 9557 */ 9558 delete = NULL; 9559 cur = root; 9560 while (cur != NULL) { 9561 if (delete != NULL) { 9562 xmlUnlinkNode(delete); 9563 xmlFreeNode(delete); 9564 delete = NULL; 9565 } 9566 if (cur->type == XML_TEXT_NODE) { 9567 if (IS_BLANK_NODE(cur)) { 9568 if (xmlNodeGetSpacePreserve(cur) != 1) { 9569 delete = cur; 9570 } 9571 } 9572 } else if ((cur->type != XML_ELEMENT_NODE) && 9573 (cur->type != XML_CDATA_SECTION_NODE)) { 9574 delete = cur; 9575 goto skip_children; 9576 } 9577 9578 /* 9579 * Skip to next node 9580 */ 9581 if (cur->children != NULL) { 9582 if ((cur->children->type != XML_ENTITY_DECL) && 9583 (cur->children->type != XML_ENTITY_REF_NODE) && 9584 (cur->children->type != XML_ENTITY_NODE)) { 9585 cur = cur->children; 9586 continue; 9587 } 9588 } 9589 skip_children: 9590 if (cur->next != NULL) { 9591 cur = cur->next; 9592 continue; 9593 } 9594 9595 do { 9596 cur = cur->parent; 9597 if (cur == NULL) 9598 break; 9599 if (cur == root) { 9600 cur = NULL; 9601 break; 9602 } 9603 if (cur->next != NULL) { 9604 cur = cur->next; 9605 break; 9606 } 9607 } while (cur != NULL); 9608 } 9609 if (delete != NULL) { 9610 xmlUnlinkNode(delete); 9611 xmlFreeNode(delete); 9612 delete = NULL; 9613 } 9614 } 9615 9616 9617 static void 9618 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9619 { 9620 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9621 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9622 9623 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9624 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9625 9626 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9627 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9628 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9629 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9630 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9631 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9632 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9633 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9634 9635 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9636 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9637 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9638 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9639 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9640 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9641 } 9642 9643 static int 9644 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9645 xmlSchemaPtr schema, 9646 xmlNodePtr node) 9647 { 9648 xmlAttrPtr attr; 9649 const xmlChar *val; 9650 int res = 0, oldErrs = ctxt->nberrors; 9651 9652 /* 9653 * Those flags should be moved to the parser context flags, 9654 * since they are not visible at the component level. I.e. 9655 * they are used if processing schema *documents* only. 9656 */ 9657 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9658 HFAILURE; 9659 9660 /* 9661 * Since the version is of type xs:token, we won't bother to 9662 * check it. 9663 */ 9664 /* REMOVED: 9665 attr = xmlSchemaGetPropNode(node, "version"); 9666 if (attr != NULL) { 9667 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9668 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9669 HFAILURE; 9670 } 9671 */ 9672 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9673 if (attr != NULL) { 9674 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9675 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9676 HFAILURE; 9677 if (res != 0) { 9678 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9679 goto exit; 9680 } 9681 } 9682 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9683 if (attr != NULL) { 9684 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9685 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9686 XML_SCHEMAS_QUALIF_ELEM); 9687 HFAILURE; 9688 if (res != 0) { 9689 xmlSchemaPSimpleTypeErr(ctxt, 9690 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9691 NULL, (xmlNodePtr) attr, NULL, 9692 "(qualified | unqualified)", val, NULL, NULL, NULL); 9693 } 9694 } 9695 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9696 if (attr != NULL) { 9697 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9698 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9699 XML_SCHEMAS_QUALIF_ATTR); 9700 HFAILURE; 9701 if (res != 0) { 9702 xmlSchemaPSimpleTypeErr(ctxt, 9703 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9704 NULL, (xmlNodePtr) attr, NULL, 9705 "(qualified | unqualified)", val, NULL, NULL, NULL); 9706 } 9707 } 9708 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9709 if (attr != NULL) { 9710 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9711 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9712 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9713 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9714 -1, 9715 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9716 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9717 HFAILURE; 9718 if (res != 0) { 9719 xmlSchemaPSimpleTypeErr(ctxt, 9720 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9721 NULL, (xmlNodePtr) attr, NULL, 9722 "(#all | List of (extension | restriction | list | union))", 9723 val, NULL, NULL, NULL); 9724 } 9725 } 9726 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9727 if (attr != NULL) { 9728 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9729 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9730 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9731 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9732 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9733 HFAILURE; 9734 if (res != 0) { 9735 xmlSchemaPSimpleTypeErr(ctxt, 9736 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9737 NULL, (xmlNodePtr) attr, NULL, 9738 "(#all | List of (extension | restriction | substitution))", 9739 val, NULL, NULL, NULL); 9740 } 9741 } 9742 9743 exit: 9744 if (oldErrs != ctxt->nberrors) 9745 res = ctxt->err; 9746 return(res); 9747 exit_failure: 9748 return(-1); 9749 } 9750 9751 /** 9752 * xmlSchemaParseSchemaTopLevel: 9753 * @ctxt: a schema validation context 9754 * @schema: the schemas 9755 * @nodes: the list of top level nodes 9756 * 9757 * Returns the internal XML Schema structure built from the resource or 9758 * NULL in case of error 9759 */ 9760 static int 9761 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9762 xmlSchemaPtr schema, xmlNodePtr nodes) 9763 { 9764 xmlNodePtr child; 9765 xmlSchemaAnnotPtr annot; 9766 int res = 0, oldErrs, tmpOldErrs; 9767 9768 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9769 return(-1); 9770 9771 oldErrs = ctxt->nberrors; 9772 child = nodes; 9773 while ((IS_SCHEMA(child, "include")) || 9774 (IS_SCHEMA(child, "import")) || 9775 (IS_SCHEMA(child, "redefine")) || 9776 (IS_SCHEMA(child, "annotation"))) { 9777 if (IS_SCHEMA(child, "annotation")) { 9778 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9779 if (schema->annot == NULL) 9780 schema->annot = annot; 9781 else 9782 xmlSchemaFreeAnnot(annot); 9783 } else if (IS_SCHEMA(child, "import")) { 9784 tmpOldErrs = ctxt->nberrors; 9785 res = xmlSchemaParseImport(ctxt, schema, child); 9786 HFAILURE; 9787 HSTOP(ctxt); 9788 if (tmpOldErrs != ctxt->nberrors) 9789 goto exit; 9790 } else if (IS_SCHEMA(child, "include")) { 9791 tmpOldErrs = ctxt->nberrors; 9792 res = xmlSchemaParseInclude(ctxt, schema, child); 9793 HFAILURE; 9794 HSTOP(ctxt); 9795 if (tmpOldErrs != ctxt->nberrors) 9796 goto exit; 9797 } else if (IS_SCHEMA(child, "redefine")) { 9798 tmpOldErrs = ctxt->nberrors; 9799 res = xmlSchemaParseRedefine(ctxt, schema, child); 9800 HFAILURE; 9801 HSTOP(ctxt); 9802 if (tmpOldErrs != ctxt->nberrors) 9803 goto exit; 9804 } 9805 child = child->next; 9806 } 9807 /* 9808 * URGENT TODO: Change the functions to return int results. 9809 * We need especially to catch internal errors. 9810 */ 9811 while (child != NULL) { 9812 if (IS_SCHEMA(child, "complexType")) { 9813 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9814 child = child->next; 9815 } else if (IS_SCHEMA(child, "simpleType")) { 9816 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9817 child = child->next; 9818 } else if (IS_SCHEMA(child, "element")) { 9819 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9820 child = child->next; 9821 } else if (IS_SCHEMA(child, "attribute")) { 9822 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9823 child = child->next; 9824 } else if (IS_SCHEMA(child, "attributeGroup")) { 9825 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9826 child = child->next; 9827 } else if (IS_SCHEMA(child, "group")) { 9828 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9829 child = child->next; 9830 } else if (IS_SCHEMA(child, "notation")) { 9831 xmlSchemaParseNotation(ctxt, schema, child); 9832 child = child->next; 9833 } else { 9834 xmlSchemaPContentErr(ctxt, 9835 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9836 NULL, child->parent, child, 9837 NULL, "((include | import | redefine | annotation)*, " 9838 "(((simpleType | complexType | group | attributeGroup) " 9839 "| element | attribute | notation), annotation*)*)"); 9840 child = child->next; 9841 } 9842 while (IS_SCHEMA(child, "annotation")) { 9843 /* 9844 * TODO: We should add all annotations. 9845 */ 9846 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9847 if (schema->annot == NULL) 9848 schema->annot = annot; 9849 else 9850 xmlSchemaFreeAnnot(annot); 9851 child = child->next; 9852 } 9853 } 9854 exit: 9855 ctxt->ctxtType = NULL; 9856 if (oldErrs != ctxt->nberrors) 9857 res = ctxt->err; 9858 return(res); 9859 exit_failure: 9860 return(-1); 9861 } 9862 9863 static xmlSchemaSchemaRelationPtr 9864 xmlSchemaSchemaRelationCreate(void) 9865 { 9866 xmlSchemaSchemaRelationPtr ret; 9867 9868 ret = (xmlSchemaSchemaRelationPtr) 9869 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9870 if (ret == NULL) { 9871 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9872 return(NULL); 9873 } 9874 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9875 return(ret); 9876 } 9877 9878 #if 0 9879 static void 9880 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9881 { 9882 xmlFree(rel); 9883 } 9884 #endif 9885 9886 static void 9887 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9888 { 9889 xmlSchemaRedefPtr prev; 9890 9891 while (redef != NULL) { 9892 prev = redef; 9893 redef = redef->next; 9894 xmlFree(prev); 9895 } 9896 } 9897 9898 static void 9899 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9900 { 9901 /* 9902 * After the construction context has been freed, there will be 9903 * no schema graph available any more. Only the schema buckets 9904 * will stay alive, which are put into the "schemasImports" and 9905 * "includes" slots of the xmlSchema. 9906 */ 9907 if (con->buckets != NULL) 9908 xmlSchemaItemListFree(con->buckets); 9909 if (con->pending != NULL) 9910 xmlSchemaItemListFree(con->pending); 9911 if (con->substGroups != NULL) 9912 xmlHashFree(con->substGroups, 9913 (xmlHashDeallocator) xmlSchemaSubstGroupFree); 9914 if (con->redefs != NULL) 9915 xmlSchemaRedefListFree(con->redefs); 9916 if (con->dict != NULL) 9917 xmlDictFree(con->dict); 9918 xmlFree(con); 9919 } 9920 9921 static xmlSchemaConstructionCtxtPtr 9922 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9923 { 9924 xmlSchemaConstructionCtxtPtr ret; 9925 9926 ret = (xmlSchemaConstructionCtxtPtr) 9927 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9928 if (ret == NULL) { 9929 xmlSchemaPErrMemory(NULL, 9930 "allocating schema construction context", NULL); 9931 return (NULL); 9932 } 9933 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9934 9935 ret->buckets = xmlSchemaItemListCreate(); 9936 if (ret->buckets == NULL) { 9937 xmlSchemaPErrMemory(NULL, 9938 "allocating list of schema buckets", NULL); 9939 xmlFree(ret); 9940 return (NULL); 9941 } 9942 ret->pending = xmlSchemaItemListCreate(); 9943 if (ret->pending == NULL) { 9944 xmlSchemaPErrMemory(NULL, 9945 "allocating list of pending global components", NULL); 9946 xmlSchemaConstructionCtxtFree(ret); 9947 return (NULL); 9948 } 9949 ret->dict = dict; 9950 xmlDictReference(dict); 9951 return(ret); 9952 } 9953 9954 static xmlSchemaParserCtxtPtr 9955 xmlSchemaParserCtxtCreate(void) 9956 { 9957 xmlSchemaParserCtxtPtr ret; 9958 9959 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9960 if (ret == NULL) { 9961 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9962 NULL); 9963 return (NULL); 9964 } 9965 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9966 ret->type = XML_SCHEMA_CTXT_PARSER; 9967 ret->attrProhibs = xmlSchemaItemListCreate(); 9968 if (ret->attrProhibs == NULL) { 9969 xmlFree(ret); 9970 return(NULL); 9971 } 9972 return(ret); 9973 } 9974 9975 /** 9976 * xmlSchemaNewParserCtxtUseDict: 9977 * @URL: the location of the schema 9978 * @dict: the dictionary to be used 9979 * 9980 * Create an XML Schemas parse context for that file/resource expected 9981 * to contain an XML Schemas file. 9982 * 9983 * Returns the parser context or NULL in case of error 9984 */ 9985 static xmlSchemaParserCtxtPtr 9986 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 9987 { 9988 xmlSchemaParserCtxtPtr ret; 9989 9990 ret = xmlSchemaParserCtxtCreate(); 9991 if (ret == NULL) 9992 return (NULL); 9993 ret->dict = dict; 9994 xmlDictReference(dict); 9995 if (URL != NULL) 9996 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 9997 return (ret); 9998 } 9999 10000 static int 10001 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 10002 { 10003 if (vctxt->pctxt == NULL) { 10004 if (vctxt->schema != NULL) 10005 vctxt->pctxt = 10006 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 10007 else 10008 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 10009 if (vctxt->pctxt == NULL) { 10010 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 10011 "failed to create a temp. parser context"); 10012 return (-1); 10013 } 10014 /* TODO: Pass user data. */ 10015 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 10016 vctxt->warning, vctxt->errCtxt); 10017 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 10018 vctxt->errCtxt); 10019 } 10020 return (0); 10021 } 10022 10023 /** 10024 * xmlSchemaGetSchemaBucket: 10025 * @pctxt: the schema parser context 10026 * @schemaLocation: the URI of the schema document 10027 * 10028 * Returns a schema bucket if it was already parsed. 10029 * 10030 * Returns a schema bucket if it was already parsed from 10031 * @schemaLocation, NULL otherwise. 10032 */ 10033 static xmlSchemaBucketPtr 10034 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10035 const xmlChar *schemaLocation) 10036 { 10037 xmlSchemaBucketPtr cur; 10038 xmlSchemaItemListPtr list; 10039 10040 list = pctxt->constructor->buckets; 10041 if (list->nbItems == 0) 10042 return(NULL); 10043 else { 10044 int i; 10045 for (i = 0; i < list->nbItems; i++) { 10046 cur = (xmlSchemaBucketPtr) list->items[i]; 10047 /* Pointer comparison! */ 10048 if (cur->schemaLocation == schemaLocation) 10049 return(cur); 10050 } 10051 } 10052 return(NULL); 10053 } 10054 10055 static xmlSchemaBucketPtr 10056 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10057 const xmlChar *schemaLocation, 10058 const xmlChar *targetNamespace) 10059 { 10060 xmlSchemaBucketPtr cur; 10061 xmlSchemaItemListPtr list; 10062 10063 list = pctxt->constructor->buckets; 10064 if (list->nbItems == 0) 10065 return(NULL); 10066 else { 10067 int i; 10068 for (i = 0; i < list->nbItems; i++) { 10069 cur = (xmlSchemaBucketPtr) list->items[i]; 10070 /* Pointer comparison! */ 10071 if ((cur->origTargetNamespace == NULL) && 10072 (cur->schemaLocation == schemaLocation) && 10073 (cur->targetNamespace == targetNamespace)) 10074 return(cur); 10075 } 10076 } 10077 return(NULL); 10078 } 10079 10080 10081 #define IS_BAD_SCHEMA_DOC(b) \ 10082 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10083 10084 static xmlSchemaBucketPtr 10085 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10086 const xmlChar *targetNamespace, 10087 int imported) 10088 { 10089 xmlSchemaBucketPtr cur; 10090 xmlSchemaItemListPtr list; 10091 10092 list = pctxt->constructor->buckets; 10093 if (list->nbItems == 0) 10094 return(NULL); 10095 else { 10096 int i; 10097 for (i = 0; i < list->nbItems; i++) { 10098 cur = (xmlSchemaBucketPtr) list->items[i]; 10099 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10100 (cur->origTargetNamespace == targetNamespace) && 10101 ((imported && cur->imported) || 10102 ((!imported) && (!cur->imported)))) 10103 return(cur); 10104 } 10105 } 10106 return(NULL); 10107 } 10108 10109 static int 10110 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10111 xmlSchemaPtr schema, 10112 xmlSchemaBucketPtr bucket) 10113 { 10114 int oldFlags; 10115 xmlDocPtr oldDoc; 10116 xmlNodePtr node; 10117 int ret, oldErrs; 10118 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10119 10120 /* 10121 * Save old values; reset the *main* schema. 10122 * URGENT TODO: This is not good; move the per-document information 10123 * to the parser. Get rid of passing the main schema to the 10124 * parsing functions. 10125 */ 10126 oldFlags = schema->flags; 10127 oldDoc = schema->doc; 10128 if (schema->flags != 0) 10129 xmlSchemaClearSchemaDefaults(schema); 10130 schema->doc = bucket->doc; 10131 pctxt->schema = schema; 10132 /* 10133 * Keep the current target namespace on the parser *not* on the 10134 * main schema. 10135 */ 10136 pctxt->targetNamespace = bucket->targetNamespace; 10137 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10138 10139 if ((bucket->targetNamespace != NULL) && 10140 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10141 /* 10142 * We are parsing the schema for schemas! 10143 */ 10144 pctxt->isS4S = 1; 10145 } 10146 /* Mark it as parsed, even if parsing fails. */ 10147 bucket->parsed++; 10148 /* Compile the schema doc. */ 10149 node = xmlDocGetRootElement(bucket->doc); 10150 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10151 if (ret != 0) 10152 goto exit; 10153 /* An empty schema; just get out. */ 10154 if (node->children == NULL) 10155 goto exit; 10156 oldErrs = pctxt->nberrors; 10157 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10158 if (ret != 0) 10159 goto exit; 10160 /* 10161 * TODO: Not nice, but I'm not 100% sure we will get always an error 10162 * as a result of the obove functions; so better rely on pctxt->err 10163 * as well. 10164 */ 10165 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10166 ret = pctxt->err; 10167 goto exit; 10168 } 10169 10170 exit: 10171 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10172 /* Restore schema values. */ 10173 schema->doc = oldDoc; 10174 schema->flags = oldFlags; 10175 return(ret); 10176 } 10177 10178 static int 10179 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10180 xmlSchemaPtr schema, 10181 xmlSchemaBucketPtr bucket) 10182 { 10183 xmlSchemaParserCtxtPtr newpctxt; 10184 int res = 0; 10185 10186 if (bucket == NULL) 10187 return(0); 10188 if (bucket->parsed) { 10189 PERROR_INT("xmlSchemaParseNewDoc", 10190 "reparsing a schema doc"); 10191 return(-1); 10192 } 10193 if (bucket->doc == NULL) { 10194 PERROR_INT("xmlSchemaParseNewDoc", 10195 "parsing a schema doc, but there's no doc"); 10196 return(-1); 10197 } 10198 if (pctxt->constructor == NULL) { 10199 PERROR_INT("xmlSchemaParseNewDoc", 10200 "no constructor"); 10201 return(-1); 10202 } 10203 /* Create and init the temporary parser context. */ 10204 newpctxt = xmlSchemaNewParserCtxtUseDict( 10205 (const char *) bucket->schemaLocation, pctxt->dict); 10206 if (newpctxt == NULL) 10207 return(-1); 10208 newpctxt->constructor = pctxt->constructor; 10209 /* 10210 * TODO: Can we avoid that the parser knows about the main schema? 10211 * It would be better if he knows about the current schema bucket 10212 * only. 10213 */ 10214 newpctxt->schema = schema; 10215 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10216 pctxt->errCtxt); 10217 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10218 pctxt->errCtxt); 10219 newpctxt->counter = pctxt->counter; 10220 10221 10222 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10223 10224 /* Channel back errors and cleanup the temporary parser context. */ 10225 if (res != 0) 10226 pctxt->err = res; 10227 pctxt->nberrors += newpctxt->nberrors; 10228 pctxt->counter = newpctxt->counter; 10229 newpctxt->constructor = NULL; 10230 /* Free the parser context. */ 10231 xmlSchemaFreeParserCtxt(newpctxt); 10232 return(res); 10233 } 10234 10235 static void 10236 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10237 xmlSchemaSchemaRelationPtr rel) 10238 { 10239 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10240 10241 if (cur == NULL) { 10242 bucket->relations = rel; 10243 return; 10244 } 10245 while (cur->next != NULL) 10246 cur = cur->next; 10247 cur->next = rel; 10248 } 10249 10250 10251 static const xmlChar * 10252 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10253 xmlNodePtr ctxtNode) 10254 { 10255 /* 10256 * Build an absolue location URI. 10257 */ 10258 if (location != NULL) { 10259 if (ctxtNode == NULL) 10260 return(location); 10261 else { 10262 xmlChar *base, *URI; 10263 const xmlChar *ret = NULL; 10264 10265 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10266 if (base == NULL) { 10267 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10268 } else { 10269 URI = xmlBuildURI(location, base); 10270 xmlFree(base); 10271 } 10272 if (URI != NULL) { 10273 ret = xmlDictLookup(dict, URI, -1); 10274 xmlFree(URI); 10275 return(ret); 10276 } 10277 } 10278 } 10279 return(NULL); 10280 } 10281 10282 10283 10284 /** 10285 * xmlSchemaAddSchemaDoc: 10286 * @pctxt: a schema validation context 10287 * @schema: the schema being built 10288 * @node: a subtree containing XML Schema informations 10289 * 10290 * Parse an included (and to-be-redefined) XML schema document. 10291 * 10292 * Returns 0 on success, a positive error code on errors and 10293 * -1 in case of an internal or API error. 10294 */ 10295 10296 static int 10297 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10298 int type, /* import or include or redefine */ 10299 const xmlChar *schemaLocation, 10300 xmlDocPtr schemaDoc, 10301 const char *schemaBuffer, 10302 int schemaBufferLen, 10303 xmlNodePtr invokingNode, 10304 const xmlChar *sourceTargetNamespace, 10305 const xmlChar *importNamespace, 10306 xmlSchemaBucketPtr *bucket) 10307 { 10308 const xmlChar *targetNamespace = NULL; 10309 xmlSchemaSchemaRelationPtr relation = NULL; 10310 xmlDocPtr doc = NULL; 10311 int res = 0, err = 0, located = 0, preserveDoc = 0; 10312 xmlSchemaBucketPtr bkt = NULL; 10313 10314 if (bucket != NULL) 10315 *bucket = NULL; 10316 10317 switch (type) { 10318 case XML_SCHEMA_SCHEMA_IMPORT: 10319 case XML_SCHEMA_SCHEMA_MAIN: 10320 err = XML_SCHEMAP_SRC_IMPORT; 10321 break; 10322 case XML_SCHEMA_SCHEMA_INCLUDE: 10323 err = XML_SCHEMAP_SRC_INCLUDE; 10324 break; 10325 case XML_SCHEMA_SCHEMA_REDEFINE: 10326 err = XML_SCHEMAP_SRC_REDEFINE; 10327 break; 10328 } 10329 10330 10331 /* Special handling for the main schema: 10332 * skip the location and relation logic and just parse the doc. 10333 * We need just a bucket to be returned in this case. 10334 */ 10335 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10336 goto doc_load; 10337 10338 /* Note that we expect the location to be an absulute URI. */ 10339 if (schemaLocation != NULL) { 10340 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10341 if ((bkt != NULL) && 10342 (pctxt->constructor->bucket == bkt)) { 10343 /* Report self-imports/inclusions/redefinitions. */ 10344 10345 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10346 invokingNode, NULL, 10347 "The schema must not import/include/redefine itself", 10348 NULL, NULL); 10349 goto exit; 10350 } 10351 } 10352 /* 10353 * Create a relation for the graph of schemas. 10354 */ 10355 relation = xmlSchemaSchemaRelationCreate(); 10356 if (relation == NULL) 10357 return(-1); 10358 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10359 relation); 10360 relation->type = type; 10361 10362 /* 10363 * Save the namespace import information. 10364 */ 10365 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10366 relation->importNamespace = importNamespace; 10367 if (schemaLocation == NULL) { 10368 /* 10369 * No location; this is just an import of the namespace. 10370 * Note that we don't assign a bucket to the relation 10371 * in this case. 10372 */ 10373 goto exit; 10374 } 10375 targetNamespace = importNamespace; 10376 } 10377 10378 /* Did we already fetch the doc? */ 10379 if (bkt != NULL) { 10380 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10381 /* 10382 * We included/redefined and then try to import a schema, 10383 * but the new location provided for import was different. 10384 */ 10385 if (schemaLocation == NULL) 10386 schemaLocation = BAD_CAST "in_memory_buffer"; 10387 if (!xmlStrEqual(schemaLocation, 10388 bkt->schemaLocation)) { 10389 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10390 invokingNode, NULL, 10391 "The schema document '%s' cannot be imported, since " 10392 "it was already included or redefined", 10393 schemaLocation, NULL); 10394 goto exit; 10395 } 10396 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10397 /* 10398 * We imported and then try to include/redefine a schema, 10399 * but the new location provided for the include/redefine 10400 * was different. 10401 */ 10402 if (schemaLocation == NULL) 10403 schemaLocation = BAD_CAST "in_memory_buffer"; 10404 if (!xmlStrEqual(schemaLocation, 10405 bkt->schemaLocation)) { 10406 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10407 invokingNode, NULL, 10408 "The schema document '%s' cannot be included or " 10409 "redefined, since it was already imported", 10410 schemaLocation, NULL); 10411 goto exit; 10412 } 10413 } 10414 } 10415 10416 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10417 /* 10418 * Given that the schemaLocation [attribute] is only a hint, it is open 10419 * to applications to ignore all but the first <import> for a given 10420 * namespace, regardless of the `actual value` of schemaLocation, but 10421 * such a strategy risks missing useful information when new 10422 * schemaLocations are offered. 10423 * 10424 * We will use the first <import> that comes with a location. 10425 * Further <import>s *with* a location, will result in an error. 10426 * TODO: Better would be to just report a warning here, but 10427 * we'll try it this way until someone complains. 10428 * 10429 * Schema Document Location Strategy: 10430 * 3 Based on the namespace name, identify an existing schema document, 10431 * either as a resource which is an XML document or a <schema> element 10432 * information item, in some local schema repository; 10433 * 5 Attempt to resolve the namespace name to locate such a resource. 10434 * 10435 * NOTE: (3) and (5) are not supported. 10436 */ 10437 if (bkt != NULL) { 10438 relation->bucket = bkt; 10439 goto exit; 10440 } 10441 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10442 importNamespace, 1); 10443 10444 if (bkt != NULL) { 10445 relation->bucket = bkt; 10446 if (bkt->schemaLocation == NULL) { 10447 /* First given location of the schema; load the doc. */ 10448 bkt->schemaLocation = schemaLocation; 10449 } else { 10450 if (!xmlStrEqual(schemaLocation, 10451 bkt->schemaLocation)) { 10452 /* 10453 * Additional location given; just skip it. 10454 * URGENT TODO: We should report a warning here. 10455 * res = XML_SCHEMAP_SRC_IMPORT; 10456 */ 10457 if (schemaLocation == NULL) 10458 schemaLocation = BAD_CAST "in_memory_buffer"; 10459 10460 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10461 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10462 invokingNode, NULL, 10463 "Skipping import of schema located at '%s' for the " 10464 "namespace '%s', since this namespace was already " 10465 "imported with the schema located at '%s'", 10466 schemaLocation, importNamespace, bkt->schemaLocation); 10467 } 10468 goto exit; 10469 } 10470 } 10471 /* 10472 * No bucket + first location: load the doc and create a 10473 * bucket. 10474 */ 10475 } else { 10476 /* <include> and <redefine> */ 10477 if (bkt != NULL) { 10478 10479 if ((bkt->origTargetNamespace == NULL) && 10480 (bkt->targetNamespace != sourceTargetNamespace)) { 10481 xmlSchemaBucketPtr chamel; 10482 10483 /* 10484 * Chameleon include/redefine: skip loading only if it was 10485 * aleady build for the targetNamespace of the including 10486 * schema. 10487 */ 10488 /* 10489 * URGENT TODO: If the schema is a chameleon-include then copy 10490 * the components into the including schema and modify the 10491 * targetNamespace of those components, do nothing otherwise. 10492 * NOTE: This is currently worked-around by compiling the 10493 * chameleon for every destinct including targetNamespace; thus 10494 * not performant at the moment. 10495 * TODO: Check when the namespace in wildcards for chameleons 10496 * needs to be converted: before we built wildcard intersections 10497 * or after. 10498 * Answer: after! 10499 */ 10500 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10501 schemaLocation, sourceTargetNamespace); 10502 if (chamel != NULL) { 10503 /* A fitting chameleon was already parsed; NOP. */ 10504 relation->bucket = chamel; 10505 goto exit; 10506 } 10507 /* 10508 * We need to parse the chameleon again for a different 10509 * targetNamespace. 10510 * CHAMELEON TODO: Optimize this by only parsing the 10511 * chameleon once, and then copying the components to 10512 * the new targetNamespace. 10513 */ 10514 bkt = NULL; 10515 } else { 10516 relation->bucket = bkt; 10517 goto exit; 10518 } 10519 } 10520 } 10521 if ((bkt != NULL) && (bkt->doc != NULL)) { 10522 PERROR_INT("xmlSchemaAddSchemaDoc", 10523 "trying to load a schema doc, but a doc is already " 10524 "assigned to the schema bucket"); 10525 goto exit_failure; 10526 } 10527 10528 doc_load: 10529 /* 10530 * Load the document. 10531 */ 10532 if (schemaDoc != NULL) { 10533 doc = schemaDoc; 10534 /* Don' free this one, since it was provided by the caller. */ 10535 preserveDoc = 1; 10536 /* TODO: Does the context or the doc hold the location? */ 10537 if (schemaDoc->URL != NULL) 10538 schemaLocation = xmlDictLookup(pctxt->dict, 10539 schemaDoc->URL, -1); 10540 else 10541 schemaLocation = BAD_CAST "in_memory_buffer"; 10542 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10543 xmlParserCtxtPtr parserCtxt; 10544 10545 parserCtxt = xmlNewParserCtxt(); 10546 if (parserCtxt == NULL) { 10547 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10548 "allocating a parser context", NULL); 10549 goto exit_failure; 10550 } 10551 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10552 /* 10553 * TODO: Do we have to burden the schema parser dict with all 10554 * the content of the schema doc? 10555 */ 10556 xmlDictFree(parserCtxt->dict); 10557 parserCtxt->dict = pctxt->dict; 10558 xmlDictReference(parserCtxt->dict); 10559 } 10560 if (schemaLocation != NULL) { 10561 /* Parse from file. */ 10562 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10563 NULL, SCHEMAS_PARSE_OPTIONS); 10564 } else if (schemaBuffer != NULL) { 10565 /* Parse from memory buffer. */ 10566 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10567 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10568 schemaLocation = BAD_CAST "in_memory_buffer"; 10569 if (doc != NULL) 10570 doc->URL = xmlStrdup(schemaLocation); 10571 } 10572 /* 10573 * For <import>: 10574 * 2.1 The referent is (a fragment of) a resource which is an 10575 * XML document (see clause 1.1), which in turn corresponds to 10576 * a <schema> element information item in a well-formed information 10577 * set, which in turn corresponds to a valid schema. 10578 * TODO: (2.1) fragments of XML documents are not supported. 10579 * 10580 * 2.2 The referent is a <schema> element information item in 10581 * a well-formed information set, which in turn corresponds 10582 * to a valid schema. 10583 * TODO: (2.2) is not supported. 10584 */ 10585 if (doc == NULL) { 10586 xmlErrorPtr lerr; 10587 lerr = xmlGetLastError(); 10588 /* 10589 * Check if this a parser error, or if the document could 10590 * just not be located. 10591 * TODO: Try to find specific error codes to react only on 10592 * localisation failures. 10593 */ 10594 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10595 /* 10596 * We assume a parser error here. 10597 */ 10598 located = 1; 10599 /* TODO: Error code ?? */ 10600 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10601 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10602 invokingNode, NULL, 10603 "Failed to parse the XML resource '%s'", 10604 schemaLocation, NULL); 10605 } 10606 } 10607 xmlFreeParserCtxt(parserCtxt); 10608 if ((doc == NULL) && located) 10609 goto exit_error; 10610 } else { 10611 xmlSchemaPErr(pctxt, NULL, 10612 XML_SCHEMAP_NOTHING_TO_PARSE, 10613 "No information for parsing was provided with the " 10614 "given schema parser context.\n", 10615 NULL, NULL); 10616 goto exit_failure; 10617 } 10618 /* 10619 * Preprocess the document. 10620 */ 10621 if (doc != NULL) { 10622 xmlNodePtr docElem = NULL; 10623 10624 located = 1; 10625 docElem = xmlDocGetRootElement(doc); 10626 if (docElem == NULL) { 10627 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10628 invokingNode, NULL, 10629 "The document '%s' has no document element", 10630 schemaLocation, NULL); 10631 goto exit_error; 10632 } 10633 /* 10634 * Remove all the blank text nodes. 10635 */ 10636 xmlSchemaCleanupDoc(pctxt, docElem); 10637 /* 10638 * Check the schema's top level element. 10639 */ 10640 if (!IS_SCHEMA(docElem, "schema")) { 10641 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10642 invokingNode, NULL, 10643 "The XML document '%s' is not a schema document", 10644 schemaLocation, NULL); 10645 goto exit_error; 10646 } 10647 /* 10648 * Note that we don't apply a type check for the 10649 * targetNamespace value here. 10650 */ 10651 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10652 "targetNamespace"); 10653 } 10654 10655 /* after_doc_loading: */ 10656 if ((bkt == NULL) && located) { 10657 /* Only create a bucket if the schema was located. */ 10658 bkt = xmlSchemaBucketCreate(pctxt, type, 10659 targetNamespace); 10660 if (bkt == NULL) 10661 goto exit_failure; 10662 } 10663 if (bkt != NULL) { 10664 bkt->schemaLocation = schemaLocation; 10665 bkt->located = located; 10666 if (doc != NULL) { 10667 bkt->doc = doc; 10668 bkt->targetNamespace = targetNamespace; 10669 bkt->origTargetNamespace = targetNamespace; 10670 if (preserveDoc) 10671 bkt->preserveDoc = 1; 10672 } 10673 if (WXS_IS_BUCKET_IMPMAIN(type)) 10674 bkt->imported++; 10675 /* 10676 * Add it to the graph of schemas. 10677 */ 10678 if (relation != NULL) 10679 relation->bucket = bkt; 10680 } 10681 10682 exit: 10683 /* 10684 * Return the bucket explicitely; this is needed for the 10685 * main schema. 10686 */ 10687 if (bucket != NULL) 10688 *bucket = bkt; 10689 return (0); 10690 10691 exit_error: 10692 if ((doc != NULL) && (! preserveDoc)) { 10693 xmlFreeDoc(doc); 10694 if (bkt != NULL) 10695 bkt->doc = NULL; 10696 } 10697 return(pctxt->err); 10698 10699 exit_failure: 10700 if ((doc != NULL) && (! preserveDoc)) { 10701 xmlFreeDoc(doc); 10702 if (bkt != NULL) 10703 bkt->doc = NULL; 10704 } 10705 return (-1); 10706 } 10707 10708 /** 10709 * xmlSchemaParseImport: 10710 * @ctxt: a schema validation context 10711 * @schema: the schema being built 10712 * @node: a subtree containing XML Schema informations 10713 * 10714 * parse a XML schema Import definition 10715 * *WARNING* this interface is highly subject to change 10716 * 10717 * Returns 0 in case of success, a positive error code if 10718 * not valid and -1 in case of an internal error. 10719 */ 10720 static int 10721 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10722 xmlNodePtr node) 10723 { 10724 xmlNodePtr child; 10725 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10726 const xmlChar *thisTargetNamespace; 10727 xmlAttrPtr attr; 10728 int ret = 0; 10729 xmlSchemaBucketPtr bucket = NULL; 10730 10731 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10732 return (-1); 10733 10734 /* 10735 * Check for illegal attributes. 10736 */ 10737 attr = node->properties; 10738 while (attr != NULL) { 10739 if (attr->ns == NULL) { 10740 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10741 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10742 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10743 xmlSchemaPIllegalAttrErr(pctxt, 10744 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10745 } 10746 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10747 xmlSchemaPIllegalAttrErr(pctxt, 10748 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10749 } 10750 attr = attr->next; 10751 } 10752 /* 10753 * Extract and validate attributes. 10754 */ 10755 if (xmlSchemaPValAttr(pctxt, NULL, node, 10756 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10757 &namespaceName) != 0) { 10758 xmlSchemaPSimpleTypeErr(pctxt, 10759 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10760 NULL, node, 10761 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10762 NULL, namespaceName, NULL, NULL, NULL); 10763 return (pctxt->err); 10764 } 10765 10766 if (xmlSchemaPValAttr(pctxt, NULL, node, 10767 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10768 &schemaLocation) != 0) { 10769 xmlSchemaPSimpleTypeErr(pctxt, 10770 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10771 NULL, node, 10772 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10773 NULL, schemaLocation, NULL, NULL, NULL); 10774 return (pctxt->err); 10775 } 10776 /* 10777 * And now for the children... 10778 */ 10779 child = node->children; 10780 if (IS_SCHEMA(child, "annotation")) { 10781 /* 10782 * the annotation here is simply discarded ... 10783 * TODO: really? 10784 */ 10785 child = child->next; 10786 } 10787 if (child != NULL) { 10788 xmlSchemaPContentErr(pctxt, 10789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10790 NULL, node, child, NULL, 10791 "(annotation?)"); 10792 } 10793 /* 10794 * Apply additional constraints. 10795 * 10796 * Note that it is important to use the original @targetNamespace 10797 * (or none at all), to rule out imports of schemas _with_ a 10798 * @targetNamespace if the importing schema is a chameleon schema 10799 * (with no @targetNamespace). 10800 */ 10801 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10802 if (namespaceName != NULL) { 10803 /* 10804 * 1.1 If the namespace [attribute] is present, then its `actual value` 10805 * must not match the `actual value` of the enclosing <schema>'s 10806 * targetNamespace [attribute]. 10807 */ 10808 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10809 xmlSchemaPCustomErr(pctxt, 10810 XML_SCHEMAP_SRC_IMPORT_1_1, 10811 NULL, node, 10812 "The value of the attribute 'namespace' must not match " 10813 "the target namespace '%s' of the importing schema", 10814 thisTargetNamespace); 10815 return (pctxt->err); 10816 } 10817 } else { 10818 /* 10819 * 1.2 If the namespace [attribute] is not present, then the enclosing 10820 * <schema> must have a targetNamespace [attribute]. 10821 */ 10822 if (thisTargetNamespace == NULL) { 10823 xmlSchemaPCustomErr(pctxt, 10824 XML_SCHEMAP_SRC_IMPORT_1_2, 10825 NULL, node, 10826 "The attribute 'namespace' must be existent if " 10827 "the importing schema has no target namespace", 10828 NULL); 10829 return (pctxt->err); 10830 } 10831 } 10832 /* 10833 * Locate and acquire the schema document. 10834 */ 10835 if (schemaLocation != NULL) 10836 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10837 schemaLocation, node); 10838 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10839 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10840 namespaceName, &bucket); 10841 10842 if (ret != 0) 10843 return(ret); 10844 10845 /* 10846 * For <import>: "It is *not* an error for the application 10847 * schema reference strategy to fail." 10848 * So just don't parse if no schema document was found. 10849 * Note that we will get no bucket if the schema could not be 10850 * located or if there was no schemaLocation. 10851 */ 10852 if ((bucket == NULL) && (schemaLocation != NULL)) { 10853 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10854 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10855 node, NULL, 10856 "Failed to locate a schema at location '%s'. " 10857 "Skipping the import", schemaLocation, NULL, NULL); 10858 } 10859 10860 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10861 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10862 } 10863 10864 return (ret); 10865 } 10866 10867 static int 10868 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10869 xmlSchemaPtr schema, 10870 xmlNodePtr node, 10871 xmlChar **schemaLocation, 10872 int type) 10873 { 10874 xmlAttrPtr attr; 10875 10876 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10877 (schemaLocation == NULL)) 10878 return (-1); 10879 10880 *schemaLocation = NULL; 10881 /* 10882 * Check for illegal attributes. 10883 * Applies for both <include> and <redefine>. 10884 */ 10885 attr = node->properties; 10886 while (attr != NULL) { 10887 if (attr->ns == NULL) { 10888 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10889 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10890 xmlSchemaPIllegalAttrErr(pctxt, 10891 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10892 } 10893 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10894 xmlSchemaPIllegalAttrErr(pctxt, 10895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10896 } 10897 attr = attr->next; 10898 } 10899 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10900 /* 10901 * Preliminary step, extract the URI-Reference and make an URI 10902 * from the base. 10903 */ 10904 /* 10905 * Attribute "schemaLocation" is mandatory. 10906 */ 10907 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10908 if (attr != NULL) { 10909 xmlChar *base = NULL; 10910 xmlChar *uri = NULL; 10911 10912 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10913 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10914 (const xmlChar **) schemaLocation) != 0) 10915 goto exit_error; 10916 base = xmlNodeGetBase(node->doc, node); 10917 if (base == NULL) { 10918 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10919 } else { 10920 uri = xmlBuildURI(*schemaLocation, base); 10921 xmlFree(base); 10922 } 10923 if (uri == NULL) { 10924 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10925 "could not build an URI from the schemaLocation") 10926 goto exit_failure; 10927 } 10928 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10929 xmlFree(uri); 10930 } else { 10931 xmlSchemaPMissingAttrErr(pctxt, 10932 XML_SCHEMAP_S4S_ATTR_MISSING, 10933 NULL, node, "schemaLocation", NULL); 10934 goto exit_error; 10935 } 10936 /* 10937 * Report self-inclusion and self-redefinition. 10938 */ 10939 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10940 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10941 xmlSchemaPCustomErr(pctxt, 10942 XML_SCHEMAP_SRC_REDEFINE, 10943 NULL, node, 10944 "The schema document '%s' cannot redefine itself.", 10945 *schemaLocation); 10946 } else { 10947 xmlSchemaPCustomErr(pctxt, 10948 XML_SCHEMAP_SRC_INCLUDE, 10949 NULL, node, 10950 "The schema document '%s' cannot include itself.", 10951 *schemaLocation); 10952 } 10953 goto exit_error; 10954 } 10955 10956 return(0); 10957 exit_error: 10958 return(pctxt->err); 10959 exit_failure: 10960 return(-1); 10961 } 10962 10963 static int 10964 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10965 xmlSchemaPtr schema, 10966 xmlNodePtr node, 10967 int type) 10968 { 10969 xmlNodePtr child = NULL; 10970 const xmlChar *schemaLocation = NULL; 10971 int res = 0; /* hasRedefinitions = 0 */ 10972 int isChameleon = 0, wasChameleon = 0; 10973 xmlSchemaBucketPtr bucket = NULL; 10974 10975 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10976 return (-1); 10977 10978 /* 10979 * Parse attributes. Note that the returned schemaLocation will 10980 * be already converted to an absolute URI. 10981 */ 10982 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 10983 node, (xmlChar **) (&schemaLocation), type); 10984 if (res != 0) 10985 return(res); 10986 /* 10987 * Load and add the schema document. 10988 */ 10989 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 10990 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 10991 if (res != 0) 10992 return(res); 10993 /* 10994 * If we get no schema bucket back, then this means that the schema 10995 * document could not be located or was broken XML or was not 10996 * a schema document. 10997 */ 10998 if ((bucket == NULL) || (bucket->doc == NULL)) { 10999 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 11000 /* 11001 * WARNING for <include>: 11002 * We will raise an error if the schema cannot be located 11003 * for inclusions, since the that was the feedback from the 11004 * schema people. I.e. the following spec piece will *not* be 11005 * satisfied: 11006 * SPEC src-include: "It is not an error for the `actual value` of the 11007 * schemaLocation [attribute] to fail to resolve it all, in which 11008 * case no corresponding inclusion is performed. 11009 * So do we need a warning report here?" 11010 */ 11011 res = XML_SCHEMAP_SRC_INCLUDE; 11012 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11013 node, NULL, 11014 "Failed to load the document '%s' for inclusion", 11015 schemaLocation, NULL); 11016 } else { 11017 /* 11018 * NOTE: This was changed to raise an error even if no redefinitions 11019 * are specified. 11020 * 11021 * SPEC src-redefine (1) 11022 * "If there are any element information items among the [children] 11023 * other than <annotation> then the `actual value` of the 11024 * schemaLocation [attribute] must successfully resolve." 11025 * TODO: Ask the WG if a the location has always to resolve 11026 * here as well! 11027 */ 11028 res = XML_SCHEMAP_SRC_REDEFINE; 11029 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11030 node, NULL, 11031 "Failed to load the document '%s' for redefinition", 11032 schemaLocation, NULL); 11033 } 11034 } else { 11035 /* 11036 * Check targetNamespace sanity before parsing the new schema. 11037 * TODO: Note that we won't check further content if the 11038 * targetNamespace was bad. 11039 */ 11040 if (bucket->origTargetNamespace != NULL) { 11041 /* 11042 * SPEC src-include (2.1) 11043 * "SII has a targetNamespace [attribute], and its `actual 11044 * value` is identical to the `actual value` of the targetNamespace 11045 * [attribute] of SII' (which must have such an [attribute])." 11046 */ 11047 if (pctxt->targetNamespace == NULL) { 11048 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11049 XML_SCHEMAP_SRC_INCLUDE, 11050 node, NULL, 11051 "The target namespace of the included/redefined schema " 11052 "'%s' has to be absent, since the including/redefining " 11053 "schema has no target namespace", 11054 schemaLocation, NULL); 11055 goto exit_error; 11056 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11057 pctxt->targetNamespace)) { 11058 /* TODO: Change error function. */ 11059 xmlSchemaPCustomErrExt(pctxt, 11060 XML_SCHEMAP_SRC_INCLUDE, 11061 NULL, node, 11062 "The target namespace '%s' of the included/redefined " 11063 "schema '%s' differs from '%s' of the " 11064 "including/redefining schema", 11065 bucket->origTargetNamespace, schemaLocation, 11066 pctxt->targetNamespace); 11067 goto exit_error; 11068 } 11069 } else if (pctxt->targetNamespace != NULL) { 11070 /* 11071 * Chameleons: the original target namespace will 11072 * differ from the resulting namespace. 11073 */ 11074 isChameleon = 1; 11075 if (bucket->parsed && 11076 bucket->origTargetNamespace != NULL) { 11077 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11078 XML_SCHEMAP_SRC_INCLUDE, 11079 node, NULL, 11080 "The target namespace of the included/redefined schema " 11081 "'%s' has to be absent or the same as the " 11082 "including/redefining schema's target namespace", 11083 schemaLocation, NULL); 11084 goto exit_error; 11085 } 11086 bucket->targetNamespace = pctxt->targetNamespace; 11087 } 11088 } 11089 /* 11090 * Parse the schema. 11091 */ 11092 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11093 if (isChameleon) { 11094 /* TODO: Get rid of this flag on the schema itself. */ 11095 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11096 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11097 } else 11098 wasChameleon = 1; 11099 } 11100 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11101 /* Restore chameleon flag. */ 11102 if (isChameleon && (!wasChameleon)) 11103 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11104 } 11105 /* 11106 * And now for the children... 11107 */ 11108 child = node->children; 11109 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11110 /* 11111 * Parse (simpleType | complexType | group | attributeGroup))* 11112 */ 11113 pctxt->redefined = bucket; 11114 /* 11115 * How to proceed if the redefined schema was not located? 11116 */ 11117 pctxt->isRedefine = 1; 11118 while (IS_SCHEMA(child, "annotation") || 11119 IS_SCHEMA(child, "simpleType") || 11120 IS_SCHEMA(child, "complexType") || 11121 IS_SCHEMA(child, "group") || 11122 IS_SCHEMA(child, "attributeGroup")) { 11123 if (IS_SCHEMA(child, "annotation")) { 11124 /* 11125 * TODO: discard or not? 11126 */ 11127 } else if (IS_SCHEMA(child, "simpleType")) { 11128 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11129 } else if (IS_SCHEMA(child, "complexType")) { 11130 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11131 /* hasRedefinitions = 1; */ 11132 } else if (IS_SCHEMA(child, "group")) { 11133 /* hasRedefinitions = 1; */ 11134 xmlSchemaParseModelGroupDefinition(pctxt, 11135 schema, child); 11136 } else if (IS_SCHEMA(child, "attributeGroup")) { 11137 /* hasRedefinitions = 1; */ 11138 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11139 child); 11140 } 11141 child = child->next; 11142 } 11143 pctxt->redefined = NULL; 11144 pctxt->isRedefine = 0; 11145 } else { 11146 if (IS_SCHEMA(child, "annotation")) { 11147 /* 11148 * TODO: discard or not? 11149 */ 11150 child = child->next; 11151 } 11152 } 11153 if (child != NULL) { 11154 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11155 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11156 xmlSchemaPContentErr(pctxt, res, 11157 NULL, node, child, NULL, 11158 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11159 } else { 11160 xmlSchemaPContentErr(pctxt, res, 11161 NULL, node, child, NULL, 11162 "(annotation?)"); 11163 } 11164 } 11165 return(res); 11166 11167 exit_error: 11168 return(pctxt->err); 11169 } 11170 11171 static int 11172 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11173 xmlNodePtr node) 11174 { 11175 int res; 11176 #ifndef ENABLE_REDEFINE 11177 TODO 11178 return(0); 11179 #endif 11180 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11181 XML_SCHEMA_SCHEMA_REDEFINE); 11182 if (res != 0) 11183 return(res); 11184 return(0); 11185 } 11186 11187 static int 11188 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11189 xmlNodePtr node) 11190 { 11191 int res; 11192 11193 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11194 XML_SCHEMA_SCHEMA_INCLUDE); 11195 if (res != 0) 11196 return(res); 11197 return(0); 11198 } 11199 11200 /** 11201 * xmlSchemaParseModelGroup: 11202 * @ctxt: a schema validation context 11203 * @schema: the schema being built 11204 * @node: a subtree containing XML Schema informations 11205 * @type: the "compositor" type 11206 * @particleNeeded: if a a model group with a particle 11207 * 11208 * parse a XML schema Sequence definition. 11209 * Applies parts of: 11210 * Schema Representation Constraint: 11211 * Redefinition Constraints and Semantics (src-redefine) 11212 * (6.1), (6.1.1), (6.1.2) 11213 * 11214 * Schema Component Constraint: 11215 * All Group Limited (cos-all-limited) (2) 11216 * TODO: Actually this should go to component-level checks, 11217 * but is done here due to performance. Move it to an other layer 11218 * is schema construction via an API is implemented. 11219 * 11220 * *WARNING* this interface is highly subject to change 11221 * 11222 * Returns -1 in case of error, 0 if the declaration is improper and 11223 * 1 in case of success. 11224 */ 11225 static xmlSchemaTreeItemPtr 11226 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11227 xmlNodePtr node, xmlSchemaTypeType type, 11228 int withParticle) 11229 { 11230 xmlSchemaModelGroupPtr item; 11231 xmlSchemaParticlePtr particle = NULL; 11232 xmlNodePtr child = NULL; 11233 xmlAttrPtr attr; 11234 int min = 1, max = 1, isElemRef, hasRefs = 0; 11235 11236 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11237 return (NULL); 11238 /* 11239 * Create a model group with the given compositor. 11240 */ 11241 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11242 if (item == NULL) 11243 return (NULL); 11244 11245 if (withParticle) { 11246 if (type == XML_SCHEMA_TYPE_ALL) { 11247 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11248 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11249 } else { 11250 /* choice + sequence */ 11251 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11252 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11253 "(xs:nonNegativeInteger | unbounded)"); 11254 } 11255 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11256 /* 11257 * Create a particle 11258 */ 11259 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11260 if (particle == NULL) 11261 return (NULL); 11262 particle->children = (xmlSchemaTreeItemPtr) item; 11263 /* 11264 * Check for illegal attributes. 11265 */ 11266 attr = node->properties; 11267 while (attr != NULL) { 11268 if (attr->ns == NULL) { 11269 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11270 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11271 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11272 xmlSchemaPIllegalAttrErr(ctxt, 11273 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11274 } 11275 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11276 xmlSchemaPIllegalAttrErr(ctxt, 11277 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11278 } 11279 attr = attr->next; 11280 } 11281 } else { 11282 /* 11283 * Check for illegal attributes. 11284 */ 11285 attr = node->properties; 11286 while (attr != NULL) { 11287 if (attr->ns == NULL) { 11288 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11289 xmlSchemaPIllegalAttrErr(ctxt, 11290 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11291 } 11292 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11293 xmlSchemaPIllegalAttrErr(ctxt, 11294 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11295 } 11296 attr = attr->next; 11297 } 11298 } 11299 11300 /* 11301 * Extract and validate attributes. 11302 */ 11303 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11304 /* 11305 * And now for the children... 11306 */ 11307 child = node->children; 11308 if (IS_SCHEMA(child, "annotation")) { 11309 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11310 child = child->next; 11311 } 11312 if (type == XML_SCHEMA_TYPE_ALL) { 11313 xmlSchemaParticlePtr part, last = NULL; 11314 11315 while (IS_SCHEMA(child, "element")) { 11316 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11317 schema, child, &isElemRef, 0); 11318 /* 11319 * SPEC cos-all-limited (2) 11320 * "The {max occurs} of all the particles in the {particles} 11321 * of the ('all') group must be 0 or 1. 11322 */ 11323 if (part != NULL) { 11324 if (isElemRef) 11325 hasRefs++; 11326 if (part->minOccurs > 1) { 11327 xmlSchemaPCustomErr(ctxt, 11328 XML_SCHEMAP_COS_ALL_LIMITED, 11329 NULL, child, 11330 "Invalid value for minOccurs (must be 0 or 1)", 11331 NULL); 11332 /* Reset to 1. */ 11333 part->minOccurs = 1; 11334 } 11335 if (part->maxOccurs > 1) { 11336 xmlSchemaPCustomErr(ctxt, 11337 XML_SCHEMAP_COS_ALL_LIMITED, 11338 NULL, child, 11339 "Invalid value for maxOccurs (must be 0 or 1)", 11340 NULL); 11341 /* Reset to 1. */ 11342 part->maxOccurs = 1; 11343 } 11344 if (last == NULL) 11345 item->children = (xmlSchemaTreeItemPtr) part; 11346 else 11347 last->next = (xmlSchemaTreeItemPtr) part; 11348 last = part; 11349 } 11350 child = child->next; 11351 } 11352 if (child != NULL) { 11353 xmlSchemaPContentErr(ctxt, 11354 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11355 NULL, node, child, NULL, 11356 "(annotation?, (annotation?, element*)"); 11357 } 11358 } else { 11359 /* choice + sequence */ 11360 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11361 11362 while ((IS_SCHEMA(child, "element")) || 11363 (IS_SCHEMA(child, "group")) || 11364 (IS_SCHEMA(child, "any")) || 11365 (IS_SCHEMA(child, "choice")) || 11366 (IS_SCHEMA(child, "sequence"))) { 11367 11368 if (IS_SCHEMA(child, "element")) { 11369 part = (xmlSchemaTreeItemPtr) 11370 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11371 if (part && isElemRef) 11372 hasRefs++; 11373 } else if (IS_SCHEMA(child, "group")) { 11374 part = 11375 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11376 if (part != NULL) 11377 hasRefs++; 11378 /* 11379 * Handle redefinitions. 11380 */ 11381 if (ctxt->isRedefine && ctxt->redef && 11382 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11383 part && part->children) 11384 { 11385 if ((xmlSchemaGetQNameRefName(part->children) == 11386 ctxt->redef->refName) && 11387 (xmlSchemaGetQNameRefTargetNs(part->children) == 11388 ctxt->redef->refTargetNs)) 11389 { 11390 /* 11391 * SPEC src-redefine: 11392 * (6.1) "If it has a <group> among its contents at 11393 * some level the `actual value` of whose ref 11394 * [attribute] is the same as the `actual value` of 11395 * its own name attribute plus target namespace, then 11396 * all of the following must be true:" 11397 * (6.1.1) "It must have exactly one such group." 11398 */ 11399 if (ctxt->redefCounter != 0) { 11400 xmlChar *str = NULL; 11401 11402 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11403 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11404 "The redefining model group definition " 11405 "'%s' must not contain more than one " 11406 "reference to the redefined definition", 11407 xmlSchemaFormatQName(&str, 11408 ctxt->redef->refTargetNs, 11409 ctxt->redef->refName), 11410 NULL); 11411 FREE_AND_NULL(str) 11412 part = NULL; 11413 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11414 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11415 { 11416 xmlChar *str = NULL; 11417 /* 11418 * SPEC src-redefine: 11419 * (6.1.2) "The `actual value` of both that 11420 * group's minOccurs and maxOccurs [attribute] 11421 * must be 1 (or `absent`). 11422 */ 11423 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11424 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11425 "The redefining model group definition " 11426 "'%s' must not contain a reference to the " 11427 "redefined definition with a " 11428 "maxOccurs/minOccurs other than 1", 11429 xmlSchemaFormatQName(&str, 11430 ctxt->redef->refTargetNs, 11431 ctxt->redef->refName), 11432 NULL); 11433 FREE_AND_NULL(str) 11434 part = NULL; 11435 } 11436 ctxt->redef->reference = WXS_BASIC_CAST part; 11437 ctxt->redefCounter++; 11438 } 11439 } 11440 } else if (IS_SCHEMA(child, "any")) { 11441 part = (xmlSchemaTreeItemPtr) 11442 xmlSchemaParseAny(ctxt, schema, child); 11443 } else if (IS_SCHEMA(child, "choice")) { 11444 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11445 XML_SCHEMA_TYPE_CHOICE, 1); 11446 } else if (IS_SCHEMA(child, "sequence")) { 11447 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11448 XML_SCHEMA_TYPE_SEQUENCE, 1); 11449 } 11450 if (part != NULL) { 11451 if (last == NULL) 11452 item->children = part; 11453 else 11454 last->next = part; 11455 last = part; 11456 } 11457 child = child->next; 11458 } 11459 if (child != NULL) { 11460 xmlSchemaPContentErr(ctxt, 11461 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11462 NULL, node, child, NULL, 11463 "(annotation?, (element | group | choice | sequence | any)*)"); 11464 } 11465 } 11466 if ((max == 0) && (min == 0)) 11467 return (NULL); 11468 if (hasRefs) { 11469 /* 11470 * We need to resolve references. 11471 */ 11472 WXS_ADD_PENDING(ctxt, item); 11473 } 11474 if (withParticle) 11475 return ((xmlSchemaTreeItemPtr) particle); 11476 else 11477 return ((xmlSchemaTreeItemPtr) item); 11478 } 11479 11480 /** 11481 * xmlSchemaParseRestriction: 11482 * @ctxt: a schema validation context 11483 * @schema: the schema being built 11484 * @node: a subtree containing XML Schema informations 11485 * 11486 * parse a XML schema Restriction definition 11487 * *WARNING* this interface is highly subject to change 11488 * 11489 * Returns the type definition or NULL in case of error 11490 */ 11491 static xmlSchemaTypePtr 11492 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11493 xmlNodePtr node, xmlSchemaTypeType parentType) 11494 { 11495 xmlSchemaTypePtr type; 11496 xmlNodePtr child = NULL; 11497 xmlAttrPtr attr; 11498 11499 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11500 return (NULL); 11501 /* Not a component, don't create it. */ 11502 type = ctxt->ctxtType; 11503 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11504 11505 /* 11506 * Check for illegal attributes. 11507 */ 11508 attr = node->properties; 11509 while (attr != NULL) { 11510 if (attr->ns == NULL) { 11511 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11512 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11513 xmlSchemaPIllegalAttrErr(ctxt, 11514 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11515 } 11516 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11517 xmlSchemaPIllegalAttrErr(ctxt, 11518 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11519 } 11520 attr = attr->next; 11521 } 11522 /* 11523 * Extract and validate attributes. 11524 */ 11525 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11526 /* 11527 * Attribute 11528 */ 11529 /* 11530 * Extract the base type. The "base" attribute is mandatory if inside 11531 * a complex type or if redefining. 11532 * 11533 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11534 * among its [children]), the simple type definition which is 11535 * the {content type} of the type definition `resolved` to by 11536 * the `actual value` of the base [attribute]" 11537 */ 11538 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11539 &(type->baseNs), &(type->base)) == 0) 11540 { 11541 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11542 xmlSchemaPMissingAttrErr(ctxt, 11543 XML_SCHEMAP_S4S_ATTR_MISSING, 11544 NULL, node, "base", NULL); 11545 } else if ((ctxt->isRedefine) && 11546 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11547 { 11548 if (type->base == NULL) { 11549 xmlSchemaPMissingAttrErr(ctxt, 11550 XML_SCHEMAP_S4S_ATTR_MISSING, 11551 NULL, node, "base", NULL); 11552 } else if ((! xmlStrEqual(type->base, type->name)) || 11553 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11554 { 11555 xmlChar *str1 = NULL, *str2 = NULL; 11556 /* 11557 * REDEFINE: SPEC src-redefine (5) 11558 * "Within the [children], each <simpleType> must have a 11559 * <restriction> among its [children] ... the `actual value` of 11560 * whose base [attribute] must be the same as the `actual value` 11561 * of its own name attribute plus target namespace;" 11562 */ 11563 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11564 NULL, node, "This is a redefinition, but the QName " 11565 "value '%s' of the 'base' attribute does not match the " 11566 "type's designation '%s'", 11567 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11568 xmlSchemaFormatQName(&str2, type->targetNamespace, 11569 type->name), NULL); 11570 FREE_AND_NULL(str1); 11571 FREE_AND_NULL(str2); 11572 /* Avoid confusion and erase the values. */ 11573 type->base = NULL; 11574 type->baseNs = NULL; 11575 } 11576 } 11577 } 11578 /* 11579 * And now for the children... 11580 */ 11581 child = node->children; 11582 if (IS_SCHEMA(child, "annotation")) { 11583 /* 11584 * Add the annotation to the simple type ancestor. 11585 */ 11586 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11587 xmlSchemaParseAnnotation(ctxt, child, 1)); 11588 child = child->next; 11589 } 11590 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11591 /* 11592 * Corresponds to <simpleType><restriction><simpleType>. 11593 */ 11594 if (IS_SCHEMA(child, "simpleType")) { 11595 if (type->base != NULL) { 11596 /* 11597 * src-restriction-base-or-simpleType 11598 * Either the base [attribute] or the simpleType [child] of the 11599 * <restriction> element must be present, but not both. 11600 */ 11601 xmlSchemaPContentErr(ctxt, 11602 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11603 NULL, node, child, 11604 "The attribute 'base' and the <simpleType> child are " 11605 "mutually exclusive", NULL); 11606 } else { 11607 type->baseType = (xmlSchemaTypePtr) 11608 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11609 } 11610 child = child->next; 11611 } else if (type->base == NULL) { 11612 xmlSchemaPContentErr(ctxt, 11613 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11614 NULL, node, child, 11615 "Either the attribute 'base' or a <simpleType> child " 11616 "must be present", NULL); 11617 } 11618 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11619 /* 11620 * Corresponds to <complexType><complexContent><restriction>... 11621 * followed by: 11622 * 11623 * Model groups <all>, <choice> and <sequence>. 11624 */ 11625 if (IS_SCHEMA(child, "all")) { 11626 type->subtypes = (xmlSchemaTypePtr) 11627 xmlSchemaParseModelGroup(ctxt, schema, child, 11628 XML_SCHEMA_TYPE_ALL, 1); 11629 child = child->next; 11630 } else if (IS_SCHEMA(child, "choice")) { 11631 type->subtypes = (xmlSchemaTypePtr) 11632 xmlSchemaParseModelGroup(ctxt, 11633 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11634 child = child->next; 11635 } else if (IS_SCHEMA(child, "sequence")) { 11636 type->subtypes = (xmlSchemaTypePtr) 11637 xmlSchemaParseModelGroup(ctxt, schema, child, 11638 XML_SCHEMA_TYPE_SEQUENCE, 1); 11639 child = child->next; 11640 /* 11641 * Model group reference <group>. 11642 */ 11643 } else if (IS_SCHEMA(child, "group")) { 11644 type->subtypes = (xmlSchemaTypePtr) 11645 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11646 /* 11647 * Note that the reference will be resolved in 11648 * xmlSchemaResolveTypeReferences(); 11649 */ 11650 child = child->next; 11651 } 11652 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11653 /* 11654 * Corresponds to <complexType><simpleContent><restriction>... 11655 * 11656 * "1.1 the simple type definition corresponding to the <simpleType> 11657 * among the [children] of <restriction> if there is one;" 11658 */ 11659 if (IS_SCHEMA(child, "simpleType")) { 11660 /* 11661 * We will store the to-be-restricted simple type in 11662 * type->contentTypeDef *temporarily*. 11663 */ 11664 type->contentTypeDef = (xmlSchemaTypePtr) 11665 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11666 if ( type->contentTypeDef == NULL) 11667 return (NULL); 11668 child = child->next; 11669 } 11670 } 11671 11672 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11673 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11674 xmlSchemaFacetPtr facet, lastfacet = NULL; 11675 /* 11676 * Corresponds to <complexType><simpleContent><restriction>... 11677 * <simpleType><restriction>... 11678 */ 11679 11680 /* 11681 * Add the facets to the simple type ancestor. 11682 */ 11683 /* 11684 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11685 * Simple Type Definition Schema Representation Constraint: 11686 * *Single Facet Value* 11687 */ 11688 while ((IS_SCHEMA(child, "minInclusive")) || 11689 (IS_SCHEMA(child, "minExclusive")) || 11690 (IS_SCHEMA(child, "maxInclusive")) || 11691 (IS_SCHEMA(child, "maxExclusive")) || 11692 (IS_SCHEMA(child, "totalDigits")) || 11693 (IS_SCHEMA(child, "fractionDigits")) || 11694 (IS_SCHEMA(child, "pattern")) || 11695 (IS_SCHEMA(child, "enumeration")) || 11696 (IS_SCHEMA(child, "whiteSpace")) || 11697 (IS_SCHEMA(child, "length")) || 11698 (IS_SCHEMA(child, "maxLength")) || 11699 (IS_SCHEMA(child, "minLength"))) { 11700 facet = xmlSchemaParseFacet(ctxt, schema, child); 11701 if (facet != NULL) { 11702 if (lastfacet == NULL) 11703 type->facets = facet; 11704 else 11705 lastfacet->next = facet; 11706 lastfacet = facet; 11707 lastfacet->next = NULL; 11708 } 11709 child = child->next; 11710 } 11711 /* 11712 * Create links for derivation and validation. 11713 */ 11714 if (type->facets != NULL) { 11715 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11716 11717 facet = type->facets; 11718 do { 11719 facetLink = (xmlSchemaFacetLinkPtr) 11720 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11721 if (facetLink == NULL) { 11722 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11723 xmlFree(facetLink); 11724 return (NULL); 11725 } 11726 facetLink->facet = facet; 11727 facetLink->next = NULL; 11728 if (lastFacetLink == NULL) 11729 type->facetSet = facetLink; 11730 else 11731 lastFacetLink->next = facetLink; 11732 lastFacetLink = facetLink; 11733 facet = facet->next; 11734 } while (facet != NULL); 11735 } 11736 } 11737 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11738 /* 11739 * Attribute uses/declarations. 11740 */ 11741 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11742 (xmlSchemaItemListPtr *) &(type->attrUses), 11743 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11744 return(NULL); 11745 /* 11746 * Attribute wildcard. 11747 */ 11748 if (IS_SCHEMA(child, "anyAttribute")) { 11749 type->attributeWildcard = 11750 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11751 child = child->next; 11752 } 11753 } 11754 if (child != NULL) { 11755 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11756 xmlSchemaPContentErr(ctxt, 11757 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11758 NULL, node, child, NULL, 11759 "annotation?, (group | all | choice | sequence)?, " 11760 "((attribute | attributeGroup)*, anyAttribute?))"); 11761 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11762 xmlSchemaPContentErr(ctxt, 11763 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11764 NULL, node, child, NULL, 11765 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11766 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11767 "length | minLength | maxLength | enumeration | whiteSpace | " 11768 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11769 } else { 11770 /* Simple type */ 11771 xmlSchemaPContentErr(ctxt, 11772 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11773 NULL, node, child, NULL, 11774 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11775 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11776 "length | minLength | maxLength | enumeration | whiteSpace | " 11777 "pattern)*))"); 11778 } 11779 } 11780 return (NULL); 11781 } 11782 11783 /** 11784 * xmlSchemaParseExtension: 11785 * @ctxt: a schema validation context 11786 * @schema: the schema being built 11787 * @node: a subtree containing XML Schema informations 11788 * 11789 * Parses an <extension>, which is found inside a 11790 * <simpleContent> or <complexContent>. 11791 * *WARNING* this interface is highly subject to change. 11792 * 11793 * TODO: Returns the type definition or NULL in case of error 11794 */ 11795 static xmlSchemaTypePtr 11796 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11797 xmlNodePtr node, xmlSchemaTypeType parentType) 11798 { 11799 xmlSchemaTypePtr type; 11800 xmlNodePtr child = NULL; 11801 xmlAttrPtr attr; 11802 11803 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11804 return (NULL); 11805 /* Not a component, don't create it. */ 11806 type = ctxt->ctxtType; 11807 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11808 11809 /* 11810 * Check for illegal attributes. 11811 */ 11812 attr = node->properties; 11813 while (attr != NULL) { 11814 if (attr->ns == NULL) { 11815 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11816 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11817 xmlSchemaPIllegalAttrErr(ctxt, 11818 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11819 } 11820 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11821 xmlSchemaPIllegalAttrErr(ctxt, 11822 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11823 } 11824 attr = attr->next; 11825 } 11826 11827 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11828 11829 /* 11830 * Attribute "base" - mandatory. 11831 */ 11832 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11833 "base", &(type->baseNs), &(type->base)) == 0) && 11834 (type->base == NULL)) { 11835 xmlSchemaPMissingAttrErr(ctxt, 11836 XML_SCHEMAP_S4S_ATTR_MISSING, 11837 NULL, node, "base", NULL); 11838 } 11839 /* 11840 * And now for the children... 11841 */ 11842 child = node->children; 11843 if (IS_SCHEMA(child, "annotation")) { 11844 /* 11845 * Add the annotation to the type ancestor. 11846 */ 11847 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11848 xmlSchemaParseAnnotation(ctxt, child, 1)); 11849 child = child->next; 11850 } 11851 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11852 /* 11853 * Corresponds to <complexType><complexContent><extension>... and: 11854 * 11855 * Model groups <all>, <choice>, <sequence> and <group>. 11856 */ 11857 if (IS_SCHEMA(child, "all")) { 11858 type->subtypes = (xmlSchemaTypePtr) 11859 xmlSchemaParseModelGroup(ctxt, schema, 11860 child, XML_SCHEMA_TYPE_ALL, 1); 11861 child = child->next; 11862 } else if (IS_SCHEMA(child, "choice")) { 11863 type->subtypes = (xmlSchemaTypePtr) 11864 xmlSchemaParseModelGroup(ctxt, schema, 11865 child, XML_SCHEMA_TYPE_CHOICE, 1); 11866 child = child->next; 11867 } else if (IS_SCHEMA(child, "sequence")) { 11868 type->subtypes = (xmlSchemaTypePtr) 11869 xmlSchemaParseModelGroup(ctxt, schema, 11870 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11871 child = child->next; 11872 } else if (IS_SCHEMA(child, "group")) { 11873 type->subtypes = (xmlSchemaTypePtr) 11874 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11875 /* 11876 * Note that the reference will be resolved in 11877 * xmlSchemaResolveTypeReferences(); 11878 */ 11879 child = child->next; 11880 } 11881 } 11882 if (child != NULL) { 11883 /* 11884 * Attribute uses/declarations. 11885 */ 11886 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11887 (xmlSchemaItemListPtr *) &(type->attrUses), 11888 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11889 return(NULL); 11890 /* 11891 * Attribute wildcard. 11892 */ 11893 if (IS_SCHEMA(child, "anyAttribute")) { 11894 ctxt->ctxtType->attributeWildcard = 11895 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11896 child = child->next; 11897 } 11898 } 11899 if (child != NULL) { 11900 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11901 /* Complex content extension. */ 11902 xmlSchemaPContentErr(ctxt, 11903 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11904 NULL, node, child, NULL, 11905 "(annotation?, ((group | all | choice | sequence)?, " 11906 "((attribute | attributeGroup)*, anyAttribute?)))"); 11907 } else { 11908 /* Simple content extension. */ 11909 xmlSchemaPContentErr(ctxt, 11910 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11911 NULL, node, child, NULL, 11912 "(annotation?, ((attribute | attributeGroup)*, " 11913 "anyAttribute?))"); 11914 } 11915 } 11916 return (NULL); 11917 } 11918 11919 /** 11920 * xmlSchemaParseSimpleContent: 11921 * @ctxt: a schema validation context 11922 * @schema: the schema being built 11923 * @node: a subtree containing XML Schema informations 11924 * 11925 * parse a XML schema SimpleContent definition 11926 * *WARNING* this interface is highly subject to change 11927 * 11928 * Returns the type definition or NULL in case of error 11929 */ 11930 static int 11931 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11932 xmlSchemaPtr schema, xmlNodePtr node, 11933 int *hasRestrictionOrExtension) 11934 { 11935 xmlSchemaTypePtr type; 11936 xmlNodePtr child = NULL; 11937 xmlAttrPtr attr; 11938 11939 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11940 (hasRestrictionOrExtension == NULL)) 11941 return (-1); 11942 *hasRestrictionOrExtension = 0; 11943 /* Not a component, don't create it. */ 11944 type = ctxt->ctxtType; 11945 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11946 /* 11947 * Check for illegal attributes. 11948 */ 11949 attr = node->properties; 11950 while (attr != NULL) { 11951 if (attr->ns == NULL) { 11952 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11953 xmlSchemaPIllegalAttrErr(ctxt, 11954 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11955 } 11956 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11957 xmlSchemaPIllegalAttrErr(ctxt, 11958 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11959 } 11960 attr = attr->next; 11961 } 11962 11963 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11964 11965 /* 11966 * And now for the children... 11967 */ 11968 child = node->children; 11969 if (IS_SCHEMA(child, "annotation")) { 11970 /* 11971 * Add the annotation to the complex type ancestor. 11972 */ 11973 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11974 xmlSchemaParseAnnotation(ctxt, child, 1)); 11975 child = child->next; 11976 } 11977 if (child == NULL) { 11978 xmlSchemaPContentErr(ctxt, 11979 XML_SCHEMAP_S4S_ELEM_MISSING, 11980 NULL, node, NULL, NULL, 11981 "(annotation?, (restriction | extension))"); 11982 } 11983 if (child == NULL) { 11984 xmlSchemaPContentErr(ctxt, 11985 XML_SCHEMAP_S4S_ELEM_MISSING, 11986 NULL, node, NULL, NULL, 11987 "(annotation?, (restriction | extension))"); 11988 } 11989 if (IS_SCHEMA(child, "restriction")) { 11990 xmlSchemaParseRestriction(ctxt, schema, child, 11991 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11992 (*hasRestrictionOrExtension) = 1; 11993 child = child->next; 11994 } else if (IS_SCHEMA(child, "extension")) { 11995 xmlSchemaParseExtension(ctxt, schema, child, 11996 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 11997 (*hasRestrictionOrExtension) = 1; 11998 child = child->next; 11999 } 12000 if (child != NULL) { 12001 xmlSchemaPContentErr(ctxt, 12002 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12003 NULL, node, child, NULL, 12004 "(annotation?, (restriction | extension))"); 12005 } 12006 return (0); 12007 } 12008 12009 /** 12010 * xmlSchemaParseComplexContent: 12011 * @ctxt: a schema validation context 12012 * @schema: the schema being built 12013 * @node: a subtree containing XML Schema informations 12014 * 12015 * parse a XML schema ComplexContent definition 12016 * *WARNING* this interface is highly subject to change 12017 * 12018 * Returns the type definition or NULL in case of error 12019 */ 12020 static int 12021 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 12022 xmlSchemaPtr schema, xmlNodePtr node, 12023 int *hasRestrictionOrExtension) 12024 { 12025 xmlSchemaTypePtr type; 12026 xmlNodePtr child = NULL; 12027 xmlAttrPtr attr; 12028 12029 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 12030 (hasRestrictionOrExtension == NULL)) 12031 return (-1); 12032 *hasRestrictionOrExtension = 0; 12033 /* Not a component, don't create it. */ 12034 type = ctxt->ctxtType; 12035 /* 12036 * Check for illegal attributes. 12037 */ 12038 attr = node->properties; 12039 while (attr != NULL) { 12040 if (attr->ns == NULL) { 12041 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12042 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12043 { 12044 xmlSchemaPIllegalAttrErr(ctxt, 12045 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12046 } 12047 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12048 xmlSchemaPIllegalAttrErr(ctxt, 12049 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12050 } 12051 attr = attr->next; 12052 } 12053 12054 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12055 12056 /* 12057 * Set the 'mixed' on the complex type ancestor. 12058 */ 12059 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12060 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12061 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12062 } 12063 child = node->children; 12064 if (IS_SCHEMA(child, "annotation")) { 12065 /* 12066 * Add the annotation to the complex type ancestor. 12067 */ 12068 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12069 xmlSchemaParseAnnotation(ctxt, child, 1)); 12070 child = child->next; 12071 } 12072 if (child == NULL) { 12073 xmlSchemaPContentErr(ctxt, 12074 XML_SCHEMAP_S4S_ELEM_MISSING, 12075 NULL, node, NULL, 12076 NULL, "(annotation?, (restriction | extension))"); 12077 } 12078 if (child == NULL) { 12079 xmlSchemaPContentErr(ctxt, 12080 XML_SCHEMAP_S4S_ELEM_MISSING, 12081 NULL, node, NULL, 12082 NULL, "(annotation?, (restriction | extension))"); 12083 } 12084 if (IS_SCHEMA(child, "restriction")) { 12085 xmlSchemaParseRestriction(ctxt, schema, child, 12086 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12087 (*hasRestrictionOrExtension) = 1; 12088 child = child->next; 12089 } else if (IS_SCHEMA(child, "extension")) { 12090 xmlSchemaParseExtension(ctxt, schema, child, 12091 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12092 (*hasRestrictionOrExtension) = 1; 12093 child = child->next; 12094 } 12095 if (child != NULL) { 12096 xmlSchemaPContentErr(ctxt, 12097 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12098 NULL, node, child, 12099 NULL, "(annotation?, (restriction | extension))"); 12100 } 12101 return (0); 12102 } 12103 12104 /** 12105 * xmlSchemaParseComplexType: 12106 * @ctxt: a schema validation context 12107 * @schema: the schema being built 12108 * @node: a subtree containing XML Schema informations 12109 * 12110 * parse a XML schema Complex Type definition 12111 * *WARNING* this interface is highly subject to change 12112 * 12113 * Returns the type definition or NULL in case of error 12114 */ 12115 static xmlSchemaTypePtr 12116 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12117 xmlNodePtr node, int topLevel) 12118 { 12119 xmlSchemaTypePtr type, ctxtType; 12120 xmlNodePtr child = NULL; 12121 const xmlChar *name = NULL; 12122 xmlAttrPtr attr; 12123 const xmlChar *attrValue; 12124 #ifdef ENABLE_NAMED_LOCALS 12125 char buf[40]; 12126 #endif 12127 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12128 12129 12130 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12131 return (NULL); 12132 12133 ctxtType = ctxt->ctxtType; 12134 12135 if (topLevel) { 12136 attr = xmlSchemaGetPropNode(node, "name"); 12137 if (attr == NULL) { 12138 xmlSchemaPMissingAttrErr(ctxt, 12139 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12140 return (NULL); 12141 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12142 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12143 return (NULL); 12144 } 12145 } 12146 12147 if (topLevel == 0) { 12148 /* 12149 * Parse as local complex type definition. 12150 */ 12151 #ifdef ENABLE_NAMED_LOCALS 12152 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12153 type = xmlSchemaAddType(ctxt, schema, 12154 XML_SCHEMA_TYPE_COMPLEX, 12155 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12156 ctxt->targetNamespace, node, 0); 12157 #else 12158 type = xmlSchemaAddType(ctxt, schema, 12159 XML_SCHEMA_TYPE_COMPLEX, 12160 NULL, ctxt->targetNamespace, node, 0); 12161 #endif 12162 if (type == NULL) 12163 return (NULL); 12164 name = type->name; 12165 type->node = node; 12166 type->type = XML_SCHEMA_TYPE_COMPLEX; 12167 /* 12168 * TODO: We need the target namespace. 12169 */ 12170 } else { 12171 /* 12172 * Parse as global complex type definition. 12173 */ 12174 type = xmlSchemaAddType(ctxt, schema, 12175 XML_SCHEMA_TYPE_COMPLEX, 12176 name, ctxt->targetNamespace, node, 1); 12177 if (type == NULL) 12178 return (NULL); 12179 type->node = node; 12180 type->type = XML_SCHEMA_TYPE_COMPLEX; 12181 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12182 } 12183 type->targetNamespace = ctxt->targetNamespace; 12184 /* 12185 * Handle attributes. 12186 */ 12187 attr = node->properties; 12188 while (attr != NULL) { 12189 if (attr->ns == NULL) { 12190 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12191 /* 12192 * Attribute "id". 12193 */ 12194 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12195 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12196 /* 12197 * Attribute "mixed". 12198 */ 12199 if (xmlSchemaPGetBoolNodeValue(ctxt, 12200 NULL, (xmlNodePtr) attr)) 12201 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12202 } else if (topLevel) { 12203 /* 12204 * Attributes of global complex type definitions. 12205 */ 12206 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12207 /* Pass. */ 12208 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12209 /* 12210 * Attribute "abstract". 12211 */ 12212 if (xmlSchemaPGetBoolNodeValue(ctxt, 12213 NULL, (xmlNodePtr) attr)) 12214 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12215 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12216 /* 12217 * Attribute "final". 12218 */ 12219 attrValue = xmlSchemaGetNodeContent(ctxt, 12220 (xmlNodePtr) attr); 12221 if (xmlSchemaPValAttrBlockFinal(attrValue, 12222 &(type->flags), 12223 -1, 12224 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12225 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12226 -1, -1, -1) != 0) 12227 { 12228 xmlSchemaPSimpleTypeErr(ctxt, 12229 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12230 NULL, (xmlNodePtr) attr, NULL, 12231 "(#all | List of (extension | restriction))", 12232 attrValue, NULL, NULL, NULL); 12233 } else 12234 final = 1; 12235 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12236 /* 12237 * Attribute "block". 12238 */ 12239 attrValue = xmlSchemaGetNodeContent(ctxt, 12240 (xmlNodePtr) attr); 12241 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12242 -1, 12243 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12244 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12245 -1, -1, -1) != 0) { 12246 xmlSchemaPSimpleTypeErr(ctxt, 12247 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12248 NULL, (xmlNodePtr) attr, NULL, 12249 "(#all | List of (extension | restriction)) ", 12250 attrValue, NULL, NULL, NULL); 12251 } else 12252 block = 1; 12253 } else { 12254 xmlSchemaPIllegalAttrErr(ctxt, 12255 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12256 } 12257 } else { 12258 xmlSchemaPIllegalAttrErr(ctxt, 12259 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12260 } 12261 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12262 xmlSchemaPIllegalAttrErr(ctxt, 12263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12264 } 12265 attr = attr->next; 12266 } 12267 if (! block) { 12268 /* 12269 * Apply default "block" values. 12270 */ 12271 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12272 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12273 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12274 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12275 } 12276 if (! final) { 12277 /* 12278 * Apply default "block" values. 12279 */ 12280 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12281 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12282 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12283 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12284 } 12285 /* 12286 * And now for the children... 12287 */ 12288 child = node->children; 12289 if (IS_SCHEMA(child, "annotation")) { 12290 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12291 child = child->next; 12292 } 12293 ctxt->ctxtType = type; 12294 if (IS_SCHEMA(child, "simpleContent")) { 12295 /* 12296 * <complexType><simpleContent>... 12297 * 3.4.3 : 2.2 12298 * Specifying mixed='true' when the <simpleContent> 12299 * alternative is chosen has no effect 12300 */ 12301 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12302 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12303 xmlSchemaParseSimpleContent(ctxt, schema, child, 12304 &hasRestrictionOrExtension); 12305 child = child->next; 12306 } else if (IS_SCHEMA(child, "complexContent")) { 12307 /* 12308 * <complexType><complexContent>... 12309 */ 12310 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12311 xmlSchemaParseComplexContent(ctxt, schema, child, 12312 &hasRestrictionOrExtension); 12313 child = child->next; 12314 } else { 12315 /* 12316 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12317 * 12318 * SPEC 12319 * "...the third alternative (neither <simpleContent> nor 12320 * <complexContent>) is chosen. This case is understood as shorthand 12321 * for complex content restricting the `ur-type definition`, and the 12322 * details of the mappings should be modified as necessary. 12323 */ 12324 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12325 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12326 /* 12327 * Parse model groups. 12328 */ 12329 if (IS_SCHEMA(child, "all")) { 12330 type->subtypes = (xmlSchemaTypePtr) 12331 xmlSchemaParseModelGroup(ctxt, schema, child, 12332 XML_SCHEMA_TYPE_ALL, 1); 12333 child = child->next; 12334 } else if (IS_SCHEMA(child, "choice")) { 12335 type->subtypes = (xmlSchemaTypePtr) 12336 xmlSchemaParseModelGroup(ctxt, schema, child, 12337 XML_SCHEMA_TYPE_CHOICE, 1); 12338 child = child->next; 12339 } else if (IS_SCHEMA(child, "sequence")) { 12340 type->subtypes = (xmlSchemaTypePtr) 12341 xmlSchemaParseModelGroup(ctxt, schema, child, 12342 XML_SCHEMA_TYPE_SEQUENCE, 1); 12343 child = child->next; 12344 } else if (IS_SCHEMA(child, "group")) { 12345 type->subtypes = (xmlSchemaTypePtr) 12346 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12347 /* 12348 * Note that the reference will be resolved in 12349 * xmlSchemaResolveTypeReferences(); 12350 */ 12351 child = child->next; 12352 } 12353 /* 12354 * Parse attribute decls/refs. 12355 */ 12356 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12357 (xmlSchemaItemListPtr *) &(type->attrUses), 12358 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12359 return(NULL); 12360 /* 12361 * Parse attribute wildcard. 12362 */ 12363 if (IS_SCHEMA(child, "anyAttribute")) { 12364 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12365 child = child->next; 12366 } 12367 } 12368 if (child != NULL) { 12369 xmlSchemaPContentErr(ctxt, 12370 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12371 NULL, node, child, 12372 NULL, "(annotation?, (simpleContent | complexContent | " 12373 "((group | all | choice | sequence)?, ((attribute | " 12374 "attributeGroup)*, anyAttribute?))))"); 12375 } 12376 /* 12377 * REDEFINE: SPEC src-redefine (5) 12378 */ 12379 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12380 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12381 NULL, node, "This is a redefinition, thus the " 12382 "<complexType> must have a <restriction> or <extension> " 12383 "grand-child", NULL); 12384 } 12385 ctxt->ctxtType = ctxtType; 12386 return (type); 12387 } 12388 12389 /************************************************************************ 12390 * * 12391 * Validating using Schemas * 12392 * * 12393 ************************************************************************/ 12394 12395 /************************************************************************ 12396 * * 12397 * Reading/Writing Schemas * 12398 * * 12399 ************************************************************************/ 12400 12401 #if 0 /* Will be enabled if it is clear what options are needed. */ 12402 /** 12403 * xmlSchemaParserCtxtSetOptions: 12404 * @ctxt: a schema parser context 12405 * @options: a combination of xmlSchemaParserOption 12406 * 12407 * Sets the options to be used during the parse. 12408 * 12409 * Returns 0 in case of success, -1 in case of an 12410 * API error. 12411 */ 12412 static int 12413 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12414 int options) 12415 12416 { 12417 int i; 12418 12419 if (ctxt == NULL) 12420 return (-1); 12421 /* 12422 * WARNING: Change the start value if adding to the 12423 * xmlSchemaParseOption. 12424 */ 12425 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12426 if (options & 1<<i) { 12427 return (-1); 12428 } 12429 } 12430 ctxt->options = options; 12431 return (0); 12432 } 12433 12434 /** 12435 * xmlSchemaValidCtxtGetOptions: 12436 * @ctxt: a schema parser context 12437 * 12438 * Returns the option combination of the parser context. 12439 */ 12440 static int 12441 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12442 12443 { 12444 if (ctxt == NULL) 12445 return (-1); 12446 else 12447 return (ctxt->options); 12448 } 12449 #endif 12450 12451 /** 12452 * xmlSchemaNewParserCtxt: 12453 * @URL: the location of the schema 12454 * 12455 * Create an XML Schemas parse context for that file/resource expected 12456 * to contain an XML Schemas file. 12457 * 12458 * Returns the parser context or NULL in case of error 12459 */ 12460 xmlSchemaParserCtxtPtr 12461 xmlSchemaNewParserCtxt(const char *URL) 12462 { 12463 xmlSchemaParserCtxtPtr ret; 12464 12465 if (URL == NULL) 12466 return (NULL); 12467 12468 ret = xmlSchemaParserCtxtCreate(); 12469 if (ret == NULL) 12470 return(NULL); 12471 ret->dict = xmlDictCreate(); 12472 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12473 return (ret); 12474 } 12475 12476 /** 12477 * xmlSchemaNewMemParserCtxt: 12478 * @buffer: a pointer to a char array containing the schemas 12479 * @size: the size of the array 12480 * 12481 * Create an XML Schemas parse context for that memory buffer expected 12482 * to contain an XML Schemas file. 12483 * 12484 * Returns the parser context or NULL in case of error 12485 */ 12486 xmlSchemaParserCtxtPtr 12487 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12488 { 12489 xmlSchemaParserCtxtPtr ret; 12490 12491 if ((buffer == NULL) || (size <= 0)) 12492 return (NULL); 12493 ret = xmlSchemaParserCtxtCreate(); 12494 if (ret == NULL) 12495 return(NULL); 12496 ret->buffer = buffer; 12497 ret->size = size; 12498 ret->dict = xmlDictCreate(); 12499 return (ret); 12500 } 12501 12502 /** 12503 * xmlSchemaNewDocParserCtxt: 12504 * @doc: a preparsed document tree 12505 * 12506 * Create an XML Schemas parse context for that document. 12507 * NB. The document may be modified during the parsing process. 12508 * 12509 * Returns the parser context or NULL in case of error 12510 */ 12511 xmlSchemaParserCtxtPtr 12512 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12513 { 12514 xmlSchemaParserCtxtPtr ret; 12515 12516 if (doc == NULL) 12517 return (NULL); 12518 ret = xmlSchemaParserCtxtCreate(); 12519 if (ret == NULL) 12520 return(NULL); 12521 ret->doc = doc; 12522 ret->dict = xmlDictCreate(); 12523 /* The application has responsibility for the document */ 12524 ret->preserve = 1; 12525 12526 return (ret); 12527 } 12528 12529 /** 12530 * xmlSchemaFreeParserCtxt: 12531 * @ctxt: the schema parser context 12532 * 12533 * Free the resources associated to the schema parser context 12534 */ 12535 void 12536 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12537 { 12538 if (ctxt == NULL) 12539 return; 12540 if (ctxt->doc != NULL && !ctxt->preserve) 12541 xmlFreeDoc(ctxt->doc); 12542 if (ctxt->vctxt != NULL) { 12543 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12544 } 12545 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12546 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12547 ctxt->constructor = NULL; 12548 ctxt->ownsConstructor = 0; 12549 } 12550 if (ctxt->attrProhibs != NULL) 12551 xmlSchemaItemListFree(ctxt->attrProhibs); 12552 xmlDictFree(ctxt->dict); 12553 xmlFree(ctxt); 12554 } 12555 12556 /************************************************************************ 12557 * * 12558 * Building the content models * 12559 * * 12560 ************************************************************************/ 12561 12562 /** 12563 * xmlSchemaBuildContentModelForSubstGroup: 12564 * 12565 * Returns 1 if nillable, 0 otherwise 12566 */ 12567 static int 12568 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12569 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12570 { 12571 xmlAutomataStatePtr start, tmp; 12572 xmlSchemaElementPtr elemDecl, member; 12573 xmlSchemaSubstGroupPtr substGroup; 12574 int i; 12575 int ret = 0; 12576 12577 elemDecl = (xmlSchemaElementPtr) particle->children; 12578 /* 12579 * Wrap the substitution group with a CHOICE. 12580 */ 12581 start = pctxt->state; 12582 if (end == NULL) 12583 end = xmlAutomataNewState(pctxt->am); 12584 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12585 if (substGroup == NULL) { 12586 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12587 XML_SCHEMAP_INTERNAL, 12588 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12589 "declaration is marked having a subst. group but none " 12590 "available.\n", elemDecl->name, NULL); 12591 return(0); 12592 } 12593 if (counter >= 0) { 12594 /* 12595 * NOTE that we put the declaration in, even if it's abstract. 12596 * However, an error will be raised during *validation* if an element 12597 * information item shall be validated against an abstract element 12598 * declaration. 12599 */ 12600 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12601 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12602 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12603 /* 12604 * Add subst. group members. 12605 */ 12606 for (i = 0; i < substGroup->members->nbItems; i++) { 12607 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12608 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12609 member->name, member->targetNamespace, member); 12610 } 12611 } else if (particle->maxOccurs == 1) { 12612 /* 12613 * NOTE that we put the declaration in, even if it's abstract, 12614 */ 12615 xmlAutomataNewEpsilon(pctxt->am, 12616 xmlAutomataNewTransition2(pctxt->am, 12617 start, NULL, 12618 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12619 /* 12620 * Add subst. group members. 12621 */ 12622 for (i = 0; i < substGroup->members->nbItems; i++) { 12623 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12624 /* 12625 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12626 * was incorrectly used instead of xmlAutomataNewTransition2() 12627 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12628 * section in xmlSchemaBuildAContentModel() ). 12629 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12630 * intended for the above "counter" section originally. I.e., 12631 * check xs:all with subst-groups. 12632 * 12633 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12634 * member->name, member->targetNamespace, 12635 * 1, 1, member); 12636 */ 12637 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12638 member->name, member->targetNamespace, member); 12639 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12640 } 12641 } else { 12642 xmlAutomataStatePtr hop; 12643 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12644 UNBOUNDED : particle->maxOccurs - 1; 12645 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12646 12647 counter = 12648 xmlAutomataNewCounter(pctxt->am, minOccurs, 12649 maxOccurs); 12650 hop = xmlAutomataNewState(pctxt->am); 12651 12652 xmlAutomataNewEpsilon(pctxt->am, 12653 xmlAutomataNewTransition2(pctxt->am, 12654 start, NULL, 12655 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12656 hop); 12657 /* 12658 * Add subst. group members. 12659 */ 12660 for (i = 0; i < substGroup->members->nbItems; i++) { 12661 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12662 xmlAutomataNewEpsilon(pctxt->am, 12663 xmlAutomataNewTransition2(pctxt->am, 12664 start, NULL, 12665 member->name, member->targetNamespace, member), 12666 hop); 12667 } 12668 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12669 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12670 } 12671 if (particle->minOccurs == 0) { 12672 xmlAutomataNewEpsilon(pctxt->am, start, end); 12673 ret = 1; 12674 } 12675 pctxt->state = end; 12676 return(ret); 12677 } 12678 12679 /** 12680 * xmlSchemaBuildContentModelForElement: 12681 * 12682 * Returns 1 if nillable, 0 otherwise 12683 */ 12684 static int 12685 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12686 xmlSchemaParticlePtr particle) 12687 { 12688 int ret = 0; 12689 12690 if (((xmlSchemaElementPtr) particle->children)->flags & 12691 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12692 /* 12693 * Substitution groups. 12694 */ 12695 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12696 } else { 12697 xmlSchemaElementPtr elemDecl; 12698 xmlAutomataStatePtr start; 12699 12700 elemDecl = (xmlSchemaElementPtr) particle->children; 12701 12702 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12703 return(0); 12704 if (particle->maxOccurs == 1) { 12705 start = ctxt->state; 12706 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12707 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12708 } else if ((particle->maxOccurs >= UNBOUNDED) && 12709 (particle->minOccurs < 2)) { 12710 /* Special case. */ 12711 start = ctxt->state; 12712 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12713 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12714 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12715 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12716 } else { 12717 int counter; 12718 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12719 UNBOUNDED : particle->maxOccurs - 1; 12720 int minOccurs = particle->minOccurs < 1 ? 12721 0 : particle->minOccurs - 1; 12722 12723 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12724 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12725 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12726 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12727 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12728 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12729 NULL, counter); 12730 } 12731 if (particle->minOccurs == 0) { 12732 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12733 ret = 1; 12734 } 12735 } 12736 return(ret); 12737 } 12738 12739 /** 12740 * xmlSchemaBuildAContentModel: 12741 * @ctxt: the schema parser context 12742 * @particle: the particle component 12743 * @name: the complex type's name whose content is being built 12744 * 12745 * Create the automaton for the {content type} of a complex type. 12746 * 12747 * Returns 1 if the content is nillable, 0 otherwise 12748 */ 12749 static int 12750 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12751 xmlSchemaParticlePtr particle) 12752 { 12753 int ret = 0, tmp2; 12754 12755 if (particle == NULL) { 12756 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12757 return(1); 12758 } 12759 if (particle->children == NULL) { 12760 /* 12761 * Just return in this case. A missing "term" of the particle 12762 * might arise due to an invalid "term" component. 12763 */ 12764 return(1); 12765 } 12766 12767 switch (particle->children->type) { 12768 case XML_SCHEMA_TYPE_ANY: { 12769 xmlAutomataStatePtr start, end; 12770 xmlSchemaWildcardPtr wild; 12771 xmlSchemaWildcardNsPtr ns; 12772 12773 wild = (xmlSchemaWildcardPtr) particle->children; 12774 12775 start = pctxt->state; 12776 end = xmlAutomataNewState(pctxt->am); 12777 12778 if (particle->maxOccurs == 1) { 12779 if (wild->any == 1) { 12780 /* 12781 * We need to add both transitions: 12782 * 12783 * 1. the {"*", "*"} for elements in a namespace. 12784 */ 12785 pctxt->state = 12786 xmlAutomataNewTransition2(pctxt->am, 12787 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12788 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12789 /* 12790 * 2. the {"*"} for elements in no namespace. 12791 */ 12792 pctxt->state = 12793 xmlAutomataNewTransition2(pctxt->am, 12794 start, NULL, BAD_CAST "*", NULL, wild); 12795 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12796 12797 } else if (wild->nsSet != NULL) { 12798 ns = wild->nsSet; 12799 do { 12800 pctxt->state = start; 12801 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12802 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12803 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12804 ns = ns->next; 12805 } while (ns != NULL); 12806 12807 } else if (wild->negNsSet != NULL) { 12808 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12809 start, end, BAD_CAST "*", wild->negNsSet->value, 12810 wild); 12811 } 12812 } else { 12813 int counter; 12814 xmlAutomataStatePtr hop; 12815 int maxOccurs = 12816 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12817 particle->maxOccurs - 1; 12818 int minOccurs = 12819 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12820 12821 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12822 hop = xmlAutomataNewState(pctxt->am); 12823 if (wild->any == 1) { 12824 pctxt->state = 12825 xmlAutomataNewTransition2(pctxt->am, 12826 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12827 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12828 pctxt->state = 12829 xmlAutomataNewTransition2(pctxt->am, 12830 start, NULL, BAD_CAST "*", NULL, wild); 12831 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12832 } else if (wild->nsSet != NULL) { 12833 ns = wild->nsSet; 12834 do { 12835 pctxt->state = 12836 xmlAutomataNewTransition2(pctxt->am, 12837 start, NULL, BAD_CAST "*", ns->value, wild); 12838 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12839 ns = ns->next; 12840 } while (ns != NULL); 12841 12842 } else if (wild->negNsSet != NULL) { 12843 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12844 start, hop, BAD_CAST "*", wild->negNsSet->value, 12845 wild); 12846 } 12847 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12848 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12849 } 12850 if (particle->minOccurs == 0) { 12851 xmlAutomataNewEpsilon(pctxt->am, start, end); 12852 ret = 1; 12853 } 12854 pctxt->state = end; 12855 break; 12856 } 12857 case XML_SCHEMA_TYPE_ELEMENT: 12858 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12859 break; 12860 case XML_SCHEMA_TYPE_SEQUENCE:{ 12861 xmlSchemaTreeItemPtr sub; 12862 12863 ret = 1; 12864 /* 12865 * If max and min occurances are default (1) then 12866 * simply iterate over the particles of the <sequence>. 12867 */ 12868 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12869 sub = particle->children->children; 12870 12871 while (sub != NULL) { 12872 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12873 (xmlSchemaParticlePtr) sub); 12874 if (tmp2 != 1) ret = 0; 12875 sub = sub->next; 12876 } 12877 } else { 12878 xmlAutomataStatePtr oldstate = pctxt->state; 12879 12880 if (particle->maxOccurs >= UNBOUNDED) { 12881 if (particle->minOccurs > 1) { 12882 xmlAutomataStatePtr tmp; 12883 int counter; 12884 12885 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12886 oldstate, NULL); 12887 oldstate = pctxt->state; 12888 12889 counter = xmlAutomataNewCounter(pctxt->am, 12890 particle->minOccurs - 1, UNBOUNDED); 12891 12892 sub = particle->children->children; 12893 while (sub != NULL) { 12894 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12895 (xmlSchemaParticlePtr) sub); 12896 if (tmp2 != 1) ret = 0; 12897 sub = sub->next; 12898 } 12899 tmp = pctxt->state; 12900 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12901 oldstate, counter); 12902 pctxt->state = 12903 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12904 NULL, counter); 12905 if (ret == 1) 12906 xmlAutomataNewEpsilon(pctxt->am, 12907 oldstate, pctxt->state); 12908 12909 } else { 12910 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12911 oldstate, NULL); 12912 oldstate = pctxt->state; 12913 12914 sub = particle->children->children; 12915 while (sub != NULL) { 12916 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12917 (xmlSchemaParticlePtr) sub); 12918 if (tmp2 != 1) ret = 0; 12919 sub = sub->next; 12920 } 12921 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12922 oldstate); 12923 /* 12924 * epsilon needed to block previous trans from 12925 * being allowed to enter back from another 12926 * construct 12927 */ 12928 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12929 pctxt->state, NULL); 12930 if (particle->minOccurs == 0) { 12931 xmlAutomataNewEpsilon(pctxt->am, 12932 oldstate, pctxt->state); 12933 ret = 1; 12934 } 12935 } 12936 } else if ((particle->maxOccurs > 1) 12937 || (particle->minOccurs > 1)) { 12938 xmlAutomataStatePtr tmp; 12939 int counter; 12940 12941 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12942 oldstate, NULL); 12943 oldstate = pctxt->state; 12944 12945 counter = xmlAutomataNewCounter(pctxt->am, 12946 particle->minOccurs - 1, 12947 particle->maxOccurs - 1); 12948 12949 sub = particle->children->children; 12950 while (sub != NULL) { 12951 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12952 (xmlSchemaParticlePtr) sub); 12953 if (tmp2 != 1) ret = 0; 12954 sub = sub->next; 12955 } 12956 tmp = pctxt->state; 12957 xmlAutomataNewCountedTrans(pctxt->am, 12958 tmp, oldstate, counter); 12959 pctxt->state = 12960 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12961 counter); 12962 if ((particle->minOccurs == 0) || (ret == 1)) { 12963 xmlAutomataNewEpsilon(pctxt->am, 12964 oldstate, pctxt->state); 12965 ret = 1; 12966 } 12967 } else { 12968 sub = particle->children->children; 12969 while (sub != NULL) { 12970 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12971 (xmlSchemaParticlePtr) sub); 12972 if (tmp2 != 1) ret = 0; 12973 sub = sub->next; 12974 } 12975 12976 /* 12977 * epsilon needed to block previous trans from 12978 * being allowed to enter back from another 12979 * construct 12980 */ 12981 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12982 pctxt->state, NULL); 12983 12984 if (particle->minOccurs == 0) { 12985 xmlAutomataNewEpsilon(pctxt->am, oldstate, 12986 pctxt->state); 12987 ret = 1; 12988 } 12989 } 12990 } 12991 break; 12992 } 12993 case XML_SCHEMA_TYPE_CHOICE:{ 12994 xmlSchemaTreeItemPtr sub; 12995 xmlAutomataStatePtr start, end; 12996 12997 ret = 0; 12998 start = pctxt->state; 12999 end = xmlAutomataNewState(pctxt->am); 13000 13001 /* 13002 * iterate over the subtypes and remerge the end with an 13003 * epsilon transition 13004 */ 13005 if (particle->maxOccurs == 1) { 13006 sub = particle->children->children; 13007 while (sub != NULL) { 13008 pctxt->state = start; 13009 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13010 (xmlSchemaParticlePtr) sub); 13011 if (tmp2 == 1) ret = 1; 13012 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 13013 sub = sub->next; 13014 } 13015 } else { 13016 int counter; 13017 xmlAutomataStatePtr hop, base; 13018 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 13019 UNBOUNDED : particle->maxOccurs - 1; 13020 int minOccurs = 13021 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 13022 13023 /* 13024 * use a counter to keep track of the number of transtions 13025 * which went through the choice. 13026 */ 13027 counter = 13028 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 13029 hop = xmlAutomataNewState(pctxt->am); 13030 base = xmlAutomataNewState(pctxt->am); 13031 13032 sub = particle->children->children; 13033 while (sub != NULL) { 13034 pctxt->state = base; 13035 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13036 (xmlSchemaParticlePtr) sub); 13037 if (tmp2 == 1) ret = 1; 13038 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 13039 sub = sub->next; 13040 } 13041 xmlAutomataNewEpsilon(pctxt->am, start, base); 13042 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13043 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13044 if (ret == 1) 13045 xmlAutomataNewEpsilon(pctxt->am, base, end); 13046 } 13047 if (particle->minOccurs == 0) { 13048 xmlAutomataNewEpsilon(pctxt->am, start, end); 13049 ret = 1; 13050 } 13051 pctxt->state = end; 13052 break; 13053 } 13054 case XML_SCHEMA_TYPE_ALL:{ 13055 xmlAutomataStatePtr start, tmp; 13056 xmlSchemaParticlePtr sub; 13057 xmlSchemaElementPtr elemDecl; 13058 13059 ret = 1; 13060 13061 sub = (xmlSchemaParticlePtr) particle->children->children; 13062 if (sub == NULL) 13063 break; 13064 13065 ret = 0; 13066 13067 start = pctxt->state; 13068 tmp = xmlAutomataNewState(pctxt->am); 13069 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13070 pctxt->state = tmp; 13071 while (sub != NULL) { 13072 pctxt->state = tmp; 13073 13074 elemDecl = (xmlSchemaElementPtr) sub->children; 13075 if (elemDecl == NULL) { 13076 PERROR_INT("xmlSchemaBuildAContentModel", 13077 "<element> particle has no term"); 13078 return(ret); 13079 }; 13080 /* 13081 * NOTE: The {max occurs} of all the particles in the 13082 * {particles} of the group must be 0 or 1; this is 13083 * already ensured during the parse of the content of 13084 * <all>. 13085 */ 13086 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13087 int counter; 13088 13089 /* 13090 * This is an abstract group, we need to share 13091 * the same counter for all the element transitions 13092 * derived from the group 13093 */ 13094 counter = xmlAutomataNewCounter(pctxt->am, 13095 sub->minOccurs, sub->maxOccurs); 13096 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13097 sub, counter, pctxt->state); 13098 } else { 13099 if ((sub->minOccurs == 1) && 13100 (sub->maxOccurs == 1)) { 13101 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13102 pctxt->state, 13103 elemDecl->name, 13104 elemDecl->targetNamespace, 13105 1, 1, elemDecl); 13106 } else if ((sub->minOccurs == 0) && 13107 (sub->maxOccurs == 1)) { 13108 13109 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13110 pctxt->state, 13111 elemDecl->name, 13112 elemDecl->targetNamespace, 13113 0, 13114 1, 13115 elemDecl); 13116 } 13117 } 13118 sub = (xmlSchemaParticlePtr) sub->next; 13119 } 13120 pctxt->state = 13121 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13122 if (particle->minOccurs == 0) { 13123 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13124 ret = 1; 13125 } 13126 break; 13127 } 13128 case XML_SCHEMA_TYPE_GROUP: 13129 /* 13130 * If we hit a model group definition, then this means that 13131 * it was empty, thus was not substituted for the containing 13132 * model group. Just do nothing in this case. 13133 * TODO: But the group should be substituted and not occur at 13134 * all in the content model at this point. Fix this. 13135 */ 13136 ret = 1; 13137 break; 13138 default: 13139 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13140 "xmlSchemaBuildAContentModel", 13141 "found unexpected term of type '%s' in content model", 13142 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13143 return(ret); 13144 } 13145 return(ret); 13146 } 13147 13148 /** 13149 * xmlSchemaBuildContentModel: 13150 * @ctxt: the schema parser context 13151 * @type: the complex type definition 13152 * @name: the element name 13153 * 13154 * Builds the content model of the complex type. 13155 */ 13156 static void 13157 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13158 xmlSchemaParserCtxtPtr ctxt) 13159 { 13160 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13161 (type->contModel != NULL) || 13162 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13163 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13164 return; 13165 13166 #ifdef DEBUG_CONTENT 13167 xmlGenericError(xmlGenericErrorContext, 13168 "Building content model for %s\n", name); 13169 #endif 13170 ctxt->am = NULL; 13171 ctxt->am = xmlNewAutomata(); 13172 if (ctxt->am == NULL) { 13173 xmlGenericError(xmlGenericErrorContext, 13174 "Cannot create automata for complex type %s\n", type->name); 13175 return; 13176 } 13177 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13178 /* 13179 * Build the automaton. 13180 */ 13181 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13182 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13183 type->contModel = xmlAutomataCompile(ctxt->am); 13184 if (type->contModel == NULL) { 13185 xmlSchemaPCustomErr(ctxt, 13186 XML_SCHEMAP_INTERNAL, 13187 WXS_BASIC_CAST type, type->node, 13188 "Failed to compile the content model", NULL); 13189 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13190 xmlSchemaPCustomErr(ctxt, 13191 XML_SCHEMAP_NOT_DETERMINISTIC, 13192 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13193 WXS_BASIC_CAST type, type->node, 13194 "The content model is not determinist", NULL); 13195 } else { 13196 #ifdef DEBUG_CONTENT_REGEXP 13197 xmlGenericError(xmlGenericErrorContext, 13198 "Content model of %s:\n", type->name); 13199 xmlRegexpPrint(stderr, type->contModel); 13200 #endif 13201 } 13202 ctxt->state = NULL; 13203 xmlFreeAutomata(ctxt->am); 13204 ctxt->am = NULL; 13205 } 13206 13207 /** 13208 * xmlSchemaResolveElementReferences: 13209 * @elem: the schema element context 13210 * @ctxt: the schema parser context 13211 * 13212 * Resolves the references of an element declaration 13213 * or particle, which has an element declaration as it's 13214 * term. 13215 */ 13216 static void 13217 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13218 xmlSchemaParserCtxtPtr ctxt) 13219 { 13220 if ((ctxt == NULL) || (elemDecl == NULL) || 13221 ((elemDecl != NULL) && 13222 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13223 return; 13224 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13225 13226 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13227 xmlSchemaTypePtr type; 13228 13229 /* (type definition) ... otherwise the type definition `resolved` 13230 * to by the `actual value` of the type [attribute] ... 13231 */ 13232 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13233 elemDecl->namedTypeNs); 13234 if (type == NULL) { 13235 xmlSchemaPResCompAttrErr(ctxt, 13236 XML_SCHEMAP_SRC_RESOLVE, 13237 WXS_BASIC_CAST elemDecl, elemDecl->node, 13238 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13239 XML_SCHEMA_TYPE_BASIC, "type definition"); 13240 } else 13241 elemDecl->subtypes = type; 13242 } 13243 if (elemDecl->substGroup != NULL) { 13244 xmlSchemaElementPtr substHead; 13245 13246 /* 13247 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13248 * substitutionGroup? 13249 */ 13250 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13251 elemDecl->substGroupNs); 13252 if (substHead == NULL) { 13253 xmlSchemaPResCompAttrErr(ctxt, 13254 XML_SCHEMAP_SRC_RESOLVE, 13255 WXS_BASIC_CAST elemDecl, NULL, 13256 "substitutionGroup", elemDecl->substGroup, 13257 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13258 } else { 13259 xmlSchemaResolveElementReferences(substHead, ctxt); 13260 /* 13261 * Set the "substitution group affiliation". 13262 * NOTE that now we use the "refDecl" field for this. 13263 */ 13264 WXS_SUBST_HEAD(elemDecl) = substHead; 13265 /* 13266 * The type definitions is set to: 13267 * SPEC "...the {type definition} of the element 13268 * declaration `resolved` to by the `actual value` 13269 * of the substitutionGroup [attribute], if present" 13270 */ 13271 if (elemDecl->subtypes == NULL) 13272 elemDecl->subtypes = substHead->subtypes; 13273 } 13274 } 13275 /* 13276 * SPEC "The definition of anyType serves as the default type definition 13277 * for element declarations whose XML representation does not specify one." 13278 */ 13279 if ((elemDecl->subtypes == NULL) && 13280 (elemDecl->namedType == NULL) && 13281 (elemDecl->substGroup == NULL)) 13282 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13283 } 13284 13285 /** 13286 * xmlSchemaResolveUnionMemberTypes: 13287 * @ctxt: the schema parser context 13288 * @type: the schema simple type definition 13289 * 13290 * Checks and builds the "member type definitions" property of the union 13291 * simple type. This handles part (1), part (2) is done in 13292 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13293 * 13294 * Returns -1 in case of an internal error, 0 otherwise. 13295 */ 13296 static int 13297 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13298 xmlSchemaTypePtr type) 13299 { 13300 13301 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13302 xmlSchemaTypePtr memberType; 13303 13304 /* 13305 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13306 * define the explicit members as the type definitions `resolved` 13307 * to by the items in the `actual value` of the memberTypes [attribute], 13308 * if any, followed by the type definitions corresponding to the 13309 * <simpleType>s among the [children] of <union>, if any." 13310 */ 13311 /* 13312 * Resolve references. 13313 */ 13314 link = type->memberTypes; 13315 lastLink = NULL; 13316 while (link != NULL) { 13317 const xmlChar *name, *nsName; 13318 13319 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13320 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13321 13322 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13323 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13324 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13325 WXS_BASIC_CAST type, type->node, "memberTypes", 13326 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13327 /* 13328 * Remove the member type link. 13329 */ 13330 if (lastLink == NULL) 13331 type->memberTypes = link->next; 13332 else 13333 lastLink->next = link->next; 13334 newLink = link; 13335 link = link->next; 13336 xmlFree(newLink); 13337 } else { 13338 link->type = memberType; 13339 lastLink = link; 13340 link = link->next; 13341 } 13342 } 13343 /* 13344 * Add local simple types, 13345 */ 13346 memberType = type->subtypes; 13347 while (memberType != NULL) { 13348 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13349 if (link == NULL) { 13350 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13351 return (-1); 13352 } 13353 link->type = memberType; 13354 link->next = NULL; 13355 if (lastLink == NULL) 13356 type->memberTypes = link; 13357 else 13358 lastLink->next = link; 13359 lastLink = link; 13360 memberType = memberType->next; 13361 } 13362 return (0); 13363 } 13364 13365 /** 13366 * xmlSchemaIsDerivedFromBuiltInType: 13367 * @ctxt: the schema parser context 13368 * @type: the type definition 13369 * @valType: the value type 13370 * 13371 * 13372 * Returns 1 if the type has the given value type, or 13373 * is derived from such a type. 13374 */ 13375 static int 13376 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13377 { 13378 if (type == NULL) 13379 return (0); 13380 if (WXS_IS_COMPLEX(type)) 13381 return (0); 13382 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13383 if (type->builtInType == valType) 13384 return(1); 13385 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13386 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13387 return (0); 13388 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13389 } 13390 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13391 } 13392 13393 #if 0 13394 /** 13395 * xmlSchemaIsDerivedFromBuiltInType: 13396 * @ctxt: the schema parser context 13397 * @type: the type definition 13398 * @valType: the value type 13399 * 13400 * 13401 * Returns 1 if the type has the given value type, or 13402 * is derived from such a type. 13403 */ 13404 static int 13405 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13406 { 13407 if (type == NULL) 13408 return (0); 13409 if (WXS_IS_COMPLEX(type)) 13410 return (0); 13411 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13412 if (type->builtInType == valType) 13413 return(1); 13414 return (0); 13415 } else 13416 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13417 13418 return (0); 13419 } 13420 13421 static xmlSchemaTypePtr 13422 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13423 { 13424 if (type == NULL) 13425 return (NULL); 13426 if (WXS_IS_COMPLEX(type)) 13427 return (NULL); 13428 if (type->type == XML_SCHEMA_TYPE_BASIC) 13429 return(type); 13430 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13431 } 13432 #endif 13433 13434 /** 13435 * xmlSchemaGetPrimitiveType: 13436 * @type: the simpleType definition 13437 * 13438 * Returns the primitive type of the given type or 13439 * NULL in case of error. 13440 */ 13441 static xmlSchemaTypePtr 13442 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13443 { 13444 13445 while (type != NULL) { 13446 /* 13447 * Note that anySimpleType is actually not a primitive type 13448 * but we need that here. 13449 */ 13450 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13451 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13452 return (type); 13453 type = type->baseType; 13454 } 13455 13456 return (NULL); 13457 } 13458 13459 #if 0 13460 /** 13461 * xmlSchemaGetBuiltInTypeAncestor: 13462 * @type: the simpleType definition 13463 * 13464 * Returns the primitive type of the given type or 13465 * NULL in case of error. 13466 */ 13467 static xmlSchemaTypePtr 13468 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13469 { 13470 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13471 return (0); 13472 while (type != NULL) { 13473 if (type->type == XML_SCHEMA_TYPE_BASIC) 13474 return (type); 13475 type = type->baseType; 13476 } 13477 13478 return (NULL); 13479 } 13480 #endif 13481 13482 /** 13483 * xmlSchemaCloneWildcardNsConstraints: 13484 * @ctxt: the schema parser context 13485 * @dest: the destination wildcard 13486 * @source: the source wildcard 13487 * 13488 * Clones the namespace constraints of source 13489 * and assignes them to dest. 13490 * Returns -1 on internal error, 0 otherwise. 13491 */ 13492 static int 13493 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13494 xmlSchemaWildcardPtr dest, 13495 xmlSchemaWildcardPtr source) 13496 { 13497 xmlSchemaWildcardNsPtr cur, tmp, last; 13498 13499 if ((source == NULL) || (dest == NULL)) 13500 return(-1); 13501 dest->any = source->any; 13502 cur = source->nsSet; 13503 last = NULL; 13504 while (cur != NULL) { 13505 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13506 if (tmp == NULL) 13507 return(-1); 13508 tmp->value = cur->value; 13509 if (last == NULL) 13510 dest->nsSet = tmp; 13511 else 13512 last->next = tmp; 13513 last = tmp; 13514 cur = cur->next; 13515 } 13516 if (dest->negNsSet != NULL) 13517 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13518 if (source->negNsSet != NULL) { 13519 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13520 if (dest->negNsSet == NULL) 13521 return(-1); 13522 dest->negNsSet->value = source->negNsSet->value; 13523 } else 13524 dest->negNsSet = NULL; 13525 return(0); 13526 } 13527 13528 /** 13529 * xmlSchemaUnionWildcards: 13530 * @ctxt: the schema parser context 13531 * @completeWild: the first wildcard 13532 * @curWild: the second wildcard 13533 * 13534 * Unions the namespace constraints of the given wildcards. 13535 * @completeWild will hold the resulting union. 13536 * Returns a positive error code on failure, -1 in case of an 13537 * internal error, 0 otherwise. 13538 */ 13539 static int 13540 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13541 xmlSchemaWildcardPtr completeWild, 13542 xmlSchemaWildcardPtr curWild) 13543 { 13544 xmlSchemaWildcardNsPtr cur, curB, tmp; 13545 13546 /* 13547 * 1 If O1 and O2 are the same value, then that value must be the 13548 * value. 13549 */ 13550 if ((completeWild->any == curWild->any) && 13551 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13552 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13553 13554 if ((completeWild->negNsSet == NULL) || 13555 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13556 13557 if (completeWild->nsSet != NULL) { 13558 int found = 0; 13559 13560 /* 13561 * Check equality of sets. 13562 */ 13563 cur = completeWild->nsSet; 13564 while (cur != NULL) { 13565 found = 0; 13566 curB = curWild->nsSet; 13567 while (curB != NULL) { 13568 if (cur->value == curB->value) { 13569 found = 1; 13570 break; 13571 } 13572 curB = curB->next; 13573 } 13574 if (!found) 13575 break; 13576 cur = cur->next; 13577 } 13578 if (found) 13579 return(0); 13580 } else 13581 return(0); 13582 } 13583 } 13584 /* 13585 * 2 If either O1 or O2 is any, then any must be the value 13586 */ 13587 if (completeWild->any != curWild->any) { 13588 if (completeWild->any == 0) { 13589 completeWild->any = 1; 13590 if (completeWild->nsSet != NULL) { 13591 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13592 completeWild->nsSet = NULL; 13593 } 13594 if (completeWild->negNsSet != NULL) { 13595 xmlFree(completeWild->negNsSet); 13596 completeWild->negNsSet = NULL; 13597 } 13598 } 13599 return (0); 13600 } 13601 /* 13602 * 3 If both O1 and O2 are sets of (namespace names or `absent`), 13603 * then the union of those sets must be the value. 13604 */ 13605 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13606 int found; 13607 xmlSchemaWildcardNsPtr start; 13608 13609 cur = curWild->nsSet; 13610 start = completeWild->nsSet; 13611 while (cur != NULL) { 13612 found = 0; 13613 curB = start; 13614 while (curB != NULL) { 13615 if (cur->value == curB->value) { 13616 found = 1; 13617 break; 13618 } 13619 curB = curB->next; 13620 } 13621 if (!found) { 13622 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13623 if (tmp == NULL) 13624 return (-1); 13625 tmp->value = cur->value; 13626 tmp->next = completeWild->nsSet; 13627 completeWild->nsSet = tmp; 13628 } 13629 cur = cur->next; 13630 } 13631 13632 return(0); 13633 } 13634 /* 13635 * 4 If the two are negations of different values (namespace names 13636 * or `absent`), then a pair of not and `absent` must be the value. 13637 */ 13638 if ((completeWild->negNsSet != NULL) && 13639 (curWild->negNsSet != NULL) && 13640 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13641 completeWild->negNsSet->value = NULL; 13642 13643 return(0); 13644 } 13645 /* 13646 * 5. 13647 */ 13648 if (((completeWild->negNsSet != NULL) && 13649 (completeWild->negNsSet->value != NULL) && 13650 (curWild->nsSet != NULL)) || 13651 ((curWild->negNsSet != NULL) && 13652 (curWild->negNsSet->value != NULL) && 13653 (completeWild->nsSet != NULL))) { 13654 13655 int nsFound, absentFound = 0; 13656 13657 if (completeWild->nsSet != NULL) { 13658 cur = completeWild->nsSet; 13659 curB = curWild->negNsSet; 13660 } else { 13661 cur = curWild->nsSet; 13662 curB = completeWild->negNsSet; 13663 } 13664 nsFound = 0; 13665 while (cur != NULL) { 13666 if (cur->value == NULL) 13667 absentFound = 1; 13668 else if (cur->value == curB->value) 13669 nsFound = 1; 13670 if (nsFound && absentFound) 13671 break; 13672 cur = cur->next; 13673 } 13674 13675 if (nsFound && absentFound) { 13676 /* 13677 * 5.1 If the set S includes both the negated namespace 13678 * name and `absent`, then any must be the value. 13679 */ 13680 completeWild->any = 1; 13681 if (completeWild->nsSet != NULL) { 13682 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13683 completeWild->nsSet = NULL; 13684 } 13685 if (completeWild->negNsSet != NULL) { 13686 xmlFree(completeWild->negNsSet); 13687 completeWild->negNsSet = NULL; 13688 } 13689 } else if (nsFound && (!absentFound)) { 13690 /* 13691 * 5.2 If the set S includes the negated namespace name 13692 * but not `absent`, then a pair of not and `absent` must 13693 * be the value. 13694 */ 13695 if (completeWild->nsSet != NULL) { 13696 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13697 completeWild->nsSet = NULL; 13698 } 13699 if (completeWild->negNsSet == NULL) { 13700 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13701 if (completeWild->negNsSet == NULL) 13702 return (-1); 13703 } 13704 completeWild->negNsSet->value = NULL; 13705 } else if ((!nsFound) && absentFound) { 13706 /* 13707 * 5.3 If the set S includes `absent` but not the negated 13708 * namespace name, then the union is not expressible. 13709 */ 13710 xmlSchemaPErr(ctxt, completeWild->node, 13711 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13712 "The union of the wilcard is not expressible.\n", 13713 NULL, NULL); 13714 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13715 } else if ((!nsFound) && (!absentFound)) { 13716 /* 13717 * 5.4 If the set S does not include either the negated namespace 13718 * name or `absent`, then whichever of O1 or O2 is a pair of not 13719 * and a namespace name must be the value. 13720 */ 13721 if (completeWild->negNsSet == NULL) { 13722 if (completeWild->nsSet != NULL) { 13723 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13724 completeWild->nsSet = NULL; 13725 } 13726 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13727 if (completeWild->negNsSet == NULL) 13728 return (-1); 13729 completeWild->negNsSet->value = curWild->negNsSet->value; 13730 } 13731 } 13732 return (0); 13733 } 13734 /* 13735 * 6. 13736 */ 13737 if (((completeWild->negNsSet != NULL) && 13738 (completeWild->negNsSet->value == NULL) && 13739 (curWild->nsSet != NULL)) || 13740 ((curWild->negNsSet != NULL) && 13741 (curWild->negNsSet->value == NULL) && 13742 (completeWild->nsSet != NULL))) { 13743 13744 if (completeWild->nsSet != NULL) { 13745 cur = completeWild->nsSet; 13746 } else { 13747 cur = curWild->nsSet; 13748 } 13749 while (cur != NULL) { 13750 if (cur->value == NULL) { 13751 /* 13752 * 6.1 If the set S includes `absent`, then any must be the 13753 * value. 13754 */ 13755 completeWild->any = 1; 13756 if (completeWild->nsSet != NULL) { 13757 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13758 completeWild->nsSet = NULL; 13759 } 13760 if (completeWild->negNsSet != NULL) { 13761 xmlFree(completeWild->negNsSet); 13762 completeWild->negNsSet = NULL; 13763 } 13764 return (0); 13765 } 13766 cur = cur->next; 13767 } 13768 if (completeWild->negNsSet == NULL) { 13769 /* 13770 * 6.2 If the set S does not include `absent`, then a pair of not 13771 * and `absent` must be the value. 13772 */ 13773 if (completeWild->nsSet != NULL) { 13774 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13775 completeWild->nsSet = NULL; 13776 } 13777 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13778 if (completeWild->negNsSet == NULL) 13779 return (-1); 13780 completeWild->negNsSet->value = NULL; 13781 } 13782 return (0); 13783 } 13784 return (0); 13785 13786 } 13787 13788 /** 13789 * xmlSchemaIntersectWildcards: 13790 * @ctxt: the schema parser context 13791 * @completeWild: the first wildcard 13792 * @curWild: the second wildcard 13793 * 13794 * Intersects the namespace constraints of the given wildcards. 13795 * @completeWild will hold the resulting intersection. 13796 * Returns a positive error code on failure, -1 in case of an 13797 * internal error, 0 otherwise. 13798 */ 13799 static int 13800 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13801 xmlSchemaWildcardPtr completeWild, 13802 xmlSchemaWildcardPtr curWild) 13803 { 13804 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13805 13806 /* 13807 * 1 If O1 and O2 are the same value, then that value must be the 13808 * value. 13809 */ 13810 if ((completeWild->any == curWild->any) && 13811 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13812 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13813 13814 if ((completeWild->negNsSet == NULL) || 13815 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13816 13817 if (completeWild->nsSet != NULL) { 13818 int found = 0; 13819 13820 /* 13821 * Check equality of sets. 13822 */ 13823 cur = completeWild->nsSet; 13824 while (cur != NULL) { 13825 found = 0; 13826 curB = curWild->nsSet; 13827 while (curB != NULL) { 13828 if (cur->value == curB->value) { 13829 found = 1; 13830 break; 13831 } 13832 curB = curB->next; 13833 } 13834 if (!found) 13835 break; 13836 cur = cur->next; 13837 } 13838 if (found) 13839 return(0); 13840 } else 13841 return(0); 13842 } 13843 } 13844 /* 13845 * 2 If either O1 or O2 is any, then the other must be the value. 13846 */ 13847 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13848 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13849 return(-1); 13850 return(0); 13851 } 13852 /* 13853 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13854 * name or `absent`) and the other is a set of (namespace names or 13855 * `absent`), then that set, minus the negated value if it was in 13856 * the set, minus `absent` if it was in the set, must be the value. 13857 */ 13858 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13859 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13860 const xmlChar *neg; 13861 13862 if (completeWild->nsSet == NULL) { 13863 neg = completeWild->negNsSet->value; 13864 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13865 return(-1); 13866 } else 13867 neg = curWild->negNsSet->value; 13868 /* 13869 * Remove absent and negated. 13870 */ 13871 prev = NULL; 13872 cur = completeWild->nsSet; 13873 while (cur != NULL) { 13874 if (cur->value == NULL) { 13875 if (prev == NULL) 13876 completeWild->nsSet = cur->next; 13877 else 13878 prev->next = cur->next; 13879 xmlFree(cur); 13880 break; 13881 } 13882 prev = cur; 13883 cur = cur->next; 13884 } 13885 if (neg != NULL) { 13886 prev = NULL; 13887 cur = completeWild->nsSet; 13888 while (cur != NULL) { 13889 if (cur->value == neg) { 13890 if (prev == NULL) 13891 completeWild->nsSet = cur->next; 13892 else 13893 prev->next = cur->next; 13894 xmlFree(cur); 13895 break; 13896 } 13897 prev = cur; 13898 cur = cur->next; 13899 } 13900 } 13901 13902 return(0); 13903 } 13904 /* 13905 * 4 If both O1 and O2 are sets of (namespace names or `absent`), 13906 * then the intersection of those sets must be the value. 13907 */ 13908 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13909 int found; 13910 13911 cur = completeWild->nsSet; 13912 prev = NULL; 13913 while (cur != NULL) { 13914 found = 0; 13915 curB = curWild->nsSet; 13916 while (curB != NULL) { 13917 if (cur->value == curB->value) { 13918 found = 1; 13919 break; 13920 } 13921 curB = curB->next; 13922 } 13923 if (!found) { 13924 if (prev == NULL) 13925 completeWild->nsSet = cur->next; 13926 else 13927 prev->next = cur->next; 13928 tmp = cur->next; 13929 xmlFree(cur); 13930 cur = tmp; 13931 continue; 13932 } 13933 prev = cur; 13934 cur = cur->next; 13935 } 13936 13937 return(0); 13938 } 13939 /* 5 If the two are negations of different namespace names, 13940 * then the intersection is not expressible 13941 */ 13942 if ((completeWild->negNsSet != NULL) && 13943 (curWild->negNsSet != NULL) && 13944 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13945 (completeWild->negNsSet->value != NULL) && 13946 (curWild->negNsSet->value != NULL)) { 13947 13948 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13949 "The intersection of the wilcard is not expressible.\n", 13950 NULL, NULL); 13951 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13952 } 13953 /* 13954 * 6 If the one is a negation of a namespace name and the other 13955 * is a negation of `absent`, then the one which is the negation 13956 * of a namespace name must be the value. 13957 */ 13958 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13959 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13960 (completeWild->negNsSet->value == NULL)) { 13961 completeWild->negNsSet->value = curWild->negNsSet->value; 13962 } 13963 return(0); 13964 } 13965 13966 /** 13967 * xmlSchemaIsWildcardNsConstraintSubset: 13968 * @ctxt: the schema parser context 13969 * @sub: the first wildcard 13970 * @super: the second wildcard 13971 * 13972 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13973 * 13974 * Returns 0 if the namespace constraint of @sub is an intensional 13975 * subset of @super, 1 otherwise. 13976 */ 13977 static int 13978 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 13979 xmlSchemaWildcardPtr super) 13980 { 13981 /* 13982 * 1 super must be any. 13983 */ 13984 if (super->any) 13985 return (0); 13986 /* 13987 * 2.1 sub must be a pair of not and a namespace name or `absent`. 13988 * 2.2 super must be a pair of not and the same value. 13989 */ 13990 if ((sub->negNsSet != NULL) && 13991 (super->negNsSet != NULL) && 13992 (sub->negNsSet->value == super->negNsSet->value)) 13993 return (0); 13994 /* 13995 * 3.1 sub must be a set whose members are either namespace names or `absent`. 13996 */ 13997 if (sub->nsSet != NULL) { 13998 /* 13999 * 3.2.1 super must be the same set or a superset thereof. 14000 */ 14001 if (super->nsSet != NULL) { 14002 xmlSchemaWildcardNsPtr cur, curB; 14003 int found = 0; 14004 14005 cur = sub->nsSet; 14006 while (cur != NULL) { 14007 found = 0; 14008 curB = super->nsSet; 14009 while (curB != NULL) { 14010 if (cur->value == curB->value) { 14011 found = 1; 14012 break; 14013 } 14014 curB = curB->next; 14015 } 14016 if (!found) 14017 return (1); 14018 cur = cur->next; 14019 } 14020 if (found) 14021 return (0); 14022 } else if (super->negNsSet != NULL) { 14023 xmlSchemaWildcardNsPtr cur; 14024 /* 14025 * 3.2.2 super must be a pair of not and a namespace name or 14026 * `absent` and that value must not be in sub's set. 14027 */ 14028 cur = sub->nsSet; 14029 while (cur != NULL) { 14030 if (cur->value == super->negNsSet->value) 14031 return (1); 14032 cur = cur->next; 14033 } 14034 return (0); 14035 } 14036 } 14037 return (1); 14038 } 14039 14040 static int 14041 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 14042 int *fixed, 14043 const xmlChar **value, 14044 xmlSchemaValPtr *val) 14045 { 14046 *fixed = 0; 14047 *value = NULL; 14048 if (val != 0) 14049 *val = NULL; 14050 14051 if (attruse->defValue != NULL) { 14052 *value = attruse->defValue; 14053 if (val != NULL) 14054 *val = attruse->defVal; 14055 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14056 *fixed = 1; 14057 return(1); 14058 } else if ((attruse->attrDecl != NULL) && 14059 (attruse->attrDecl->defValue != NULL)) { 14060 *value = attruse->attrDecl->defValue; 14061 if (val != NULL) 14062 *val = attruse->attrDecl->defVal; 14063 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14064 *fixed = 1; 14065 return(1); 14066 } 14067 return(0); 14068 } 14069 /** 14070 * xmlSchemaCheckCVCWildcardNamespace: 14071 * @wild: the wildcard 14072 * @ns: the namespace 14073 * 14074 * Validation Rule: Wildcard allows Namespace Name 14075 * (cvc-wildcard-namespace) 14076 * 14077 * Returns 0 if the given namespace matches the wildcard, 14078 * 1 otherwise and -1 on API errors. 14079 */ 14080 static int 14081 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14082 const xmlChar* ns) 14083 { 14084 if (wild == NULL) 14085 return(-1); 14086 14087 if (wild->any) 14088 return(0); 14089 else if (wild->nsSet != NULL) { 14090 xmlSchemaWildcardNsPtr cur; 14091 14092 cur = wild->nsSet; 14093 while (cur != NULL) { 14094 if (xmlStrEqual(cur->value, ns)) 14095 return(0); 14096 cur = cur->next; 14097 } 14098 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14099 (!xmlStrEqual(wild->negNsSet->value, ns))) 14100 return(0); 14101 14102 return(1); 14103 } 14104 14105 #define XML_SCHEMA_ACTION_DERIVE 0 14106 #define XML_SCHEMA_ACTION_REDEFINE 1 14107 14108 #define WXS_ACTION_STR(a) \ 14109 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14110 14111 /* 14112 * Schema Component Constraint: 14113 * Derivation Valid (Restriction, Complex) 14114 * derivation-ok-restriction (2) - (4) 14115 * 14116 * ATTENTION: 14117 * In XML Schema 1.1 this will be: 14118 * Validation Rule: 14119 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14120 * 14121 */ 14122 static int 14123 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14124 int action, 14125 xmlSchemaBasicItemPtr item, 14126 xmlSchemaBasicItemPtr baseItem, 14127 xmlSchemaItemListPtr uses, 14128 xmlSchemaItemListPtr baseUses, 14129 xmlSchemaWildcardPtr wild, 14130 xmlSchemaWildcardPtr baseWild) 14131 { 14132 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14133 int i, j, found; /* err = 0; */ 14134 const xmlChar *bEffValue; 14135 int effFixed; 14136 14137 if (uses != NULL) { 14138 for (i = 0; i < uses->nbItems; i++) { 14139 cur = uses->items[i]; 14140 found = 0; 14141 if (baseUses == NULL) 14142 goto not_found; 14143 for (j = 0; j < baseUses->nbItems; j++) { 14144 bcur = baseUses->items[j]; 14145 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14146 WXS_ATTRUSE_DECL_NAME(bcur)) && 14147 (WXS_ATTRUSE_DECL_TNS(cur) == 14148 WXS_ATTRUSE_DECL_TNS(bcur))) 14149 { 14150 /* 14151 * (2.1) "If there is an attribute use in the {attribute 14152 * uses} of the {base type definition} (call this B) whose 14153 * {attribute declaration} has the same {name} and {target 14154 * namespace}, then all of the following must be true:" 14155 */ 14156 found = 1; 14157 14158 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14159 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14160 { 14161 xmlChar *str = NULL; 14162 /* 14163 * (2.1.1) "one of the following must be true:" 14164 * (2.1.1.1) "B's {required} is false." 14165 * (2.1.1.2) "R's {required} is true." 14166 */ 14167 xmlSchemaPAttrUseErr4(pctxt, 14168 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14169 WXS_ITEM_NODE(item), item, cur, 14170 "The 'optional' attribute use is inconsistent " 14171 "with the corresponding 'required' attribute use of " 14172 "the %s %s", 14173 WXS_ACTION_STR(action), 14174 xmlSchemaGetComponentDesignation(&str, baseItem), 14175 NULL, NULL); 14176 FREE_AND_NULL(str); 14177 /* err = pctxt->err; */ 14178 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14179 WXS_ATTRUSE_TYPEDEF(cur), 14180 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14181 { 14182 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14183 14184 /* 14185 * SPEC (2.1.2) "R's {attribute declaration}'s 14186 * {type definition} must be validly derived from 14187 * B's {type definition} given the empty set as 14188 * defined in Type Derivation OK (Simple) ($3.14.6)." 14189 */ 14190 xmlSchemaPAttrUseErr4(pctxt, 14191 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14192 WXS_ITEM_NODE(item), item, cur, 14193 "The attribute declaration's %s " 14194 "is not validly derived from " 14195 "the corresponding %s of the " 14196 "attribute declaration in the %s %s", 14197 xmlSchemaGetComponentDesignation(&strA, 14198 WXS_ATTRUSE_TYPEDEF(cur)), 14199 xmlSchemaGetComponentDesignation(&strB, 14200 WXS_ATTRUSE_TYPEDEF(bcur)), 14201 WXS_ACTION_STR(action), 14202 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14203 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14204 FREE_AND_NULL(strA); 14205 FREE_AND_NULL(strB); 14206 FREE_AND_NULL(strC); 14207 /* err = pctxt->err; */ 14208 } else { 14209 /* 14210 * 2.1.3 [Definition:] Let the effective value 14211 * constraint of an attribute use be its {value 14212 * constraint}, if present, otherwise its {attribute 14213 * declaration}'s {value constraint} . 14214 */ 14215 xmlSchemaGetEffectiveValueConstraint(bcur, 14216 &effFixed, &bEffValue, NULL); 14217 /* 14218 * 2.1.3 ... one of the following must be true 14219 * 14220 * 2.1.3.1 B's `effective value constraint` is 14221 * `absent` or default. 14222 */ 14223 if ((bEffValue != NULL) && 14224 (effFixed == 1)) { 14225 const xmlChar *rEffValue = NULL; 14226 14227 xmlSchemaGetEffectiveValueConstraint(bcur, 14228 &effFixed, &rEffValue, NULL); 14229 /* 14230 * 2.1.3.2 R's `effective value constraint` is 14231 * fixed with the same string as B's. 14232 * MAYBE TODO: Compare the computed values. 14233 * Hmm, it says "same string" so 14234 * string-equality might really be sufficient. 14235 */ 14236 if ((effFixed == 0) || 14237 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14238 { 14239 xmlChar *str = NULL; 14240 14241 xmlSchemaPAttrUseErr4(pctxt, 14242 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14243 WXS_ITEM_NODE(item), item, cur, 14244 "The effective value constraint of the " 14245 "attribute use is inconsistent with " 14246 "its correspondent in the %s %s", 14247 WXS_ACTION_STR(action), 14248 xmlSchemaGetComponentDesignation(&str, 14249 baseItem), 14250 NULL, NULL); 14251 FREE_AND_NULL(str); 14252 /* err = pctxt->err; */ 14253 } 14254 } 14255 } 14256 break; 14257 } 14258 } 14259 not_found: 14260 if (!found) { 14261 /* 14262 * (2.2) "otherwise the {base type definition} must have an 14263 * {attribute wildcard} and the {target namespace} of the 14264 * R's {attribute declaration} must be `valid` with respect 14265 * to that wildcard, as defined in Wildcard allows Namespace 14266 * Name ($3.10.4)." 14267 */ 14268 if ((baseWild == NULL) || 14269 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14270 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14271 { 14272 xmlChar *str = NULL; 14273 14274 xmlSchemaPAttrUseErr4(pctxt, 14275 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14276 WXS_ITEM_NODE(item), item, cur, 14277 "Neither a matching attribute use, " 14278 "nor a matching wildcard exists in the %s %s", 14279 WXS_ACTION_STR(action), 14280 xmlSchemaGetComponentDesignation(&str, baseItem), 14281 NULL, NULL); 14282 FREE_AND_NULL(str); 14283 /* err = pctxt->err; */ 14284 } 14285 } 14286 } 14287 } 14288 /* 14289 * SPEC derivation-ok-restriction (3): 14290 * (3) "For each attribute use in the {attribute uses} of the {base type 14291 * definition} whose {required} is true, there must be an attribute 14292 * use with an {attribute declaration} with the same {name} and 14293 * {target namespace} as its {attribute declaration} in the {attribute 14294 * uses} of the complex type definition itself whose {required} is true. 14295 */ 14296 if (baseUses != NULL) { 14297 for (j = 0; j < baseUses->nbItems; j++) { 14298 bcur = baseUses->items[j]; 14299 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14300 continue; 14301 found = 0; 14302 if (uses != NULL) { 14303 for (i = 0; i < uses->nbItems; i++) { 14304 cur = uses->items[i]; 14305 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14306 WXS_ATTRUSE_DECL_NAME(bcur)) && 14307 (WXS_ATTRUSE_DECL_TNS(cur) == 14308 WXS_ATTRUSE_DECL_TNS(bcur))) { 14309 found = 1; 14310 break; 14311 } 14312 } 14313 } 14314 if (!found) { 14315 xmlChar *strA = NULL, *strB = NULL; 14316 14317 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14318 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14319 NULL, item, 14320 "A matching attribute use for the " 14321 "'required' %s of the %s %s is missing", 14322 xmlSchemaGetComponentDesignation(&strA, bcur), 14323 WXS_ACTION_STR(action), 14324 xmlSchemaGetComponentDesignation(&strB, baseItem), 14325 NULL); 14326 FREE_AND_NULL(strA); 14327 FREE_AND_NULL(strB); 14328 } 14329 } 14330 } 14331 /* 14332 * derivation-ok-restriction (4) 14333 */ 14334 if (wild != NULL) { 14335 /* 14336 * (4) "If there is an {attribute wildcard}, all of the 14337 * following must be true:" 14338 */ 14339 if (baseWild == NULL) { 14340 xmlChar *str = NULL; 14341 14342 /* 14343 * (4.1) "The {base type definition} must also have one." 14344 */ 14345 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14346 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14347 NULL, item, 14348 "The %s has an attribute wildcard, " 14349 "but the %s %s '%s' does not have one", 14350 WXS_ITEM_TYPE_NAME(item), 14351 WXS_ACTION_STR(action), 14352 WXS_ITEM_TYPE_NAME(baseItem), 14353 xmlSchemaGetComponentQName(&str, baseItem)); 14354 FREE_AND_NULL(str); 14355 return(pctxt->err); 14356 } else if ((baseWild->any == 0) && 14357 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14358 { 14359 xmlChar *str = NULL; 14360 /* 14361 * (4.2) "The complex type definition's {attribute wildcard}'s 14362 * {namespace constraint} must be a subset of the {base type 14363 * definition}'s {attribute wildcard}'s {namespace constraint}, 14364 * as defined by Wildcard Subset ($3.10.6)." 14365 */ 14366 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14367 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14368 NULL, item, 14369 "The attribute wildcard is not a valid " 14370 "subset of the wildcard in the %s %s '%s'", 14371 WXS_ACTION_STR(action), 14372 WXS_ITEM_TYPE_NAME(baseItem), 14373 xmlSchemaGetComponentQName(&str, baseItem), 14374 NULL); 14375 FREE_AND_NULL(str); 14376 return(pctxt->err); 14377 } 14378 /* 4.3 Unless the {base type definition} is the `ur-type 14379 * definition`, the complex type definition's {attribute 14380 * wildcard}'s {process contents} must be identical to or 14381 * stronger than the {base type definition}'s {attribute 14382 * wildcard}'s {process contents}, where strict is stronger 14383 * than lax is stronger than skip. 14384 */ 14385 if ((! WXS_IS_ANYTYPE(baseItem)) && 14386 (wild->processContents < baseWild->processContents)) { 14387 xmlChar *str = NULL; 14388 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14389 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14390 NULL, baseItem, 14391 "The {process contents} of the attribute wildcard is " 14392 "weaker than the one in the %s %s '%s'", 14393 WXS_ACTION_STR(action), 14394 WXS_ITEM_TYPE_NAME(baseItem), 14395 xmlSchemaGetComponentQName(&str, baseItem), 14396 NULL); 14397 FREE_AND_NULL(str) 14398 return(pctxt->err); 14399 } 14400 } 14401 return(0); 14402 } 14403 14404 14405 static int 14406 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14407 xmlSchemaBasicItemPtr item, 14408 xmlSchemaWildcardPtr *completeWild, 14409 xmlSchemaItemListPtr list, 14410 xmlSchemaItemListPtr prohibs); 14411 /** 14412 * xmlSchemaFixupTypeAttributeUses: 14413 * @ctxt: the schema parser context 14414 * @type: the complex type definition 14415 * 14416 * 14417 * Builds the wildcard and the attribute uses on the given complex type. 14418 * Returns -1 if an internal error occurs, 0 otherwise. 14419 * 14420 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14421 * strings, so recheck this if we start to hardcode some schemata, since 14422 * they might not be in the same dict. 14423 * NOTE: It is allowed to "extend" the xs:anyType type. 14424 */ 14425 static int 14426 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14427 xmlSchemaTypePtr type) 14428 { 14429 xmlSchemaTypePtr baseType = NULL; 14430 xmlSchemaAttributeUsePtr use; 14431 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14432 14433 if (type->baseType == NULL) { 14434 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14435 "no base type"); 14436 return (-1); 14437 } 14438 baseType = type->baseType; 14439 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14440 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14441 return(-1); 14442 14443 uses = type->attrUses; 14444 baseUses = baseType->attrUses; 14445 /* 14446 * Expand attribute group references. And build the 'complete' 14447 * wildcard, i.e. intersect multiple wildcards. 14448 * Move attribute prohibitions into a separate list. 14449 */ 14450 if (uses != NULL) { 14451 if (WXS_IS_RESTRICTION(type)) { 14452 /* 14453 * This one will transfer all attr. prohibitions 14454 * into pctxt->attrProhibs. 14455 */ 14456 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14457 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14458 pctxt->attrProhibs) == -1) 14459 { 14460 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14461 "failed to expand attributes"); 14462 } 14463 if (pctxt->attrProhibs->nbItems != 0) 14464 prohibs = pctxt->attrProhibs; 14465 } else { 14466 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14467 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14468 NULL) == -1) 14469 { 14470 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14471 "failed to expand attributes"); 14472 } 14473 } 14474 } 14475 /* 14476 * Inherit the attribute uses of the base type. 14477 */ 14478 if (baseUses != NULL) { 14479 int i, j; 14480 xmlSchemaAttributeUseProhibPtr pro; 14481 14482 if (WXS_IS_RESTRICTION(type)) { 14483 int usesCount; 14484 xmlSchemaAttributeUsePtr tmp; 14485 14486 if (uses != NULL) 14487 usesCount = uses->nbItems; 14488 else 14489 usesCount = 0; 14490 14491 /* Restriction. */ 14492 for (i = 0; i < baseUses->nbItems; i++) { 14493 use = baseUses->items[i]; 14494 if (prohibs) { 14495 /* 14496 * Filter out prohibited uses. 14497 */ 14498 for (j = 0; j < prohibs->nbItems; j++) { 14499 pro = prohibs->items[j]; 14500 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14501 (WXS_ATTRUSE_DECL_TNS(use) == 14502 pro->targetNamespace)) 14503 { 14504 goto inherit_next; 14505 } 14506 } 14507 } 14508 if (usesCount) { 14509 /* 14510 * Filter out existing uses. 14511 */ 14512 for (j = 0; j < usesCount; j++) { 14513 tmp = uses->items[j]; 14514 if ((WXS_ATTRUSE_DECL_NAME(use) == 14515 WXS_ATTRUSE_DECL_NAME(tmp)) && 14516 (WXS_ATTRUSE_DECL_TNS(use) == 14517 WXS_ATTRUSE_DECL_TNS(tmp))) 14518 { 14519 goto inherit_next; 14520 } 14521 } 14522 } 14523 if (uses == NULL) { 14524 type->attrUses = xmlSchemaItemListCreate(); 14525 if (type->attrUses == NULL) 14526 goto exit_failure; 14527 uses = type->attrUses; 14528 } 14529 xmlSchemaItemListAddSize(uses, 2, use); 14530 inherit_next: {} 14531 } 14532 } else { 14533 /* Extension. */ 14534 for (i = 0; i < baseUses->nbItems; i++) { 14535 use = baseUses->items[i]; 14536 if (uses == NULL) { 14537 type->attrUses = xmlSchemaItemListCreate(); 14538 if (type->attrUses == NULL) 14539 goto exit_failure; 14540 uses = type->attrUses; 14541 } 14542 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14543 } 14544 } 14545 } 14546 /* 14547 * Shrink attr. uses. 14548 */ 14549 if (uses) { 14550 if (uses->nbItems == 0) { 14551 xmlSchemaItemListFree(uses); 14552 type->attrUses = NULL; 14553 } 14554 /* 14555 * TODO: We could shrink the size of the array 14556 * to fit the actual number of items. 14557 */ 14558 } 14559 /* 14560 * Compute the complete wildcard. 14561 */ 14562 if (WXS_IS_EXTENSION(type)) { 14563 if (baseType->attributeWildcard != NULL) { 14564 /* 14565 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then 14566 * the appropriate case among the following:" 14567 */ 14568 if (type->attributeWildcard != NULL) { 14569 /* 14570 * Union the complete wildcard with the base wildcard. 14571 * SPEC {attribute wildcard} 14572 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14573 * and {annotation} are those of the `complete wildcard`, 14574 * and whose {namespace constraint} is the intensional union 14575 * of the {namespace constraint} of the `complete wildcard` 14576 * and of the `base wildcard`, as defined in Attribute 14577 * Wildcard Union ($3.10.6)." 14578 */ 14579 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14580 baseType->attributeWildcard) == -1) 14581 goto exit_failure; 14582 } else { 14583 /* 14584 * (3.2.2.1.1) "If the `complete wildcard` is `absent`, 14585 * then the `base wildcard`." 14586 */ 14587 type->attributeWildcard = baseType->attributeWildcard; 14588 } 14589 } else { 14590 /* 14591 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the 14592 * `complete wildcard`" 14593 * NOOP 14594 */ 14595 } 14596 } else { 14597 /* 14598 * SPEC {attribute wildcard} 14599 * (3.1) "If the <restriction> alternative is chosen, then the 14600 * `complete wildcard`;" 14601 * NOOP 14602 */ 14603 } 14604 14605 return (0); 14606 14607 exit_failure: 14608 return(-1); 14609 } 14610 14611 /** 14612 * xmlSchemaTypeFinalContains: 14613 * @schema: the schema 14614 * @type: the type definition 14615 * @final: the final 14616 * 14617 * Evaluates if a type definition contains the given "final". 14618 * This does take "finalDefault" into account as well. 14619 * 14620 * Returns 1 if the type does containt the given "final", 14621 * 0 otherwise. 14622 */ 14623 static int 14624 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14625 { 14626 if (type == NULL) 14627 return (0); 14628 if (type->flags & final) 14629 return (1); 14630 else 14631 return (0); 14632 } 14633 14634 /** 14635 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14636 * @type: the Union Simple Type 14637 * 14638 * Returns a list of member types of @type if existing, 14639 * returns NULL otherwise. 14640 */ 14641 static xmlSchemaTypeLinkPtr 14642 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14643 { 14644 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14645 if (type->memberTypes != NULL) 14646 return (type->memberTypes); 14647 else 14648 type = type->baseType; 14649 } 14650 return (NULL); 14651 } 14652 14653 /** 14654 * xmlSchemaGetParticleTotalRangeMin: 14655 * @particle: the particle 14656 * 14657 * Schema Component Constraint: Effective Total Range 14658 * (all and sequence) + (choice) 14659 * 14660 * Returns the minimun Effective Total Range. 14661 */ 14662 static int 14663 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14664 { 14665 if ((particle->children == NULL) || 14666 (particle->minOccurs == 0)) 14667 return (0); 14668 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14669 int min = -1, cur; 14670 xmlSchemaParticlePtr part = 14671 (xmlSchemaParticlePtr) particle->children->children; 14672 14673 if (part == NULL) 14674 return (0); 14675 while (part != NULL) { 14676 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14677 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14678 cur = part->minOccurs; 14679 else 14680 cur = xmlSchemaGetParticleTotalRangeMin(part); 14681 if (cur == 0) 14682 return (0); 14683 if ((min > cur) || (min == -1)) 14684 min = cur; 14685 part = (xmlSchemaParticlePtr) part->next; 14686 } 14687 return (particle->minOccurs * min); 14688 } else { 14689 /* <all> and <sequence> */ 14690 int sum = 0; 14691 xmlSchemaParticlePtr part = 14692 (xmlSchemaParticlePtr) particle->children->children; 14693 14694 if (part == NULL) 14695 return (0); 14696 do { 14697 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14698 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14699 sum += part->minOccurs; 14700 else 14701 sum += xmlSchemaGetParticleTotalRangeMin(part); 14702 part = (xmlSchemaParticlePtr) part->next; 14703 } while (part != NULL); 14704 return (particle->minOccurs * sum); 14705 } 14706 } 14707 14708 #if 0 14709 /** 14710 * xmlSchemaGetParticleTotalRangeMax: 14711 * @particle: the particle 14712 * 14713 * Schema Component Constraint: Effective Total Range 14714 * (all and sequence) + (choice) 14715 * 14716 * Returns the maximum Effective Total Range. 14717 */ 14718 static int 14719 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14720 { 14721 if ((particle->children == NULL) || 14722 (particle->children->children == NULL)) 14723 return (0); 14724 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14725 int max = -1, cur; 14726 xmlSchemaParticlePtr part = 14727 (xmlSchemaParticlePtr) particle->children->children; 14728 14729 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14730 if (part->children == NULL) 14731 continue; 14732 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14733 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14734 cur = part->maxOccurs; 14735 else 14736 cur = xmlSchemaGetParticleTotalRangeMax(part); 14737 if (cur == UNBOUNDED) 14738 return (UNBOUNDED); 14739 if ((max < cur) || (max == -1)) 14740 max = cur; 14741 } 14742 /* TODO: Handle overflows? */ 14743 return (particle->maxOccurs * max); 14744 } else { 14745 /* <all> and <sequence> */ 14746 int sum = 0, cur; 14747 xmlSchemaParticlePtr part = 14748 (xmlSchemaParticlePtr) particle->children->children; 14749 14750 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14751 if (part->children == NULL) 14752 continue; 14753 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14754 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14755 cur = part->maxOccurs; 14756 else 14757 cur = xmlSchemaGetParticleTotalRangeMax(part); 14758 if (cur == UNBOUNDED) 14759 return (UNBOUNDED); 14760 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14761 return (UNBOUNDED); 14762 sum += cur; 14763 } 14764 /* TODO: Handle overflows? */ 14765 return (particle->maxOccurs * sum); 14766 } 14767 } 14768 #endif 14769 14770 /** 14771 * xmlSchemaIsParticleEmptiable: 14772 * @particle: the particle 14773 * 14774 * Schema Component Constraint: Particle Emptiable 14775 * Checks whether the given particle is emptiable. 14776 * 14777 * Returns 1 if emptiable, 0 otherwise. 14778 */ 14779 static int 14780 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14781 { 14782 /* 14783 * SPEC (1) "Its {min occurs} is 0." 14784 */ 14785 if ((particle == NULL) || (particle->minOccurs == 0) || 14786 (particle->children == NULL)) 14787 return (1); 14788 /* 14789 * SPEC (2) "Its {term} is a group and the minimum part of the 14790 * effective total range of that group, [...] is 0." 14791 */ 14792 if (WXS_IS_MODEL_GROUP(particle->children)) { 14793 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14794 return (1); 14795 } 14796 return (0); 14797 } 14798 14799 /** 14800 * xmlSchemaCheckCOSSTDerivedOK: 14801 * @actxt: a context 14802 * @type: the derived simple type definition 14803 * @baseType: the base type definition 14804 * @subset: the subset of ('restriction', ect.) 14805 * 14806 * Schema Component Constraint: 14807 * Type Derivation OK (Simple) (cos-st-derived-OK) 14808 * 14809 * Checks wheter @type can be validly 14810 * derived from @baseType. 14811 * 14812 * Returns 0 on success, an positive error code otherwise. 14813 */ 14814 static int 14815 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14816 xmlSchemaTypePtr type, 14817 xmlSchemaTypePtr baseType, 14818 int subset) 14819 { 14820 /* 14821 * 1 They are the same type definition. 14822 * TODO: The identy check might have to be more complex than this. 14823 */ 14824 if (type == baseType) 14825 return (0); 14826 /* 14827 * 2.1 restriction is not in the subset, or in the {final} 14828 * of its own {base type definition}; 14829 * 14830 * NOTE that this will be used also via "xsi:type". 14831 * 14832 * TODO: Revise this, it looks strange. How can the "type" 14833 * not be fixed or *in* fixing? 14834 */ 14835 if (WXS_IS_TYPE_NOT_FIXED(type)) 14836 if (xmlSchemaTypeFixup(type, actxt) == -1) 14837 return(-1); 14838 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14839 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14840 return(-1); 14841 if ((subset & SUBSET_RESTRICTION) || 14842 (xmlSchemaTypeFinalContains(type->baseType, 14843 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14844 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14845 } 14846 /* 2.2 */ 14847 if (type->baseType == baseType) { 14848 /* 14849 * 2.2.1 D's `base type definition` is B. 14850 */ 14851 return (0); 14852 } 14853 /* 14854 * 2.2.2 D's `base type definition` is not the `ur-type definition` 14855 * and is validly derived from B given the subset, as defined by this 14856 * constraint. 14857 */ 14858 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14859 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14860 baseType, subset) == 0)) { 14861 return (0); 14862 } 14863 /* 14864 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type 14865 * definition`. 14866 */ 14867 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14868 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14869 return (0); 14870 } 14871 /* 14872 * 2.2.4 B's {variety} is union and D is validly derived from a type 14873 * definition in B's {member type definitions} given the subset, as 14874 * defined by this constraint. 14875 * 14876 * NOTE: This seems not to involve built-in types, since there is no 14877 * built-in Union Simple Type. 14878 */ 14879 if (WXS_IS_UNION(baseType)) { 14880 xmlSchemaTypeLinkPtr cur; 14881 14882 cur = baseType->memberTypes; 14883 while (cur != NULL) { 14884 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14885 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14886 return(-1); 14887 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14888 type, cur->type, subset) == 0) 14889 { 14890 /* 14891 * It just has to be validly derived from at least one 14892 * member-type. 14893 */ 14894 return (0); 14895 } 14896 cur = cur->next; 14897 } 14898 } 14899 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14900 } 14901 14902 /** 14903 * xmlSchemaCheckTypeDefCircularInternal: 14904 * @pctxt: the schema parser context 14905 * @ctxtType: the type definition 14906 * @ancestor: an ancestor of @ctxtType 14907 * 14908 * Checks st-props-correct (2) + ct-props-correct (3). 14909 * Circular type definitions are not allowed. 14910 * 14911 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14912 * circular, 0 otherwise. 14913 */ 14914 static int 14915 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14916 xmlSchemaTypePtr ctxtType, 14917 xmlSchemaTypePtr ancestor) 14918 { 14919 int ret; 14920 14921 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14922 return (0); 14923 14924 if (ctxtType == ancestor) { 14925 xmlSchemaPCustomErr(pctxt, 14926 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14927 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14928 "The definition is circular", NULL); 14929 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14930 } 14931 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14932 /* 14933 * Avoid inifinite recursion on circular types not yet checked. 14934 */ 14935 return (0); 14936 } 14937 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14938 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14939 ancestor->baseType); 14940 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14941 return (ret); 14942 } 14943 14944 /** 14945 * xmlSchemaCheckTypeDefCircular: 14946 * @item: the complex/simple type definition 14947 * @ctxt: the parser context 14948 * @name: the name 14949 * 14950 * Checks for circular type definitions. 14951 */ 14952 static void 14953 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14954 xmlSchemaParserCtxtPtr ctxt) 14955 { 14956 if ((item == NULL) || 14957 (item->type == XML_SCHEMA_TYPE_BASIC) || 14958 (item->baseType == NULL)) 14959 return; 14960 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14961 item->baseType); 14962 } 14963 14964 /* 14965 * Simple Type Definition Representation OK (src-simple-type) 4 14966 * 14967 * "4 Circular union type definition is disallowed. That is, if the 14968 * <union> alternative is chosen, there must not be any entries in the 14969 * memberTypes [attribute] at any depth which resolve to the component 14970 * corresponding to the <simpleType>." 14971 * 14972 * Note that this should work on the *representation* of a component, 14973 * thus assumes any union types in the member types not being yet 14974 * substituted. At this stage we need the variety of the types 14975 * to be already computed. 14976 */ 14977 static int 14978 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 14979 xmlSchemaTypePtr ctxType, 14980 xmlSchemaTypeLinkPtr members) 14981 { 14982 xmlSchemaTypeLinkPtr member; 14983 xmlSchemaTypePtr memberType; 14984 14985 member = members; 14986 while (member != NULL) { 14987 memberType = member->type; 14988 while ((memberType != NULL) && 14989 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 14990 if (memberType == ctxType) { 14991 xmlSchemaPCustomErr(pctxt, 14992 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 14993 WXS_BASIC_CAST ctxType, NULL, 14994 "The union type definition is circular", NULL); 14995 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 14996 } 14997 if ((WXS_IS_UNION(memberType)) && 14998 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 14999 { 15000 int res; 15001 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 15002 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 15003 ctxType, 15004 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 15005 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 15006 if (res != 0) 15007 return(res); 15008 } 15009 memberType = memberType->baseType; 15010 } 15011 member = member->next; 15012 } 15013 return(0); 15014 } 15015 15016 static int 15017 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 15018 xmlSchemaTypePtr type) 15019 { 15020 if (! WXS_IS_UNION(type)) 15021 return(0); 15022 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 15023 type->memberTypes)); 15024 } 15025 15026 /** 15027 * xmlSchemaResolveTypeReferences: 15028 * @item: the complex/simple type definition 15029 * @ctxt: the parser context 15030 * @name: the name 15031 * 15032 * Resolvese type definition references 15033 */ 15034 static void 15035 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 15036 xmlSchemaParserCtxtPtr ctxt) 15037 { 15038 if (typeDef == NULL) 15039 return; 15040 15041 /* 15042 * Resolve the base type. 15043 */ 15044 if (typeDef->baseType == NULL) { 15045 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15046 typeDef->base, typeDef->baseNs); 15047 if (typeDef->baseType == NULL) { 15048 xmlSchemaPResCompAttrErr(ctxt, 15049 XML_SCHEMAP_SRC_RESOLVE, 15050 WXS_BASIC_CAST typeDef, typeDef->node, 15051 "base", typeDef->base, typeDef->baseNs, 15052 XML_SCHEMA_TYPE_SIMPLE, NULL); 15053 return; 15054 } 15055 } 15056 if (WXS_IS_SIMPLE(typeDef)) { 15057 if (WXS_IS_UNION(typeDef)) { 15058 /* 15059 * Resolve the memberTypes. 15060 */ 15061 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15062 return; 15063 } else if (WXS_IS_LIST(typeDef)) { 15064 /* 15065 * Resolve the itemType. 15066 */ 15067 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15068 15069 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15070 typeDef->base, typeDef->baseNs); 15071 15072 if ((typeDef->subtypes == NULL) || 15073 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15074 { 15075 typeDef->subtypes = NULL; 15076 xmlSchemaPResCompAttrErr(ctxt, 15077 XML_SCHEMAP_SRC_RESOLVE, 15078 WXS_BASIC_CAST typeDef, typeDef->node, 15079 "itemType", typeDef->base, typeDef->baseNs, 15080 XML_SCHEMA_TYPE_SIMPLE, NULL); 15081 } 15082 } 15083 return; 15084 } 15085 } 15086 /* 15087 * The ball of letters below means, that if we have a particle 15088 * which has a QName-helper component as its {term}, we want 15089 * to resolve it... 15090 */ 15091 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15092 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15093 XML_SCHEMA_TYPE_PARTICLE) && 15094 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15095 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15096 XML_SCHEMA_EXTRA_QNAMEREF)) 15097 { 15098 xmlSchemaQNameRefPtr ref = 15099 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15100 xmlSchemaModelGroupDefPtr groupDef; 15101 15102 /* 15103 * URGENT TODO: Test this. 15104 */ 15105 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15106 /* 15107 * Resolve the MG definition reference. 15108 */ 15109 groupDef = 15110 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15111 ref->itemType, ref->name, ref->targetNamespace); 15112 if (groupDef == NULL) { 15113 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15114 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15115 "ref", ref->name, ref->targetNamespace, ref->itemType, 15116 NULL); 15117 /* Remove the particle. */ 15118 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15119 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15120 /* Remove the particle. */ 15121 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15122 else { 15123 /* 15124 * Assign the MG definition's {model group} to the 15125 * particle's {term}. 15126 */ 15127 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15128 15129 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15130 /* 15131 * SPEC cos-all-limited (1.2) 15132 * "1.2 the {term} property of a particle with 15133 * {max occurs}=1 which is part of a pair which constitutes 15134 * the {content type} of a complex type definition." 15135 */ 15136 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15137 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15138 /* TODO: error code */ 15139 XML_SCHEMAP_COS_ALL_LIMITED, 15140 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15141 "The particle's {max occurs} must be 1, since the " 15142 "reference resolves to an 'all' model group", 15143 NULL, NULL); 15144 } 15145 } 15146 } 15147 } 15148 } 15149 15150 15151 15152 /** 15153 * xmlSchemaCheckSTPropsCorrect: 15154 * @ctxt: the schema parser context 15155 * @type: the simple type definition 15156 * 15157 * Checks st-props-correct. 15158 * 15159 * Returns 0 if the properties are correct, 15160 * if not, a positive error code and -1 on internal 15161 * errors. 15162 */ 15163 static int 15164 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15165 xmlSchemaTypePtr type) 15166 { 15167 xmlSchemaTypePtr baseType = type->baseType; 15168 xmlChar *str = NULL; 15169 15170 /* STATE: error funcs converted. */ 15171 /* 15172 * Schema Component Constraint: Simple Type Definition Properties Correct 15173 * 15174 * NOTE: This is somehow redundant, since we actually built a simple type 15175 * to have all the needed information; this acts as an self test. 15176 */ 15177 /* Base type: If the datatype has been `derived` by `restriction` 15178 * then the Simple Type Definition component from which it is `derived`, 15179 * otherwise the Simple Type Definition for anySimpleType ($4.1.6). 15180 */ 15181 if (baseType == NULL) { 15182 /* 15183 * TODO: Think about: "modulo the impact of Missing 15184 * Sub-components ($5.3)." 15185 */ 15186 xmlSchemaPCustomErr(ctxt, 15187 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15188 WXS_BASIC_CAST type, NULL, 15189 "No base type existent", NULL); 15190 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15191 15192 } 15193 if (! WXS_IS_SIMPLE(baseType)) { 15194 xmlSchemaPCustomErr(ctxt, 15195 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15196 WXS_BASIC_CAST type, NULL, 15197 "The base type '%s' is not a simple type", 15198 xmlSchemaGetComponentQName(&str, baseType)); 15199 FREE_AND_NULL(str) 15200 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15201 } 15202 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15203 (WXS_IS_RESTRICTION(type) == 0) && 15204 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15205 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15206 xmlSchemaPCustomErr(ctxt, 15207 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15208 WXS_BASIC_CAST type, NULL, 15209 "A type, derived by list or union, must have " 15210 "the simple ur-type definition as base type, not '%s'", 15211 xmlSchemaGetComponentQName(&str, baseType)); 15212 FREE_AND_NULL(str) 15213 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15214 } 15215 /* 15216 * Variety: One of {atomic, list, union}. 15217 */ 15218 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15219 (! WXS_IS_LIST(type))) { 15220 xmlSchemaPCustomErr(ctxt, 15221 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15222 WXS_BASIC_CAST type, NULL, 15223 "The variety is absent", NULL); 15224 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15225 } 15226 /* TODO: Finish this. Hmm, is this finished? */ 15227 15228 /* 15229 * 3 The {final} of the {base type definition} must not contain restriction. 15230 */ 15231 if (xmlSchemaTypeFinalContains(baseType, 15232 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15233 xmlSchemaPCustomErr(ctxt, 15234 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15235 WXS_BASIC_CAST type, NULL, 15236 "The 'final' of its base type '%s' must not contain " 15237 "'restriction'", 15238 xmlSchemaGetComponentQName(&str, baseType)); 15239 FREE_AND_NULL(str) 15240 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15241 } 15242 15243 /* 15244 * 2 All simple type definitions must be derived ultimately from the `simple 15245 * ur-type definition` (so circular definitions are disallowed). That is, it 15246 * must be possible to reach a built-in primitive datatype or the `simple 15247 * ur-type definition` by repeatedly following the {base type definition}. 15248 * 15249 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15250 */ 15251 return (0); 15252 } 15253 15254 /** 15255 * xmlSchemaCheckCOSSTRestricts: 15256 * @ctxt: the schema parser context 15257 * @type: the simple type definition 15258 * 15259 * Schema Component Constraint: 15260 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15261 15262 * Checks if the given @type (simpleType) is derived validly by restriction. 15263 * STATUS: 15264 * 15265 * Returns -1 on internal errors, 0 if the type is validly derived, 15266 * a positive error code otherwise. 15267 */ 15268 static int 15269 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15270 xmlSchemaTypePtr type) 15271 { 15272 xmlChar *str = NULL; 15273 15274 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15275 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15276 "given type is not a user-derived simpleType"); 15277 return (-1); 15278 } 15279 15280 if (WXS_IS_ATOMIC(type)) { 15281 xmlSchemaTypePtr primitive; 15282 /* 15283 * 1.1 The {base type definition} must be an atomic simple 15284 * type definition or a built-in primitive datatype. 15285 */ 15286 if (! WXS_IS_ATOMIC(type->baseType)) { 15287 xmlSchemaPCustomErr(pctxt, 15288 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15289 WXS_BASIC_CAST type, NULL, 15290 "The base type '%s' is not an atomic simple type", 15291 xmlSchemaGetComponentQName(&str, type->baseType)); 15292 FREE_AND_NULL(str) 15293 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15294 } 15295 /* 1.2 The {final} of the {base type definition} must not contain 15296 * restriction. 15297 */ 15298 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15299 if (xmlSchemaTypeFinalContains(type->baseType, 15300 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15301 xmlSchemaPCustomErr(pctxt, 15302 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15303 WXS_BASIC_CAST type, NULL, 15304 "The final of its base type '%s' must not contain 'restriction'", 15305 xmlSchemaGetComponentQName(&str, type->baseType)); 15306 FREE_AND_NULL(str) 15307 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15308 } 15309 15310 /* 15311 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15312 * type definition}, as specified in the appropriate subsection of 3.2 15313 * Primitive datatypes. 15314 */ 15315 if (type->facets != NULL) { 15316 xmlSchemaFacetPtr facet; 15317 int ok = 1; 15318 15319 primitive = xmlSchemaGetPrimitiveType(type); 15320 if (primitive == NULL) { 15321 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15322 "failed to get primitive type"); 15323 return (-1); 15324 } 15325 facet = type->facets; 15326 do { 15327 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15328 ok = 0; 15329 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15330 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15331 type, primitive, facet); 15332 } 15333 facet = facet->next; 15334 } while (facet != NULL); 15335 if (ok == 0) 15336 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15337 } 15338 /* 15339 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15340 * of the {base type definition} (call this BF),then the DF's {value} 15341 * must be a valid restriction of BF's {value} as defined in 15342 * [XML Schemas: Datatypes]." 15343 * 15344 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15345 * xmlSchemaDeriveAndValidateFacets() 15346 */ 15347 } else if (WXS_IS_LIST(type)) { 15348 xmlSchemaTypePtr itemType = NULL; 15349 15350 itemType = type->subtypes; 15351 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15352 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15353 "failed to evaluate the item type"); 15354 return (-1); 15355 } 15356 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15357 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15358 /* 15359 * 2.1 The {item type definition} must have a {variety} of atomic or 15360 * union (in which case all the {member type definitions} 15361 * must be atomic). 15362 */ 15363 if ((! WXS_IS_ATOMIC(itemType)) && 15364 (! WXS_IS_UNION(itemType))) { 15365 xmlSchemaPCustomErr(pctxt, 15366 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15367 WXS_BASIC_CAST type, NULL, 15368 "The item type '%s' does not have a variety of atomic or union", 15369 xmlSchemaGetComponentQName(&str, itemType)); 15370 FREE_AND_NULL(str) 15371 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15372 } else if (WXS_IS_UNION(itemType)) { 15373 xmlSchemaTypeLinkPtr member; 15374 15375 member = itemType->memberTypes; 15376 while (member != NULL) { 15377 if (! WXS_IS_ATOMIC(member->type)) { 15378 xmlSchemaPCustomErr(pctxt, 15379 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15380 WXS_BASIC_CAST type, NULL, 15381 "The item type is a union type, but the " 15382 "member type '%s' of this item type is not atomic", 15383 xmlSchemaGetComponentQName(&str, member->type)); 15384 FREE_AND_NULL(str) 15385 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15386 } 15387 member = member->next; 15388 } 15389 } 15390 15391 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15392 xmlSchemaFacetPtr facet; 15393 /* 15394 * This is the case if we have: <simpleType><list .. 15395 */ 15396 /* 15397 * 2.3.1 15398 * 2.3.1.1 The {final} of the {item type definition} must not 15399 * contain list. 15400 */ 15401 if (xmlSchemaTypeFinalContains(itemType, 15402 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15403 xmlSchemaPCustomErr(pctxt, 15404 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15405 WXS_BASIC_CAST type, NULL, 15406 "The final of its item type '%s' must not contain 'list'", 15407 xmlSchemaGetComponentQName(&str, itemType)); 15408 FREE_AND_NULL(str) 15409 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15410 } 15411 /* 15412 * 2.3.1.2 The {facets} must only contain the whiteSpace 15413 * facet component. 15414 * OPTIMIZE TODO: the S4S already disallows any facet 15415 * to be specified. 15416 */ 15417 if (type->facets != NULL) { 15418 facet = type->facets; 15419 do { 15420 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15421 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15422 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15423 type, facet); 15424 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15425 } 15426 facet = facet->next; 15427 } while (facet != NULL); 15428 } 15429 /* 15430 * MAYBE TODO: (Hmm, not really) Datatypes states: 15431 * A `list` datatype can be `derived` from an `atomic` datatype 15432 * whose `lexical space` allows space (such as string or anyURI)or 15433 * a `union` datatype any of whose {member type definitions}'s 15434 * `lexical space` allows space. 15435 */ 15436 } else { 15437 /* 15438 * This is the case if we have: <simpleType><restriction ... 15439 * I.e. the variety of "list" is inherited. 15440 */ 15441 /* 15442 * 2.3.2 15443 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15444 */ 15445 if (! WXS_IS_LIST(type->baseType)) { 15446 xmlSchemaPCustomErr(pctxt, 15447 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15448 WXS_BASIC_CAST type, NULL, 15449 "The base type '%s' must be a list type", 15450 xmlSchemaGetComponentQName(&str, type->baseType)); 15451 FREE_AND_NULL(str) 15452 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15453 } 15454 /* 15455 * 2.3.2.2 The {final} of the {base type definition} must not 15456 * contain restriction. 15457 */ 15458 if (xmlSchemaTypeFinalContains(type->baseType, 15459 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15460 xmlSchemaPCustomErr(pctxt, 15461 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15462 WXS_BASIC_CAST type, NULL, 15463 "The 'final' of the base type '%s' must not contain 'restriction'", 15464 xmlSchemaGetComponentQName(&str, type->baseType)); 15465 FREE_AND_NULL(str) 15466 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15467 } 15468 /* 15469 * 2.3.2.3 The {item type definition} must be validly derived 15470 * from the {base type definition}'s {item type definition} given 15471 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6). 15472 */ 15473 { 15474 xmlSchemaTypePtr baseItemType; 15475 15476 baseItemType = type->baseType->subtypes; 15477 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15478 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15479 "failed to eval the item type of a base type"); 15480 return (-1); 15481 } 15482 if ((itemType != baseItemType) && 15483 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15484 baseItemType, 0) != 0)) { 15485 xmlChar *strBIT = NULL, *strBT = NULL; 15486 xmlSchemaPCustomErrExt(pctxt, 15487 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15488 WXS_BASIC_CAST type, NULL, 15489 "The item type '%s' is not validly derived from " 15490 "the item type '%s' of the base type '%s'", 15491 xmlSchemaGetComponentQName(&str, itemType), 15492 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15493 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15494 15495 FREE_AND_NULL(str) 15496 FREE_AND_NULL(strBIT) 15497 FREE_AND_NULL(strBT) 15498 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15499 } 15500 } 15501 15502 if (type->facets != NULL) { 15503 xmlSchemaFacetPtr facet; 15504 int ok = 1; 15505 /* 15506 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15507 * and enumeration facet components are allowed among the {facets}. 15508 */ 15509 facet = type->facets; 15510 do { 15511 switch (facet->type) { 15512 case XML_SCHEMA_FACET_LENGTH: 15513 case XML_SCHEMA_FACET_MINLENGTH: 15514 case XML_SCHEMA_FACET_MAXLENGTH: 15515 case XML_SCHEMA_FACET_WHITESPACE: 15516 /* 15517 * TODO: 2.5.1.2 List datatypes 15518 * The value of `whiteSpace` is fixed to the value collapse. 15519 */ 15520 case XML_SCHEMA_FACET_PATTERN: 15521 case XML_SCHEMA_FACET_ENUMERATION: 15522 break; 15523 default: { 15524 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15525 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15526 type, facet); 15527 /* 15528 * We could return, but it's nicer to report all 15529 * invalid facets. 15530 */ 15531 ok = 0; 15532 } 15533 } 15534 facet = facet->next; 15535 } while (facet != NULL); 15536 if (ok == 0) 15537 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15538 /* 15539 * SPEC (2.3.2.5) (same as 1.3.2) 15540 * 15541 * NOTE (2.3.2.5) This is currently done in 15542 * xmlSchemaDeriveAndValidateFacets() 15543 */ 15544 } 15545 } 15546 } else if (WXS_IS_UNION(type)) { 15547 /* 15548 * 3.1 The {member type definitions} must all have {variety} of 15549 * atomic or list. 15550 */ 15551 xmlSchemaTypeLinkPtr member; 15552 15553 member = type->memberTypes; 15554 while (member != NULL) { 15555 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15556 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15557 15558 if ((! WXS_IS_ATOMIC(member->type)) && 15559 (! WXS_IS_LIST(member->type))) { 15560 xmlSchemaPCustomErr(pctxt, 15561 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15562 WXS_BASIC_CAST type, NULL, 15563 "The member type '%s' is neither an atomic, nor a list type", 15564 xmlSchemaGetComponentQName(&str, member->type)); 15565 FREE_AND_NULL(str) 15566 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15567 } 15568 member = member->next; 15569 } 15570 /* 15571 * 3.3.1 If the {base type definition} is the `simple ur-type 15572 * definition` 15573 */ 15574 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15575 /* 15576 * 3.3.1.1 All of the {member type definitions} must have a 15577 * {final} which does not contain union. 15578 */ 15579 member = type->memberTypes; 15580 while (member != NULL) { 15581 if (xmlSchemaTypeFinalContains(member->type, 15582 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15583 xmlSchemaPCustomErr(pctxt, 15584 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15585 WXS_BASIC_CAST type, NULL, 15586 "The 'final' of member type '%s' contains 'union'", 15587 xmlSchemaGetComponentQName(&str, member->type)); 15588 FREE_AND_NULL(str) 15589 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15590 } 15591 member = member->next; 15592 } 15593 /* 15594 * 3.3.1.2 The {facets} must be empty. 15595 */ 15596 if (type->facetSet != NULL) { 15597 xmlSchemaPCustomErr(pctxt, 15598 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15599 WXS_BASIC_CAST type, NULL, 15600 "No facets allowed", NULL); 15601 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15602 } 15603 } else { 15604 /* 15605 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15606 * I.e. the variety of "list" is inherited. 15607 */ 15608 if (! WXS_IS_UNION(type->baseType)) { 15609 xmlSchemaPCustomErr(pctxt, 15610 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15611 WXS_BASIC_CAST type, NULL, 15612 "The base type '%s' is not a union type", 15613 xmlSchemaGetComponentQName(&str, type->baseType)); 15614 FREE_AND_NULL(str) 15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15616 } 15617 /* 15618 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15619 */ 15620 if (xmlSchemaTypeFinalContains(type->baseType, 15621 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15622 xmlSchemaPCustomErr(pctxt, 15623 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15624 WXS_BASIC_CAST type, NULL, 15625 "The 'final' of its base type '%s' must not contain 'restriction'", 15626 xmlSchemaGetComponentQName(&str, type->baseType)); 15627 FREE_AND_NULL(str) 15628 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15629 } 15630 /* 15631 * 3.3.2.3 The {member type definitions}, in order, must be validly 15632 * derived from the corresponding type definitions in the {base 15633 * type definition}'s {member type definitions} given the empty set, 15634 * as defined in Type Derivation OK (Simple) ($3.14.6). 15635 */ 15636 { 15637 xmlSchemaTypeLinkPtr baseMember; 15638 15639 /* 15640 * OPTIMIZE: if the type is restricting, it has no local defined 15641 * member types and inherits the member types of the base type; 15642 * thus a check for equality can be skipped. 15643 */ 15644 /* 15645 * Even worse: I cannot see a scenario where a restricting 15646 * union simple type can have other member types as the member 15647 * types of it's base type. This check seems not necessary with 15648 * respect to the derivation process in libxml2. 15649 * But necessary if constructing types with an API. 15650 */ 15651 if (type->memberTypes != NULL) { 15652 member = type->memberTypes; 15653 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15654 if ((member == NULL) && (baseMember != NULL)) { 15655 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15656 "different number of member types in base"); 15657 } 15658 while (member != NULL) { 15659 if (baseMember == NULL) { 15660 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15661 "different number of member types in base"); 15662 } else if ((member->type != baseMember->type) && 15663 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15664 member->type, baseMember->type, 0) != 0)) { 15665 xmlChar *strBMT = NULL, *strBT = NULL; 15666 15667 xmlSchemaPCustomErrExt(pctxt, 15668 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15669 WXS_BASIC_CAST type, NULL, 15670 "The member type %s is not validly " 15671 "derived from its corresponding member " 15672 "type %s of the base type %s", 15673 xmlSchemaGetComponentQName(&str, member->type), 15674 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15675 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15676 FREE_AND_NULL(str) 15677 FREE_AND_NULL(strBMT) 15678 FREE_AND_NULL(strBT) 15679 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15680 } 15681 member = member->next; 15682 if (baseMember != NULL) 15683 baseMember = baseMember->next; 15684 } 15685 } 15686 } 15687 /* 15688 * 3.3.2.4 Only pattern and enumeration facet components are 15689 * allowed among the {facets}. 15690 */ 15691 if (type->facets != NULL) { 15692 xmlSchemaFacetPtr facet; 15693 int ok = 1; 15694 15695 facet = type->facets; 15696 do { 15697 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15698 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15699 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15700 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15701 type, facet); 15702 ok = 0; 15703 } 15704 facet = facet->next; 15705 } while (facet != NULL); 15706 if (ok == 0) 15707 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15708 15709 } 15710 /* 15711 * SPEC (3.3.2.5) (same as 1.3.2) 15712 * 15713 * NOTE (3.3.2.5) This is currently done in 15714 * xmlSchemaDeriveAndValidateFacets() 15715 */ 15716 } 15717 } 15718 15719 return (0); 15720 } 15721 15722 /** 15723 * xmlSchemaCheckSRCSimpleType: 15724 * @ctxt: the schema parser context 15725 * @type: the simple type definition 15726 * 15727 * Checks crc-simple-type constraints. 15728 * 15729 * Returns 0 if the constraints are satisfied, 15730 * if not a positive error code and -1 on internal 15731 * errors. 15732 */ 15733 #if 0 15734 static int 15735 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15736 xmlSchemaTypePtr type) 15737 { 15738 /* 15739 * src-simple-type.1 The corresponding simple type definition, if any, 15740 * must satisfy the conditions set out in Constraints on Simple Type 15741 * Definition Schema Components ($3.14.6). 15742 */ 15743 if (WXS_IS_RESTRICTION(type)) { 15744 /* 15745 * src-simple-type.2 "If the <restriction> alternative is chosen, 15746 * either it must have a base [attribute] or a <simpleType> among its 15747 * [children], but not both." 15748 * NOTE: This is checked in the parse function of <restriction>. 15749 */ 15750 /* 15751 * 15752 */ 15753 } else if (WXS_IS_LIST(type)) { 15754 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15755 * an itemType [attribute] or a <simpleType> among its [children], 15756 * but not both." 15757 * 15758 * NOTE: This is checked in the parse function of <list>. 15759 */ 15760 } else if (WXS_IS_UNION(type)) { 15761 /* 15762 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15763 */ 15764 } 15765 return (0); 15766 } 15767 #endif 15768 15769 static int 15770 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15771 { 15772 if (ctxt->vctxt == NULL) { 15773 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15774 if (ctxt->vctxt == NULL) { 15775 xmlSchemaPErr(ctxt, NULL, 15776 XML_SCHEMAP_INTERNAL, 15777 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15778 "failed to create a temp. validation context.\n", 15779 NULL, NULL); 15780 return (-1); 15781 } 15782 /* TODO: Pass user data. */ 15783 xmlSchemaSetValidErrors(ctxt->vctxt, 15784 ctxt->error, ctxt->warning, ctxt->errCtxt); 15785 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15786 ctxt->serror, ctxt->errCtxt); 15787 } 15788 return (0); 15789 } 15790 15791 static int 15792 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15793 xmlNodePtr node, 15794 xmlSchemaTypePtr type, 15795 const xmlChar *value, 15796 xmlSchemaValPtr *retVal, 15797 int fireErrors, 15798 int normalize, 15799 int isNormalized); 15800 15801 /** 15802 * xmlSchemaParseCheckCOSValidDefault: 15803 * @pctxt: the schema parser context 15804 * @type: the simple type definition 15805 * @value: the default value 15806 * @node: an optional node (the holder of the value) 15807 * 15808 * Schema Component Constraint: Element Default Valid (Immediate) 15809 * (cos-valid-default) 15810 * This will be used by the parser only. For the validator there's 15811 * an other version. 15812 * 15813 * Returns 0 if the constraints are satisfied, 15814 * if not, a positive error code and -1 on internal 15815 * errors. 15816 */ 15817 static int 15818 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15819 xmlNodePtr node, 15820 xmlSchemaTypePtr type, 15821 const xmlChar *value, 15822 xmlSchemaValPtr *val) 15823 { 15824 int ret = 0; 15825 15826 /* 15827 * cos-valid-default: 15828 * Schema Component Constraint: Element Default Valid (Immediate) 15829 * For a string to be a valid default with respect to a type 15830 * definition the appropriate case among the following must be true: 15831 */ 15832 if WXS_IS_COMPLEX(type) { 15833 /* 15834 * Complex type. 15835 * 15836 * SPEC (2.1) "its {content type} must be a simple type definition 15837 * or mixed." 15838 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15839 * type}'s particle must be `emptiable` as defined by 15840 * Particle Emptiable ($3.9.6)." 15841 */ 15842 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15843 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15844 /* NOTE that this covers (2.2.2) as well. */ 15845 xmlSchemaPCustomErr(pctxt, 15846 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15847 WXS_BASIC_CAST type, type->node, 15848 "For a string to be a valid default, the type definition " 15849 "must be a simple type or a complex type with mixed content " 15850 "and a particle emptiable", NULL); 15851 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15852 } 15853 } 15854 /* 15855 * 1 If the type definition is a simple type definition, then the string 15856 * must be `valid` with respect to that definition as defined by String 15857 * Valid ($3.14.4). 15858 * 15859 * AND 15860 * 15861 * 2.2.1 If the {content type} is a simple type definition, then the 15862 * string must be `valid` with respect to that simple type definition 15863 * as defined by String Valid ($3.14.4). 15864 */ 15865 if (WXS_IS_SIMPLE(type)) 15866 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15867 type, value, val, 1, 1, 0); 15868 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15869 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15870 type->contentTypeDef, value, val, 1, 1, 0); 15871 else 15872 return (ret); 15873 15874 if (ret < 0) { 15875 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15876 "calling xmlSchemaVCheckCVCSimpleType()"); 15877 } 15878 15879 return (ret); 15880 } 15881 15882 /** 15883 * xmlSchemaCheckCTPropsCorrect: 15884 * @ctxt: the schema parser context 15885 * @type: the complex type definition 15886 * 15887 *.(4.6) Constraints on Complex Type Definition Schema Components 15888 * Schema Component Constraint: 15889 * Complex Type Definition Properties Correct (ct-props-correct) 15890 * STATUS: (seems) complete 15891 * 15892 * Returns 0 if the constraints are satisfied, a positive 15893 * error code if not and -1 if an internal error occured. 15894 */ 15895 static int 15896 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15897 xmlSchemaTypePtr type) 15898 { 15899 /* 15900 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15901 * 15902 * SPEC (1) "The values of the properties of a complex type definition must 15903 * be as described in the property tableau in The Complex Type Definition 15904 * Schema Component ($3.4.1), modulo the impact of Missing 15905 * Sub-components ($5.3)." 15906 */ 15907 if ((type->baseType != NULL) && 15908 (WXS_IS_SIMPLE(type->baseType)) && 15909 (WXS_IS_EXTENSION(type) == 0)) { 15910 /* 15911 * SPEC (2) "If the {base type definition} is a simple type definition, 15912 * the {derivation method} must be extension." 15913 */ 15914 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15915 XML_SCHEMAP_SRC_CT_1, 15916 NULL, WXS_BASIC_CAST type, 15917 "If the base type is a simple type, the derivation method must be " 15918 "'extension'", NULL, NULL); 15919 return (XML_SCHEMAP_SRC_CT_1); 15920 } 15921 /* 15922 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type 15923 * definition`. That is, it must be possible to reach the `ur-type 15924 * definition` by repeatedly following the {base type definition}." 15925 * 15926 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15927 */ 15928 /* 15929 * NOTE that (4) and (5) need the following: 15930 * - attribute uses need to be already inherited (apply attr. prohibitions) 15931 * - attribute group references need to be expanded already 15932 * - simple types need to be typefixed already 15933 */ 15934 if (type->attrUses && 15935 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15936 { 15937 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15938 xmlSchemaAttributeUsePtr use, tmp; 15939 int i, j, hasId = 0; 15940 15941 for (i = uses->nbItems -1; i >= 0; i--) { 15942 use = uses->items[i]; 15943 15944 /* 15945 * SPEC ct-props-correct 15946 * (4) "Two distinct attribute declarations in the 15947 * {attribute uses} must not have identical {name}s and 15948 * {target namespace}s." 15949 */ 15950 if (i > 0) { 15951 for (j = i -1; j >= 0; j--) { 15952 tmp = uses->items[j]; 15953 if ((WXS_ATTRUSE_DECL_NAME(use) == 15954 WXS_ATTRUSE_DECL_NAME(tmp)) && 15955 (WXS_ATTRUSE_DECL_TNS(use) == 15956 WXS_ATTRUSE_DECL_TNS(tmp))) 15957 { 15958 xmlChar *str = NULL; 15959 15960 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15961 XML_SCHEMAP_AG_PROPS_CORRECT, 15962 NULL, WXS_BASIC_CAST type, 15963 "Duplicate %s", 15964 xmlSchemaGetComponentDesignation(&str, use), 15965 NULL); 15966 FREE_AND_NULL(str); 15967 /* 15968 * Remove the duplicate. 15969 */ 15970 if (xmlSchemaItemListRemove(uses, i) == -1) 15971 goto exit_failure; 15972 goto next_use; 15973 } 15974 } 15975 } 15976 /* 15977 * SPEC ct-props-correct 15978 * (5) "Two distinct attribute declarations in the 15979 * {attribute uses} must not have {type definition}s which 15980 * are or are derived from ID." 15981 */ 15982 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 15983 if (xmlSchemaIsDerivedFromBuiltInType( 15984 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 15985 { 15986 if (hasId) { 15987 xmlChar *str = NULL; 15988 15989 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15990 XML_SCHEMAP_AG_PROPS_CORRECT, 15991 NULL, WXS_BASIC_CAST type, 15992 "There must not exist more than one attribute " 15993 "declaration of type 'xs:ID' " 15994 "(or derived from 'xs:ID'). The %s violates this " 15995 "constraint", 15996 xmlSchemaGetComponentDesignation(&str, use), 15997 NULL); 15998 FREE_AND_NULL(str); 15999 if (xmlSchemaItemListRemove(uses, i) == -1) 16000 goto exit_failure; 16001 } 16002 16003 hasId = 1; 16004 } 16005 } 16006 next_use: {} 16007 } 16008 } 16009 return (0); 16010 exit_failure: 16011 return(-1); 16012 } 16013 16014 static int 16015 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 16016 xmlSchemaTypePtr typeB) 16017 { 16018 /* 16019 * TODO: This should implement component-identity 16020 * in the future. 16021 */ 16022 if ((typeA == NULL) || (typeB == NULL)) 16023 return (0); 16024 return (typeA == typeB); 16025 } 16026 16027 /** 16028 * xmlSchemaCheckCOSCTDerivedOK: 16029 * @ctxt: the schema parser context 16030 * @type: the to-be derived complex type definition 16031 * @baseType: the base complex type definition 16032 * @set: the given set 16033 * 16034 * Schema Component Constraint: 16035 * Type Derivation OK (Complex) (cos-ct-derived-ok) 16036 * 16037 * STATUS: completed 16038 * 16039 * Returns 0 if the constraints are satisfied, or 1 16040 * if not. 16041 */ 16042 static int 16043 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16044 xmlSchemaTypePtr type, 16045 xmlSchemaTypePtr baseType, 16046 int set) 16047 { 16048 int equal = xmlSchemaAreEqualTypes(type, baseType); 16049 /* TODO: Error codes. */ 16050 /* 16051 * SPEC "For a complex type definition (call it D, for derived) 16052 * to be validly derived from a type definition (call this 16053 * B, for base) given a subset of {extension, restriction} 16054 * all of the following must be true:" 16055 */ 16056 if (! equal) { 16057 /* 16058 * SPEC (1) "If B and D are not the same type definition, then the 16059 * {derivation method} of D must not be in the subset." 16060 */ 16061 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16062 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16063 return (1); 16064 } else { 16065 /* 16066 * SPEC (2.1) "B and D must be the same type definition." 16067 */ 16068 return (0); 16069 } 16070 /* 16071 * SPEC (2.2) "B must be D's {base type definition}." 16072 */ 16073 if (type->baseType == baseType) 16074 return (0); 16075 /* 16076 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type 16077 * definition`." 16078 */ 16079 if (WXS_IS_ANYTYPE(type->baseType)) 16080 return (1); 16081 16082 if (WXS_IS_COMPLEX(type->baseType)) { 16083 /* 16084 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16085 * must be validly derived from B given the subset as defined by this 16086 * constraint." 16087 */ 16088 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16089 baseType, set)); 16090 } else { 16091 /* 16092 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16093 * must be validly derived from B given the subset as defined in Type 16094 * Derivation OK (Simple) ($3.14.6). 16095 */ 16096 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16097 baseType, set)); 16098 } 16099 } 16100 16101 /** 16102 * xmlSchemaCheckCOSDerivedOK: 16103 * @type: the derived simple type definition 16104 * @baseType: the base type definition 16105 * 16106 * Calls: 16107 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16108 * 16109 * Checks wheter @type can be validly derived from @baseType. 16110 * 16111 * Returns 0 on success, an positive error code otherwise. 16112 */ 16113 static int 16114 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16115 xmlSchemaTypePtr type, 16116 xmlSchemaTypePtr baseType, 16117 int set) 16118 { 16119 if (WXS_IS_SIMPLE(type)) 16120 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16121 else 16122 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16123 } 16124 16125 /** 16126 * xmlSchemaCheckCOSCTExtends: 16127 * @ctxt: the schema parser context 16128 * @type: the complex type definition 16129 * 16130 * (3.4.6) Constraints on Complex Type Definition Schema Components 16131 * Schema Component Constraint: 16132 * Derivation Valid (Extension) (cos-ct-extends) 16133 * 16134 * STATUS: 16135 * missing: 16136 * (1.5) 16137 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16138 * 16139 * Returns 0 if the constraints are satisfied, a positive 16140 * error code if not and -1 if an internal error occured. 16141 */ 16142 static int 16143 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16144 xmlSchemaTypePtr type) 16145 { 16146 xmlSchemaTypePtr base = type->baseType; 16147 /* 16148 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16149 * temporarily only. 16150 */ 16151 /* 16152 * SPEC (1) "If the {base type definition} is a complex type definition, 16153 * then all of the following must be true:" 16154 */ 16155 if (WXS_IS_COMPLEX(base)) { 16156 /* 16157 * SPEC (1.1) "The {final} of the {base type definition} must not 16158 * contain extension." 16159 */ 16160 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16161 xmlSchemaPCustomErr(ctxt, 16162 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16163 WXS_BASIC_CAST type, NULL, 16164 "The 'final' of the base type definition " 16165 "contains 'extension'", NULL); 16166 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16167 } 16168 16169 /* 16170 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16171 * since they are automatically satisfied through the 16172 * inheriting mechanism. 16173 * Note that even if redefining components, the inheriting mechanism 16174 * is used. 16175 */ 16176 #if 0 16177 /* 16178 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16179 * uses} 16180 * of the complex type definition itself, that is, for every attribute 16181 * use in the {attribute uses} of the {base type definition}, there 16182 * must be an attribute use in the {attribute uses} of the complex 16183 * type definition itself whose {attribute declaration} has the same 16184 * {name}, {target namespace} and {type definition} as its attribute 16185 * declaration" 16186 */ 16187 if (base->attrUses != NULL) { 16188 int i, j, found; 16189 xmlSchemaAttributeUsePtr use, buse; 16190 16191 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16192 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16193 found = 0; 16194 if (type->attrUses != NULL) { 16195 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16196 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16197 { 16198 if ((WXS_ATTRUSE_DECL_NAME(use) == 16199 WXS_ATTRUSE_DECL_NAME(buse)) && 16200 (WXS_ATTRUSE_DECL_TNS(use) == 16201 WXS_ATTRUSE_DECL_TNS(buse)) && 16202 (WXS_ATTRUSE_TYPEDEF(use) == 16203 WXS_ATTRUSE_TYPEDEF(buse)) 16204 { 16205 found = 1; 16206 break; 16207 } 16208 } 16209 } 16210 if (! found) { 16211 xmlChar *str = NULL; 16212 16213 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16214 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16215 NULL, WXS_BASIC_CAST type, 16216 /* 16217 * TODO: The report does not indicate that also the 16218 * type needs to be the same. 16219 */ 16220 "This type is missing a matching correspondent " 16221 "for its {base type}'s %s in its {attribute uses}", 16222 xmlSchemaGetComponentDesignation(&str, 16223 buse->children), 16224 NULL); 16225 FREE_AND_NULL(str) 16226 } 16227 } 16228 } 16229 /* 16230 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16231 * definition must also have one, and the base type definition's 16232 * {attribute wildcard}'s {namespace constraint} must be a subset 16233 * of the complex type definition's {attribute wildcard}'s {namespace 16234 * constraint}, as defined by Wildcard Subset ($3.10.6)." 16235 */ 16236 16237 /* 16238 * MAYBE TODO: Enable if ever needed. But this will be needed only 16239 * if created the type via a schema construction API. 16240 */ 16241 if (base->attributeWildcard != NULL) { 16242 if (type->attributeWilcard == NULL) { 16243 xmlChar *str = NULL; 16244 16245 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16246 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16247 NULL, type, 16248 "The base %s has an attribute wildcard, " 16249 "but this type is missing an attribute wildcard", 16250 xmlSchemaGetComponentDesignation(&str, base)); 16251 FREE_AND_NULL(str) 16252 16253 } else if (xmlSchemaCheckCOSNSSubset( 16254 base->attributeWildcard, type->attributeWildcard)) 16255 { 16256 xmlChar *str = NULL; 16257 16258 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16259 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16260 NULL, type, 16261 "The attribute wildcard is not a valid " 16262 "superset of the one in the base %s", 16263 xmlSchemaGetComponentDesignation(&str, base)); 16264 FREE_AND_NULL(str) 16265 } 16266 } 16267 #endif 16268 /* 16269 * SPEC (1.4) "One of the following must be true:" 16270 */ 16271 if ((type->contentTypeDef != NULL) && 16272 (type->contentTypeDef == base->contentTypeDef)) { 16273 /* 16274 * SPEC (1.4.1) "The {content type} of the {base type definition} 16275 * and the {content type} of the complex type definition itself 16276 * must be the same simple type definition" 16277 * PASS 16278 */ 16279 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16280 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16281 /* 16282 * SPEC (1.4.2) "The {content type} of both the {base type 16283 * definition} and the complex type definition itself must 16284 * be empty." 16285 * PASS 16286 */ 16287 } else { 16288 /* 16289 * SPEC (1.4.3) "All of the following must be true:" 16290 */ 16291 if (type->subtypes == NULL) { 16292 /* 16293 * SPEC 1.4.3.1 The {content type} of the complex type 16294 * definition itself must specify a particle. 16295 */ 16296 xmlSchemaPCustomErr(ctxt, 16297 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16298 WXS_BASIC_CAST type, NULL, 16299 "The content type must specify a particle", NULL); 16300 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16301 } 16302 /* 16303 * SPEC (1.4.3.2) "One of the following must be true:" 16304 */ 16305 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16306 /* 16307 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16308 * definition} must be empty. 16309 * PASS 16310 */ 16311 } else { 16312 /* 16313 * SPEC (1.4.3.2.2) "All of the following must be true:" 16314 */ 16315 if ((type->contentType != base->contentType) || 16316 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16317 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16318 /* 16319 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16320 * or both must be element-only." 16321 */ 16322 xmlSchemaPCustomErr(ctxt, 16323 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16324 WXS_BASIC_CAST type, NULL, 16325 "The content type of both, the type and its base " 16326 "type, must either 'mixed' or 'element-only'", NULL); 16327 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16328 } 16329 /* 16330 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16331 * complex type definition must be a `valid extension` 16332 * of the {base type definition}'s particle, as defined 16333 * in Particle Valid (Extension) ($3.9.6)." 16334 * 16335 * NOTE that we won't check "Particle Valid (Extension)", 16336 * since it is ensured by the derivation process in 16337 * xmlSchemaTypeFixup(). We need to implement this when heading 16338 * for a construction API 16339 * TODO: !! This is needed to be checked if redefining a type !! 16340 */ 16341 } 16342 /* 16343 * URGENT TODO (1.5) 16344 */ 16345 } 16346 } else { 16347 /* 16348 * SPEC (2) "If the {base type definition} is a simple type definition, 16349 * then all of the following must be true:" 16350 */ 16351 if (type->contentTypeDef != base) { 16352 /* 16353 * SPEC (2.1) "The {content type} must be the same simple type 16354 * definition." 16355 */ 16356 xmlSchemaPCustomErr(ctxt, 16357 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16358 WXS_BASIC_CAST type, NULL, 16359 "The content type must be the simple base type", NULL); 16360 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16361 } 16362 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16363 /* 16364 * SPEC (2.2) "The {final} of the {base type definition} must not 16365 * contain extension" 16366 * NOTE that this is the same as (1.1). 16367 */ 16368 xmlSchemaPCustomErr(ctxt, 16369 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16370 WXS_BASIC_CAST type, NULL, 16371 "The 'final' of the base type definition " 16372 "contains 'extension'", NULL); 16373 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16374 } 16375 } 16376 return (0); 16377 } 16378 16379 /** 16380 * xmlSchemaCheckDerivationOKRestriction: 16381 * @ctxt: the schema parser context 16382 * @type: the complex type definition 16383 * 16384 * (3.4.6) Constraints on Complex Type Definition Schema Components 16385 * Schema Component Constraint: 16386 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16387 * 16388 * STATUS: 16389 * missing: 16390 * (5.4.2) ??? 16391 * 16392 * ATTENTION: 16393 * In XML Schema 1.1 this will be: 16394 * Validation Rule: Checking complex type subsumption 16395 * 16396 * Returns 0 if the constraints are satisfied, a positive 16397 * error code if not and -1 if an internal error occured. 16398 */ 16399 static int 16400 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16401 xmlSchemaTypePtr type) 16402 { 16403 xmlSchemaTypePtr base; 16404 16405 /* 16406 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16407 * temporarily only. 16408 */ 16409 base = type->baseType; 16410 if (! WXS_IS_COMPLEX(base)) { 16411 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16412 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16413 type->node, WXS_BASIC_CAST type, 16414 "The base type must be a complex type", NULL, NULL); 16415 return(ctxt->err); 16416 } 16417 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16418 /* 16419 * SPEC (1) "The {base type definition} must be a complex type 16420 * definition whose {final} does not contain restriction." 16421 */ 16422 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16423 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16424 type->node, WXS_BASIC_CAST type, 16425 "The 'final' of the base type definition " 16426 "contains 'restriction'", NULL, NULL); 16427 return (ctxt->err); 16428 } 16429 /* 16430 * SPEC (2), (3) and (4) 16431 * Those are handled in a separate function, since the 16432 * same constraints are needed for redefinition of 16433 * attribute groups as well. 16434 */ 16435 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16436 XML_SCHEMA_ACTION_DERIVE, 16437 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16438 type->attrUses, base->attrUses, 16439 type->attributeWildcard, 16440 base->attributeWildcard) == -1) 16441 { 16442 return(-1); 16443 } 16444 /* 16445 * SPEC (5) "One of the following must be true:" 16446 */ 16447 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16448 /* 16449 * SPEC (5.1) "The {base type definition} must be the 16450 * `ur-type definition`." 16451 * PASS 16452 */ 16453 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16454 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16455 /* 16456 * SPEC (5.2.1) "The {content type} of the complex type definition 16457 * must be a simple type definition" 16458 * 16459 * SPEC (5.2.2) "One of the following must be true:" 16460 */ 16461 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16462 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16463 { 16464 int err; 16465 /* 16466 * SPEC (5.2.2.1) "The {content type} of the {base type 16467 * definition} must be a simple type definition from which 16468 * the {content type} is validly derived given the empty 16469 * set as defined in Type Derivation OK (Simple) ($3.14.6)." 16470 * 16471 * ATTENTION TODO: This seems not needed if the type implicitely 16472 * derived from the base type. 16473 * 16474 */ 16475 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16476 type->contentTypeDef, base->contentTypeDef, 0); 16477 if (err != 0) { 16478 xmlChar *strA = NULL, *strB = NULL; 16479 16480 if (err == -1) 16481 return(-1); 16482 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16483 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16484 NULL, WXS_BASIC_CAST type, 16485 "The {content type} %s is not validly derived from the " 16486 "base type's {content type} %s", 16487 xmlSchemaGetComponentDesignation(&strA, 16488 type->contentTypeDef), 16489 xmlSchemaGetComponentDesignation(&strB, 16490 base->contentTypeDef)); 16491 FREE_AND_NULL(strA); 16492 FREE_AND_NULL(strB); 16493 return(ctxt->err); 16494 } 16495 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16496 (xmlSchemaIsParticleEmptiable( 16497 (xmlSchemaParticlePtr) base->subtypes))) { 16498 /* 16499 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16500 * and have a particle which is `emptiable` as defined in 16501 * Particle Emptiable ($3.9.6)." 16502 * PASS 16503 */ 16504 } else { 16505 xmlSchemaPCustomErr(ctxt, 16506 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16507 WXS_BASIC_CAST type, NULL, 16508 "The content type of the base type must be either " 16509 "a simple type or 'mixed' and an emptiable particle", NULL); 16510 return (ctxt->err); 16511 } 16512 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16513 /* 16514 * SPEC (5.3.1) "The {content type} of the complex type itself must 16515 * be empty" 16516 */ 16517 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16518 /* 16519 * SPEC (5.3.2.1) "The {content type} of the {base type 16520 * definition} must also be empty." 16521 * PASS 16522 */ 16523 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16524 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16525 xmlSchemaIsParticleEmptiable( 16526 (xmlSchemaParticlePtr) base->subtypes)) { 16527 /* 16528 * SPEC (5.3.2.2) "The {content type} of the {base type 16529 * definition} must be elementOnly or mixed and have a particle 16530 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)." 16531 * PASS 16532 */ 16533 } else { 16534 xmlSchemaPCustomErr(ctxt, 16535 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16536 WXS_BASIC_CAST type, NULL, 16537 "The content type of the base type must be either " 16538 "empty or 'mixed' (or 'elements-only') and an emptiable " 16539 "particle", NULL); 16540 return (ctxt->err); 16541 } 16542 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16543 WXS_HAS_MIXED_CONTENT(type)) { 16544 /* 16545 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16546 * itself must be element-only" 16547 */ 16548 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16549 /* 16550 * SPEC (5.4.1.2) "The {content type} of the complex type 16551 * definition itself and of the {base type definition} must be 16552 * mixed" 16553 */ 16554 xmlSchemaPCustomErr(ctxt, 16555 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16556 WXS_BASIC_CAST type, NULL, 16557 "If the content type is 'mixed', then the content type of the " 16558 "base type must also be 'mixed'", NULL); 16559 return (ctxt->err); 16560 } 16561 /* 16562 * SPEC (5.4.2) "The particle of the complex type definition itself 16563 * must be a `valid restriction` of the particle of the {content 16564 * type} of the {base type definition} as defined in Particle Valid 16565 * (Restriction) ($3.9.6). 16566 * 16567 * URGENT TODO: (5.4.2) 16568 */ 16569 } else { 16570 xmlSchemaPCustomErr(ctxt, 16571 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16572 WXS_BASIC_CAST type, NULL, 16573 "The type is not a valid restriction of its base type", NULL); 16574 return (ctxt->err); 16575 } 16576 return (0); 16577 } 16578 16579 /** 16580 * xmlSchemaCheckCTComponent: 16581 * @ctxt: the schema parser context 16582 * @type: the complex type definition 16583 * 16584 * (3.4.6) Constraints on Complex Type Definition Schema Components 16585 * 16586 * Returns 0 if the constraints are satisfied, a positive 16587 * error code if not and -1 if an internal error occured. 16588 */ 16589 static int 16590 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16591 xmlSchemaTypePtr type) 16592 { 16593 int ret; 16594 /* 16595 * Complex Type Definition Properties Correct 16596 */ 16597 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16598 if (ret != 0) 16599 return (ret); 16600 if (WXS_IS_EXTENSION(type)) 16601 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16602 else 16603 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16604 return (ret); 16605 } 16606 16607 /** 16608 * xmlSchemaCheckSRCCT: 16609 * @ctxt: the schema parser context 16610 * @type: the complex type definition 16611 * 16612 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16613 * Schema Representation Constraint: 16614 * Complex Type Definition Representation OK (src-ct) 16615 * 16616 * Returns 0 if the constraints are satisfied, a positive 16617 * error code if not and -1 if an internal error occured. 16618 */ 16619 static int 16620 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16621 xmlSchemaTypePtr type) 16622 { 16623 xmlSchemaTypePtr base; 16624 int ret = 0; 16625 16626 /* 16627 * TODO: Adjust the error codes here, as I used 16628 * XML_SCHEMAP_SRC_CT_1 only yet. 16629 */ 16630 base = type->baseType; 16631 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16632 /* 16633 * 1 If the <complexContent> alternative is chosen, the type definition 16634 * `resolved` to by the `actual value` of the base [attribute] 16635 * must be a complex type definition; 16636 */ 16637 if (! WXS_IS_COMPLEX(base)) { 16638 xmlChar *str = NULL; 16639 xmlSchemaPCustomErr(ctxt, 16640 XML_SCHEMAP_SRC_CT_1, 16641 WXS_BASIC_CAST type, type->node, 16642 "If using <complexContent>, the base type is expected to be " 16643 "a complex type. The base type '%s' is a simple type", 16644 xmlSchemaFormatQName(&str, base->targetNamespace, 16645 base->name)); 16646 FREE_AND_NULL(str) 16647 return (XML_SCHEMAP_SRC_CT_1); 16648 } 16649 } else { 16650 /* 16651 * SPEC 16652 * 2 If the <simpleContent> alternative is chosen, all of the 16653 * following must be true: 16654 * 2.1 The type definition `resolved` to by the `actual value` of the 16655 * base [attribute] must be one of the following: 16656 */ 16657 if (WXS_IS_SIMPLE(base)) { 16658 if (WXS_IS_EXTENSION(type) == 0) { 16659 xmlChar *str = NULL; 16660 /* 16661 * 2.1.3 only if the <extension> alternative is also 16662 * chosen, a simple type definition. 16663 */ 16664 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16665 xmlSchemaPCustomErr(ctxt, 16666 XML_SCHEMAP_SRC_CT_1, 16667 WXS_BASIC_CAST type, NULL, 16668 "If using <simpleContent> and <restriction>, the base " 16669 "type must be a complex type. The base type '%s' is " 16670 "a simple type", 16671 xmlSchemaFormatQName(&str, base->targetNamespace, 16672 base->name)); 16673 FREE_AND_NULL(str) 16674 return (XML_SCHEMAP_SRC_CT_1); 16675 } 16676 } else { 16677 /* Base type is a complex type. */ 16678 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16679 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16680 /* 16681 * 2.1.1 a complex type definition whose {content type} is a 16682 * simple type definition; 16683 * PASS 16684 */ 16685 if (base->contentTypeDef == NULL) { 16686 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16687 WXS_BASIC_CAST type, NULL, 16688 "Internal error: xmlSchemaCheckSRCCT, " 16689 "'%s', base type has no content type", 16690 type->name); 16691 return (-1); 16692 } 16693 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16694 (WXS_IS_RESTRICTION(type))) { 16695 16696 /* 16697 * 2.1.2 only if the <restriction> alternative is also 16698 * chosen, a complex type definition whose {content type} 16699 * is mixed and a particle emptiable. 16700 */ 16701 if (! xmlSchemaIsParticleEmptiable( 16702 (xmlSchemaParticlePtr) base->subtypes)) { 16703 ret = XML_SCHEMAP_SRC_CT_1; 16704 } else 16705 /* 16706 * Attention: at this point the <simpleType> child is in 16707 * ->contentTypeDef (put there during parsing). 16708 */ 16709 if (type->contentTypeDef == NULL) { 16710 xmlChar *str = NULL; 16711 /* 16712 * 2.2 If clause 2.1.2 above is satisfied, then there 16713 * must be a <simpleType> among the [children] of 16714 * <restriction>. 16715 */ 16716 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16717 xmlSchemaPCustomErr(ctxt, 16718 XML_SCHEMAP_SRC_CT_1, 16719 WXS_BASIC_CAST type, NULL, 16720 "A <simpleType> is expected among the children " 16721 "of <restriction>, if <simpleContent> is used and " 16722 "the base type '%s' is a complex type", 16723 xmlSchemaFormatQName(&str, base->targetNamespace, 16724 base->name)); 16725 FREE_AND_NULL(str) 16726 return (XML_SCHEMAP_SRC_CT_1); 16727 } 16728 } else { 16729 ret = XML_SCHEMAP_SRC_CT_1; 16730 } 16731 } 16732 if (ret > 0) { 16733 xmlChar *str = NULL; 16734 if (WXS_IS_RESTRICTION(type)) { 16735 xmlSchemaPCustomErr(ctxt, 16736 XML_SCHEMAP_SRC_CT_1, 16737 WXS_BASIC_CAST type, NULL, 16738 "If <simpleContent> and <restriction> is used, the " 16739 "base type must be a simple type or a complex type with " 16740 "mixed content and particle emptiable. The base type " 16741 "'%s' is none of those", 16742 xmlSchemaFormatQName(&str, base->targetNamespace, 16743 base->name)); 16744 } else { 16745 xmlSchemaPCustomErr(ctxt, 16746 XML_SCHEMAP_SRC_CT_1, 16747 WXS_BASIC_CAST type, NULL, 16748 "If <simpleContent> and <extension> is used, the " 16749 "base type must be a simple type. The base type '%s' " 16750 "is a complex type", 16751 xmlSchemaFormatQName(&str, base->targetNamespace, 16752 base->name)); 16753 } 16754 FREE_AND_NULL(str) 16755 } 16756 } 16757 /* 16758 * SPEC (3) "The corresponding complex type definition component must 16759 * satisfy the conditions set out in Constraints on Complex Type 16760 * Definition Schema Components ($3.4.6);" 16761 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16762 */ 16763 /* 16764 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16765 * above for {attribute wildcard} is satisfied, the intensional 16766 * intersection must be expressible, as defined in Attribute Wildcard 16767 * Intersection ($3.10.6). 16768 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16769 */ 16770 return (ret); 16771 } 16772 16773 #ifdef ENABLE_PARTICLE_RESTRICTION 16774 /** 16775 * xmlSchemaCheckParticleRangeOK: 16776 * @ctxt: the schema parser context 16777 * @type: the complex type definition 16778 * 16779 * (3.9.6) Constraints on Particle Schema Components 16780 * Schema Component Constraint: 16781 * Occurrence Range OK (range-ok) 16782 * 16783 * STATUS: complete 16784 * 16785 * Returns 0 if the constraints are satisfied, a positive 16786 * error code if not and -1 if an internal error occured. 16787 */ 16788 static int 16789 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16790 int bmin, int bmax) 16791 { 16792 if (rmin < bmin) 16793 return (1); 16794 if ((bmax != UNBOUNDED) && 16795 (rmax > bmax)) 16796 return (1); 16797 return (0); 16798 } 16799 16800 /** 16801 * xmlSchemaCheckRCaseNameAndTypeOK: 16802 * @ctxt: the schema parser context 16803 * @r: the restricting element declaration particle 16804 * @b: the base element declaration particle 16805 * 16806 * (3.9.6) Constraints on Particle Schema Components 16807 * Schema Component Constraint: 16808 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16809 * (rcase-NameAndTypeOK) 16810 * 16811 * STATUS: 16812 * MISSING (3.2.3) 16813 * CLARIFY: (3.2.2) 16814 * 16815 * Returns 0 if the constraints are satisfied, a positive 16816 * error code if not and -1 if an internal error occured. 16817 */ 16818 static int 16819 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16820 xmlSchemaParticlePtr r, 16821 xmlSchemaParticlePtr b) 16822 { 16823 xmlSchemaElementPtr elemR, elemB; 16824 16825 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16826 elemR = (xmlSchemaElementPtr) r->children; 16827 elemB = (xmlSchemaElementPtr) b->children; 16828 /* 16829 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16830 * the same." 16831 */ 16832 if ((elemR != elemB) && 16833 ((! xmlStrEqual(elemR->name, elemB->name)) || 16834 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16835 return (1); 16836 /* 16837 * SPEC (2) "R's occurrence range is a valid restriction of B's 16838 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16839 */ 16840 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16841 b->minOccurs, b->maxOccurs) != 0) 16842 return (1); 16843 /* 16844 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16845 * {scope} are global." 16846 */ 16847 if (elemR == elemB) 16848 return (0); 16849 /* 16850 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16851 */ 16852 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16853 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16854 return (1); 16855 /* 16856 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16857 * or is not fixed, or R's declaration's {value constraint} is fixed 16858 * with the same value." 16859 */ 16860 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16861 ((elemR->value == NULL) || 16862 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16863 /* TODO: Equality of the initial value or normalized or canonical? */ 16864 (! xmlStrEqual(elemR->value, elemB->value)))) 16865 return (1); 16866 /* 16867 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16868 * definitions} is a subset of B's declaration's {identity-constraint 16869 * definitions}, if any." 16870 */ 16871 if (elemB->idcs != NULL) { 16872 /* TODO */ 16873 } 16874 /* 16875 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16876 * superset of B's declaration's {disallowed substitutions}." 16877 */ 16878 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16879 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16880 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16881 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16882 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16883 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16884 return (1); 16885 /* 16886 * SPEC (3.2.5) "R's {type definition} is validly derived given 16887 * {extension, list, union} from B's {type definition}" 16888 * 16889 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16890 * set, if the corresponding constraints handle "restriction" and 16891 * "extension" only? 16892 * 16893 */ 16894 { 16895 int set = 0; 16896 16897 set |= SUBSET_EXTENSION; 16898 set |= SUBSET_LIST; 16899 set |= SUBSET_UNION; 16900 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16901 elemB->subtypes, set) != 0) 16902 return (1); 16903 } 16904 return (0); 16905 } 16906 16907 /** 16908 * xmlSchemaCheckRCaseNSCompat: 16909 * @ctxt: the schema parser context 16910 * @r: the restricting element declaration particle 16911 * @b: the base wildcard particle 16912 * 16913 * (3.9.6) Constraints on Particle Schema Components 16914 * Schema Component Constraint: 16915 * Particle Derivation OK (Elt:Any -- NSCompat) 16916 * (rcase-NSCompat) 16917 * 16918 * STATUS: complete 16919 * 16920 * Returns 0 if the constraints are satisfied, a positive 16921 * error code if not and -1 if an internal error occured. 16922 */ 16923 static int 16924 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16925 xmlSchemaParticlePtr r, 16926 xmlSchemaParticlePtr b) 16927 { 16928 /* TODO:Error codes (rcase-NSCompat). */ 16929 /* 16930 * SPEC "For an element declaration particle to be a `valid restriction` 16931 * of a wildcard particle all of the following must be true:" 16932 * 16933 * SPEC (1) "The element declaration's {target namespace} is `valid` 16934 * with respect to the wildcard's {namespace constraint} as defined by 16935 * Wildcard allows Namespace Name ($3.10.4)." 16936 */ 16937 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16938 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16939 return (1); 16940 /* 16941 * SPEC (2) "R's occurrence range is a valid restriction of B's 16942 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16943 */ 16944 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16945 b->minOccurs, b->maxOccurs) != 0) 16946 return (1); 16947 16948 return (0); 16949 } 16950 16951 /** 16952 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16953 * @ctxt: the schema parser context 16954 * @r: the restricting element declaration particle 16955 * @b: the base model group particle 16956 * 16957 * (3.9.6) Constraints on Particle Schema Components 16958 * Schema Component Constraint: 16959 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16960 * (rcase-RecurseAsIfGroup) 16961 * 16962 * STATUS: TODO 16963 * 16964 * Returns 0 if the constraints are satisfied, a positive 16965 * error code if not and -1 if an internal error occured. 16966 */ 16967 static int 16968 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16969 xmlSchemaParticlePtr r, 16970 xmlSchemaParticlePtr b) 16971 { 16972 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16973 TODO 16974 return (0); 16975 } 16976 16977 /** 16978 * xmlSchemaCheckRCaseNSSubset: 16979 * @ctxt: the schema parser context 16980 * @r: the restricting wildcard particle 16981 * @b: the base wildcard particle 16982 * 16983 * (3.9.6) Constraints on Particle Schema Components 16984 * Schema Component Constraint: 16985 * Particle Derivation OK (Any:Any -- NSSubset) 16986 * (rcase-NSSubset) 16987 * 16988 * STATUS: complete 16989 * 16990 * Returns 0 if the constraints are satisfied, a positive 16991 * error code if not and -1 if an internal error occured. 16992 */ 16993 static int 16994 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 16995 xmlSchemaParticlePtr r, 16996 xmlSchemaParticlePtr b, 16997 int isAnyTypeBase) 16998 { 16999 /* TODO: Error codes (rcase-NSSubset). */ 17000 /* 17001 * SPEC (1) "R's occurrence range is a valid restriction of B's 17002 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17003 */ 17004 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17005 b->minOccurs, b->maxOccurs)) 17006 return (1); 17007 /* 17008 * SPEC (2) "R's {namespace constraint} must be an intensional subset 17009 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)." 17010 */ 17011 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 17012 (xmlSchemaWildcardPtr) b->children)) 17013 return (1); 17014 /* 17015 * SPEC (3) "Unless B is the content model wildcard of the `ur-type 17016 * definition`, R's {process contents} must be identical to or stronger 17017 * than B's {process contents}, where strict is stronger than lax is 17018 * stronger than skip." 17019 */ 17020 if (! isAnyTypeBase) { 17021 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 17022 ((xmlSchemaWildcardPtr) b->children)->processContents) 17023 return (1); 17024 } 17025 17026 return (0); 17027 } 17028 17029 /** 17030 * xmlSchemaCheckCOSParticleRestrict: 17031 * @ctxt: the schema parser context 17032 * @type: the complex type definition 17033 * 17034 * (3.9.6) Constraints on Particle Schema Components 17035 * Schema Component Constraint: 17036 * Particle Valid (Restriction) (cos-particle-restrict) 17037 * 17038 * STATUS: TODO 17039 * 17040 * Returns 0 if the constraints are satisfied, a positive 17041 * error code if not and -1 if an internal error occured. 17042 */ 17043 static int 17044 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17045 xmlSchemaParticlePtr r, 17046 xmlSchemaParticlePtr b) 17047 { 17048 int ret = 0; 17049 17050 /*part = WXS_TYPE_PARTICLE(type); 17051 basePart = WXS_TYPE_PARTICLE(base); 17052 */ 17053 17054 TODO 17055 17056 /* 17057 * SPEC (1) "They are the same particle." 17058 */ 17059 if (r == b) 17060 return (0); 17061 17062 17063 return (0); 17064 } 17065 17066 #if 0 17067 /** 17068 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17069 * @ctxt: the schema parser context 17070 * @r: the model group particle 17071 * @b: the base wildcard particle 17072 * 17073 * (3.9.6) Constraints on Particle Schema Components 17074 * Schema Component Constraint: 17075 * Particle Derivation OK (All/Choice/Sequence:Any -- 17076 * NSRecurseCheckCardinality) 17077 * (rcase-NSRecurseCheckCardinality) 17078 * 17079 * STATUS: TODO: subst-groups 17080 * 17081 * Returns 0 if the constraints are satisfied, a positive 17082 * error code if not and -1 if an internal error occured. 17083 */ 17084 static int 17085 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17086 xmlSchemaParticlePtr r, 17087 xmlSchemaParticlePtr b) 17088 { 17089 xmlSchemaParticlePtr part; 17090 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17091 if ((r->children == NULL) || (r->children->children == NULL)) 17092 return (-1); 17093 /* 17094 * SPEC "For a group particle to be a `valid restriction` of a 17095 * wildcard particle..." 17096 * 17097 * SPEC (1) "Every member of the {particles} of the group is a `valid 17098 * restriction` of the wildcard as defined by 17099 * Particle Valid (Restriction) ($3.9.6)." 17100 */ 17101 part = (xmlSchemaParticlePtr) r->children->children; 17102 do { 17103 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17104 return (1); 17105 part = (xmlSchemaParticlePtr) part->next; 17106 } while (part != NULL); 17107 /* 17108 * SPEC (2) "The effective total range of the group [...] is a 17109 * valid restriction of B's occurrence range as defined by 17110 * Occurrence Range OK ($3.9.6)." 17111 */ 17112 if (xmlSchemaCheckParticleRangeOK( 17113 xmlSchemaGetParticleTotalRangeMin(r), 17114 xmlSchemaGetParticleTotalRangeMax(r), 17115 b->minOccurs, b->maxOccurs) != 0) 17116 return (1); 17117 return (0); 17118 } 17119 #endif 17120 17121 /** 17122 * xmlSchemaCheckRCaseRecurse: 17123 * @ctxt: the schema parser context 17124 * @r: the <all> or <sequence> model group particle 17125 * @b: the base <all> or <sequence> model group particle 17126 * 17127 * (3.9.6) Constraints on Particle Schema Components 17128 * Schema Component Constraint: 17129 * Particle Derivation OK (All:All,Sequence:Sequence -- 17130 Recurse) 17131 * (rcase-Recurse) 17132 * 17133 * STATUS: ? 17134 * TODO: subst-groups 17135 * 17136 * Returns 0 if the constraints are satisfied, a positive 17137 * error code if not and -1 if an internal error occured. 17138 */ 17139 static int 17140 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17141 xmlSchemaParticlePtr r, 17142 xmlSchemaParticlePtr b) 17143 { 17144 /* xmlSchemaParticlePtr part; */ 17145 /* TODO: Error codes (rcase-Recurse). */ 17146 if ((r->children == NULL) || (b->children == NULL) || 17147 (r->children->type != b->children->type)) 17148 return (-1); 17149 /* 17150 * SPEC "For an all or sequence group particle to be a `valid 17151 * restriction` of another group particle with the same {compositor}..." 17152 * 17153 * SPEC (1) "R's occurrence range is a valid restriction of B's 17154 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17155 */ 17156 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17157 b->minOccurs, b->maxOccurs)) 17158 return (1); 17159 17160 17161 return (0); 17162 } 17163 17164 #endif 17165 17166 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17167 xmlSchemaPCustomErrExt(pctxt, \ 17168 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17169 WXS_BASIC_CAST fac1, fac1->node, \ 17170 "It is an error for both '%s' and '%s' to be specified on the "\ 17171 "same type definition", \ 17172 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17173 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17174 17175 #define FACET_RESTR_ERR(fac1, msg) \ 17176 xmlSchemaPCustomErr(pctxt, \ 17177 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17178 WXS_BASIC_CAST fac1, fac1->node, \ 17179 msg, NULL); 17180 17181 #define FACET_RESTR_FIXED_ERR(fac) \ 17182 xmlSchemaPCustomErr(pctxt, \ 17183 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17184 WXS_BASIC_CAST fac, fac->node, \ 17185 "The base type's facet is 'fixed', thus the value must not " \ 17186 "differ", NULL); 17187 17188 static void 17189 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17190 xmlSchemaFacetPtr facet1, 17191 xmlSchemaFacetPtr facet2, 17192 int lessGreater, 17193 int orEqual, 17194 int ofBase) 17195 { 17196 xmlChar *msg = NULL; 17197 17198 msg = xmlStrdup(BAD_CAST "'"); 17199 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17200 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17201 if (lessGreater == 0) 17202 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17203 if (lessGreater == 1) 17204 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17205 else 17206 msg = xmlStrcat(msg, BAD_CAST " less than"); 17207 17208 if (orEqual) 17209 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17210 msg = xmlStrcat(msg, BAD_CAST " '"); 17211 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17212 if (ofBase) 17213 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17214 else 17215 msg = xmlStrcat(msg, BAD_CAST "'"); 17216 17217 xmlSchemaPCustomErr(pctxt, 17218 XML_SCHEMAP_INVALID_FACET_VALUE, 17219 WXS_BASIC_CAST facet1, NULL, 17220 (const char *) msg, NULL); 17221 17222 if (msg != NULL) 17223 xmlFree(msg); 17224 } 17225 17226 /* 17227 * xmlSchemaDeriveAndValidateFacets: 17228 * 17229 * Schema Component Constraint: Simple Type Restriction (Facets) 17230 * (st-restrict-facets) 17231 */ 17232 static int 17233 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17234 xmlSchemaTypePtr type) 17235 { 17236 xmlSchemaTypePtr base = type->baseType; 17237 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17238 xmlSchemaFacetPtr facet, bfacet, 17239 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17240 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17241 fmininc = NULL, fmaxinc = NULL, 17242 fminexc = NULL, fmaxexc = NULL, 17243 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17244 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17245 bfmininc = NULL, bfmaxinc = NULL, 17246 bfminexc = NULL, bfmaxexc = NULL; 17247 int res; /* err = 0, fixedErr; */ 17248 17249 /* 17250 * SPEC st-restrict-facets 1: 17251 * "The {variety} of R is the same as that of B." 17252 */ 17253 /* 17254 * SPEC st-restrict-facets 2: 17255 * "If {variety} is atomic, the {primitive type definition} 17256 * of R is the same as that of B." 17257 * 17258 * NOTE: we leave 1 & 2 out for now, since this will be 17259 * satisfied by the derivation process. 17260 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17261 */ 17262 /* 17263 * SPEC st-restrict-facets 3: 17264 * "The {facets} of R are the union of S and the {facets} 17265 * of B, eliminating duplicates. To eliminate duplicates, 17266 * when a facet of the same kind occurs in both S and the 17267 * {facets} of B, the one in the {facets} of B is not 17268 * included, with the exception of enumeration and pattern 17269 * facets, for which multiple occurrences with distinct values 17270 * are allowed." 17271 */ 17272 17273 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17274 return (0); 17275 17276 last = type->facetSet; 17277 if (last != NULL) 17278 while (last->next != NULL) 17279 last = last->next; 17280 17281 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17282 facet = cur->facet; 17283 switch (facet->type) { 17284 case XML_SCHEMA_FACET_LENGTH: 17285 flength = facet; break; 17286 case XML_SCHEMA_FACET_MINLENGTH: 17287 fminlen = facet; break; 17288 case XML_SCHEMA_FACET_MININCLUSIVE: 17289 fmininc = facet; break; 17290 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17291 fminexc = facet; break; 17292 case XML_SCHEMA_FACET_MAXLENGTH: 17293 fmaxlen = facet; break; 17294 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17295 fmaxinc = facet; break; 17296 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17297 fmaxexc = facet; break; 17298 case XML_SCHEMA_FACET_TOTALDIGITS: 17299 ftotdig = facet; break; 17300 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17301 ffracdig = facet; break; 17302 default: 17303 break; 17304 } 17305 } 17306 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17307 facet = cur->facet; 17308 switch (facet->type) { 17309 case XML_SCHEMA_FACET_LENGTH: 17310 bflength = facet; break; 17311 case XML_SCHEMA_FACET_MINLENGTH: 17312 bfminlen = facet; break; 17313 case XML_SCHEMA_FACET_MININCLUSIVE: 17314 bfmininc = facet; break; 17315 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17316 bfminexc = facet; break; 17317 case XML_SCHEMA_FACET_MAXLENGTH: 17318 bfmaxlen = facet; break; 17319 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17320 bfmaxinc = facet; break; 17321 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17322 bfmaxexc = facet; break; 17323 case XML_SCHEMA_FACET_TOTALDIGITS: 17324 bftotdig = facet; break; 17325 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17326 bffracdig = facet; break; 17327 default: 17328 break; 17329 } 17330 } 17331 /* 17332 * length and minLength or maxLength (2.2) + (3.2) 17333 */ 17334 if (flength && (fminlen || fmaxlen)) { 17335 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17336 "either of 'minLength' or 'maxLength' to be specified on " 17337 "the same type definition") 17338 } 17339 /* 17340 * Mutual exclusions in the same derivation step. 17341 */ 17342 if ((fmaxinc) && (fmaxexc)) { 17343 /* 17344 * SCC "maxInclusive and maxExclusive" 17345 */ 17346 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17347 } 17348 if ((fmininc) && (fminexc)) { 17349 /* 17350 * SCC "minInclusive and minExclusive" 17351 */ 17352 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17353 } 17354 17355 if (flength && bflength) { 17356 /* 17357 * SCC "length valid restriction" 17358 * The values have to be equal. 17359 */ 17360 res = xmlSchemaCompareValues(flength->val, bflength->val); 17361 if (res == -2) 17362 goto internal_error; 17363 if (res != 0) 17364 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17365 if ((res != 0) && (bflength->fixed)) { 17366 FACET_RESTR_FIXED_ERR(flength) 17367 } 17368 17369 } 17370 if (fminlen && bfminlen) { 17371 /* 17372 * SCC "minLength valid restriction" 17373 * minLength >= BASE minLength 17374 */ 17375 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17376 if (res == -2) 17377 goto internal_error; 17378 if (res == -1) 17379 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17380 if ((res != 0) && (bfminlen->fixed)) { 17381 FACET_RESTR_FIXED_ERR(fminlen) 17382 } 17383 } 17384 if (fmaxlen && bfmaxlen) { 17385 /* 17386 * SCC "maxLength valid restriction" 17387 * maxLength <= BASE minLength 17388 */ 17389 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17390 if (res == -2) 17391 goto internal_error; 17392 if (res == 1) 17393 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17394 if ((res != 0) && (bfmaxlen->fixed)) { 17395 FACET_RESTR_FIXED_ERR(fmaxlen) 17396 } 17397 } 17398 /* 17399 * SCC "length and minLength or maxLength" 17400 */ 17401 if (! flength) 17402 flength = bflength; 17403 if (flength) { 17404 if (! fminlen) 17405 fminlen = bfminlen; 17406 if (fminlen) { 17407 /* (1.1) length >= minLength */ 17408 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17409 if (res == -2) 17410 goto internal_error; 17411 if (res == -1) 17412 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17413 } 17414 if (! fmaxlen) 17415 fmaxlen = bfmaxlen; 17416 if (fmaxlen) { 17417 /* (2.1) length <= maxLength */ 17418 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17419 if (res == -2) 17420 goto internal_error; 17421 if (res == 1) 17422 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17423 } 17424 } 17425 if (fmaxinc) { 17426 /* 17427 * "maxInclusive" 17428 */ 17429 if (fmininc) { 17430 /* SCC "maxInclusive >= minInclusive" */ 17431 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17432 if (res == -2) 17433 goto internal_error; 17434 if (res == -1) { 17435 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17436 } 17437 } 17438 /* 17439 * SCC "maxInclusive valid restriction" 17440 */ 17441 if (bfmaxinc) { 17442 /* maxInclusive <= BASE maxInclusive */ 17443 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17444 if (res == -2) 17445 goto internal_error; 17446 if (res == 1) 17447 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17448 if ((res != 0) && (bfmaxinc->fixed)) { 17449 FACET_RESTR_FIXED_ERR(fmaxinc) 17450 } 17451 } 17452 if (bfmaxexc) { 17453 /* maxInclusive < BASE maxExclusive */ 17454 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17455 if (res == -2) 17456 goto internal_error; 17457 if (res != -1) { 17458 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17459 } 17460 } 17461 if (bfmininc) { 17462 /* maxInclusive >= BASE minInclusive */ 17463 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17464 if (res == -2) 17465 goto internal_error; 17466 if (res == -1) { 17467 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17468 } 17469 } 17470 if (bfminexc) { 17471 /* maxInclusive > BASE minExclusive */ 17472 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17473 if (res == -2) 17474 goto internal_error; 17475 if (res != 1) { 17476 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17477 } 17478 } 17479 } 17480 if (fmaxexc) { 17481 /* 17482 * "maxExclusive >= minExclusive" 17483 */ 17484 if (fminexc) { 17485 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17486 if (res == -2) 17487 goto internal_error; 17488 if (res == -1) { 17489 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17490 } 17491 } 17492 /* 17493 * "maxExclusive valid restriction" 17494 */ 17495 if (bfmaxexc) { 17496 /* maxExclusive <= BASE maxExclusive */ 17497 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17498 if (res == -2) 17499 goto internal_error; 17500 if (res == 1) { 17501 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17502 } 17503 if ((res != 0) && (bfmaxexc->fixed)) { 17504 FACET_RESTR_FIXED_ERR(fmaxexc) 17505 } 17506 } 17507 if (bfmaxinc) { 17508 /* maxExclusive <= BASE maxInclusive */ 17509 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17510 if (res == -2) 17511 goto internal_error; 17512 if (res == 1) { 17513 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17514 } 17515 } 17516 if (bfmininc) { 17517 /* maxExclusive > BASE minInclusive */ 17518 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17519 if (res == -2) 17520 goto internal_error; 17521 if (res != 1) { 17522 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17523 } 17524 } 17525 if (bfminexc) { 17526 /* maxExclusive > BASE minExclusive */ 17527 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17528 if (res == -2) 17529 goto internal_error; 17530 if (res != 1) { 17531 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17532 } 17533 } 17534 } 17535 if (fminexc) { 17536 /* 17537 * "minExclusive < maxInclusive" 17538 */ 17539 if (fmaxinc) { 17540 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17541 if (res == -2) 17542 goto internal_error; 17543 if (res != -1) { 17544 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17545 } 17546 } 17547 /* 17548 * "minExclusive valid restriction" 17549 */ 17550 if (bfminexc) { 17551 /* minExclusive >= BASE minExclusive */ 17552 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17553 if (res == -2) 17554 goto internal_error; 17555 if (res == -1) { 17556 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17557 } 17558 if ((res != 0) && (bfminexc->fixed)) { 17559 FACET_RESTR_FIXED_ERR(fminexc) 17560 } 17561 } 17562 if (bfmaxinc) { 17563 /* minExclusive <= BASE maxInclusive */ 17564 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17565 if (res == -2) 17566 goto internal_error; 17567 if (res == 1) { 17568 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17569 } 17570 } 17571 if (bfmininc) { 17572 /* minExclusive >= BASE minInclusive */ 17573 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17574 if (res == -2) 17575 goto internal_error; 17576 if (res == -1) { 17577 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17578 } 17579 } 17580 if (bfmaxexc) { 17581 /* minExclusive < BASE maxExclusive */ 17582 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17583 if (res == -2) 17584 goto internal_error; 17585 if (res != -1) { 17586 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17587 } 17588 } 17589 } 17590 if (fmininc) { 17591 /* 17592 * "minInclusive < maxExclusive" 17593 */ 17594 if (fmaxexc) { 17595 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17596 if (res == -2) 17597 goto internal_error; 17598 if (res != -1) { 17599 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17600 } 17601 } 17602 /* 17603 * "minExclusive valid restriction" 17604 */ 17605 if (bfmininc) { 17606 /* minInclusive >= BASE minInclusive */ 17607 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17608 if (res == -2) 17609 goto internal_error; 17610 if (res == -1) { 17611 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17612 } 17613 if ((res != 0) && (bfmininc->fixed)) { 17614 FACET_RESTR_FIXED_ERR(fmininc) 17615 } 17616 } 17617 if (bfmaxinc) { 17618 /* minInclusive <= BASE maxInclusive */ 17619 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17620 if (res == -2) 17621 goto internal_error; 17622 if (res == 1) { 17623 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17624 } 17625 } 17626 if (bfminexc) { 17627 /* minInclusive > BASE minExclusive */ 17628 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17629 if (res == -2) 17630 goto internal_error; 17631 if (res != 1) 17632 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17633 } 17634 if (bfmaxexc) { 17635 /* minInclusive < BASE maxExclusive */ 17636 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17637 if (res == -2) 17638 goto internal_error; 17639 if (res != -1) 17640 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17641 } 17642 } 17643 if (ftotdig && bftotdig) { 17644 /* 17645 * SCC " totalDigits valid restriction" 17646 * totalDigits <= BASE totalDigits 17647 */ 17648 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17649 if (res == -2) 17650 goto internal_error; 17651 if (res == 1) 17652 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17653 -1, 1, 1); 17654 if ((res != 0) && (bftotdig->fixed)) { 17655 FACET_RESTR_FIXED_ERR(ftotdig) 17656 } 17657 } 17658 if (ffracdig && bffracdig) { 17659 /* 17660 * SCC "fractionDigits valid restriction" 17661 * fractionDigits <= BASE fractionDigits 17662 */ 17663 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17664 if (res == -2) 17665 goto internal_error; 17666 if (res == 1) 17667 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17668 -1, 1, 1); 17669 if ((res != 0) && (bffracdig->fixed)) { 17670 FACET_RESTR_FIXED_ERR(ffracdig) 17671 } 17672 } 17673 /* 17674 * SCC "fractionDigits less than or equal to totalDigits" 17675 */ 17676 if (! ftotdig) 17677 ftotdig = bftotdig; 17678 if (! ffracdig) 17679 ffracdig = bffracdig; 17680 if (ftotdig && ffracdig) { 17681 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17682 if (res == -2) 17683 goto internal_error; 17684 if (res == 1) 17685 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17686 -1, 1, 0); 17687 } 17688 /* 17689 * *Enumerations* won' be added here, since only the first set 17690 * of enumerations in the ancestor-or-self axis is used 17691 * for validation, plus we need to use the base type of those 17692 * enumerations for whitespace. 17693 * 17694 * *Patterns*: won't be add here, since they are ORed at 17695 * type level and ANDed at ancestor level. This will 17696 * happed during validation by walking the base axis 17697 * of the type. 17698 */ 17699 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17700 bfacet = cur->facet; 17701 /* 17702 * Special handling of enumerations and patterns. 17703 * TODO: hmm, they should not appear in the set, so remove this. 17704 */ 17705 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17706 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17707 continue; 17708 /* 17709 * Search for a duplicate facet in the current type. 17710 */ 17711 link = type->facetSet; 17712 /* err = 0; */ 17713 /* fixedErr = 0; */ 17714 while (link != NULL) { 17715 facet = link->facet; 17716 if (facet->type == bfacet->type) { 17717 switch (facet->type) { 17718 case XML_SCHEMA_FACET_WHITESPACE: 17719 /* 17720 * The whitespace must be stronger. 17721 */ 17722 if (facet->whitespace < bfacet->whitespace) { 17723 FACET_RESTR_ERR(facet, 17724 "The 'whitespace' value has to be equal to " 17725 "or stronger than the 'whitespace' value of " 17726 "the base type") 17727 } 17728 if ((bfacet->fixed) && 17729 (facet->whitespace != bfacet->whitespace)) { 17730 FACET_RESTR_FIXED_ERR(facet) 17731 } 17732 break; 17733 default: 17734 break; 17735 } 17736 /* Duplicate found. */ 17737 break; 17738 } 17739 link = link->next; 17740 } 17741 /* 17742 * If no duplicate was found: add the base types's facet 17743 * to the set. 17744 */ 17745 if (link == NULL) { 17746 link = (xmlSchemaFacetLinkPtr) 17747 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17748 if (link == NULL) { 17749 xmlSchemaPErrMemory(pctxt, 17750 "deriving facets, creating a facet link", NULL); 17751 return (-1); 17752 } 17753 link->facet = cur->facet; 17754 link->next = NULL; 17755 if (last == NULL) 17756 type->facetSet = link; 17757 else 17758 last->next = link; 17759 last = link; 17760 } 17761 17762 } 17763 17764 return (0); 17765 internal_error: 17766 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17767 "an error occured"); 17768 return (-1); 17769 } 17770 17771 static int 17772 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17773 xmlSchemaTypePtr type) 17774 { 17775 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17776 /* 17777 * The actual value is then formed by replacing any union type 17778 * definition in the `explicit members` with the members of their 17779 * {member type definitions}, in order. 17780 * 17781 * TODO: There's a bug entry at 17782 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17783 * which indicates that we'll keep the union types the future. 17784 */ 17785 link = type->memberTypes; 17786 while (link != NULL) { 17787 17788 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17789 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17790 17791 if (WXS_IS_UNION(link->type)) { 17792 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17793 if (subLink != NULL) { 17794 link->type = subLink->type; 17795 if (subLink->next != NULL) { 17796 lastLink = link->next; 17797 subLink = subLink->next; 17798 prevLink = link; 17799 while (subLink != NULL) { 17800 newLink = (xmlSchemaTypeLinkPtr) 17801 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17802 if (newLink == NULL) { 17803 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17804 NULL); 17805 return (-1); 17806 } 17807 newLink->type = subLink->type; 17808 prevLink->next = newLink; 17809 prevLink = newLink; 17810 newLink->next = lastLink; 17811 17812 subLink = subLink->next; 17813 } 17814 } 17815 } 17816 } 17817 link = link->next; 17818 } 17819 return (0); 17820 } 17821 17822 static void 17823 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17824 { 17825 int has = 0, needVal = 0, normVal = 0; 17826 17827 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17828 if (has) { 17829 needVal = (type->baseType->flags & 17830 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17831 normVal = (type->baseType->flags & 17832 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17833 } 17834 if (type->facets != NULL) { 17835 xmlSchemaFacetPtr fac; 17836 17837 for (fac = type->facets; fac != NULL; fac = fac->next) { 17838 switch (fac->type) { 17839 case XML_SCHEMA_FACET_WHITESPACE: 17840 break; 17841 case XML_SCHEMA_FACET_PATTERN: 17842 normVal = 1; 17843 has = 1; 17844 break; 17845 case XML_SCHEMA_FACET_ENUMERATION: 17846 needVal = 1; 17847 normVal = 1; 17848 has = 1; 17849 break; 17850 default: 17851 has = 1; 17852 break; 17853 } 17854 } 17855 } 17856 if (normVal) 17857 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17858 if (needVal) 17859 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17860 if (has) 17861 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17862 17863 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17864 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17865 /* 17866 * OPTIMIZE VAL TODO: Some facets need a computed value. 17867 */ 17868 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17869 (prim->builtInType != XML_SCHEMAS_STRING)) { 17870 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17871 } 17872 } 17873 } 17874 17875 static int 17876 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17877 { 17878 17879 17880 /* 17881 * Evaluate the whitespace-facet value. 17882 */ 17883 if (WXS_IS_LIST(type)) { 17884 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17885 return (0); 17886 } else if (WXS_IS_UNION(type)) 17887 return (0); 17888 17889 if (type->facetSet != NULL) { 17890 xmlSchemaFacetLinkPtr lin; 17891 17892 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17893 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17894 switch (lin->facet->whitespace) { 17895 case XML_SCHEMAS_FACET_PRESERVE: 17896 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17897 break; 17898 case XML_SCHEMAS_FACET_REPLACE: 17899 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17900 break; 17901 case XML_SCHEMAS_FACET_COLLAPSE: 17902 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17903 break; 17904 default: 17905 return (-1); 17906 } 17907 return (0); 17908 } 17909 } 17910 } 17911 /* 17912 * For all `atomic` datatypes other than string (and types `derived` 17913 * by `restriction` from it) the value of whiteSpace is fixed to 17914 * collapse 17915 */ 17916 { 17917 xmlSchemaTypePtr anc; 17918 17919 for (anc = type->baseType; anc != NULL && 17920 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17921 anc = anc->baseType) { 17922 17923 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17924 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17925 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17926 17927 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17928 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17929 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17930 17931 } else 17932 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17933 break; 17934 } 17935 } 17936 } 17937 return (0); 17938 } 17939 17940 static int 17941 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17942 xmlSchemaTypePtr type) 17943 { 17944 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17945 return(0); 17946 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17947 return(0); 17948 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17949 17950 if (WXS_IS_LIST(type)) { 17951 /* 17952 * Corresponds to <simpleType><list>... 17953 */ 17954 if (type->subtypes == NULL) { 17955 /* 17956 * This one is really needed, so get out. 17957 */ 17958 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17959 "list type has no item-type assigned"); 17960 return(-1); 17961 } 17962 } else if (WXS_IS_UNION(type)) { 17963 /* 17964 * Corresponds to <simpleType><union>... 17965 */ 17966 if (type->memberTypes == NULL) { 17967 /* 17968 * This one is really needed, so get out. 17969 */ 17970 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17971 "union type has no member-types assigned"); 17972 return(-1); 17973 } 17974 } else { 17975 /* 17976 * Corresponds to <simpleType><restriction>... 17977 */ 17978 if (type->baseType == NULL) { 17979 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17980 "type has no base-type assigned"); 17981 return(-1); 17982 } 17983 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 17984 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 17985 return(-1); 17986 /* 17987 * Variety 17988 * If the <restriction> alternative is chosen, then the 17989 * {variety} of the {base type definition}. 17990 */ 17991 if (WXS_IS_ATOMIC(type->baseType)) 17992 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 17993 else if (WXS_IS_LIST(type->baseType)) { 17994 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 17995 /* 17996 * Inherit the itemType. 17997 */ 17998 type->subtypes = type->baseType->subtypes; 17999 } else if (WXS_IS_UNION(type->baseType)) { 18000 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 18001 /* 18002 * NOTE that we won't assign the memberTypes of the base, 18003 * since this will make trouble when freeing them; we will 18004 * use a lookup function to access them instead. 18005 */ 18006 } 18007 } 18008 return(0); 18009 } 18010 18011 #ifdef DEBUG_TYPE 18012 static void 18013 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 18014 xmlSchemaTypePtr type) 18015 { 18016 if (type->node != NULL) { 18017 xmlGenericError(xmlGenericErrorContext, 18018 "Type of %s : %s:%d :", name, 18019 type->node->doc->URL, 18020 xmlGetLineNo(type->node)); 18021 } else { 18022 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 18023 } 18024 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 18025 switch (type->contentType) { 18026 case XML_SCHEMA_CONTENT_SIMPLE: 18027 xmlGenericError(xmlGenericErrorContext, "simple\n"); 18028 break; 18029 case XML_SCHEMA_CONTENT_ELEMENTS: 18030 xmlGenericError(xmlGenericErrorContext, "elements\n"); 18031 break; 18032 case XML_SCHEMA_CONTENT_UNKNOWN: 18033 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 18034 break; 18035 case XML_SCHEMA_CONTENT_EMPTY: 18036 xmlGenericError(xmlGenericErrorContext, "empty\n"); 18037 break; 18038 case XML_SCHEMA_CONTENT_MIXED: 18039 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 18040 type->subtypes)) 18041 xmlGenericError(xmlGenericErrorContext, 18042 "mixed as emptiable particle\n"); 18043 else 18044 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18045 break; 18046 /* Removed, since not used. */ 18047 /* 18048 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18049 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18050 break; 18051 */ 18052 case XML_SCHEMA_CONTENT_BASIC: 18053 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18054 break; 18055 default: 18056 xmlGenericError(xmlGenericErrorContext, 18057 "not registered !!!\n"); 18058 break; 18059 } 18060 } 18061 } 18062 #endif 18063 18064 /* 18065 * 3.14.6 Constraints on Simple Type Definition Schema Components 18066 */ 18067 static int 18068 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18069 xmlSchemaTypePtr type) 18070 { 18071 int res, olderrs = pctxt->nberrors; 18072 18073 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18074 return(-1); 18075 18076 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18077 return(0); 18078 18079 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18080 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18081 18082 if (type->baseType == NULL) { 18083 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18084 "missing baseType"); 18085 goto exit_failure; 18086 } 18087 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18088 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18089 /* 18090 * If a member type of a union is a union itself, we need to substitute 18091 * that member type for its member types. 18092 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18093 * types in WXS 1.1. 18094 */ 18095 if ((type->memberTypes != NULL) && 18096 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18097 return(-1); 18098 /* 18099 * SPEC src-simple-type 1 18100 * "The corresponding simple type definition, if any, must satisfy 18101 * the conditions set out in Constraints on Simple Type Definition 18102 * Schema Components ($3.14.6)." 18103 */ 18104 /* 18105 * Schema Component Constraint: Simple Type Definition Properties Correct 18106 * (st-props-correct) 18107 */ 18108 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18109 HFAILURE HERROR 18110 /* 18111 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18112 * (cos-st-restricts) 18113 */ 18114 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18115 HFAILURE HERROR 18116 /* 18117 * TODO: Removed the error report, since it got annoying to get an 18118 * extra error report, if anything failed until now. 18119 * Enable this if needed. 18120 * 18121 * xmlSchemaPErr(ctxt, type->node, 18122 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18123 * "Simple type '%s' does not satisfy the constraints " 18124 * "on simple type definitions.\n", 18125 * type->name, NULL); 18126 */ 18127 /* 18128 * Schema Component Constraint: Simple Type Restriction (Facets) 18129 * (st-restrict-facets) 18130 */ 18131 res = xmlSchemaCheckFacetValues(type, pctxt); 18132 HFAILURE HERROR 18133 if ((type->facetSet != NULL) || 18134 (type->baseType->facetSet != NULL)) { 18135 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18136 HFAILURE HERROR 18137 } 18138 /* 18139 * Whitespace value. 18140 */ 18141 res = xmlSchemaTypeFixupWhitespace(type); 18142 HFAILURE HERROR 18143 xmlSchemaTypeFixupOptimFacets(type); 18144 18145 exit_error: 18146 #ifdef DEBUG_TYPE 18147 xmlSchemaDebugFixedType(pctxt, type); 18148 #endif 18149 if (olderrs != pctxt->nberrors) 18150 return(pctxt->err); 18151 return(0); 18152 18153 exit_failure: 18154 #ifdef DEBUG_TYPE 18155 xmlSchemaDebugFixedType(pctxt, type); 18156 #endif 18157 return(-1); 18158 } 18159 18160 static int 18161 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18162 xmlSchemaTypePtr type) 18163 { 18164 int res = 0, olderrs = pctxt->nberrors; 18165 xmlSchemaTypePtr baseType = type->baseType; 18166 18167 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18168 return(0); 18169 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18170 if (baseType == NULL) { 18171 PERROR_INT("xmlSchemaFixupComplexType", 18172 "missing baseType"); 18173 goto exit_failure; 18174 } 18175 /* 18176 * Fixup the base type. 18177 */ 18178 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18179 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18180 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18181 /* 18182 * Skip fixup if the base type is invalid. 18183 * TODO: Generate a warning! 18184 */ 18185 return(0); 18186 } 18187 /* 18188 * This basically checks if the base type can be derived. 18189 */ 18190 res = xmlSchemaCheckSRCCT(pctxt, type); 18191 HFAILURE HERROR 18192 /* 18193 * Fixup the content type. 18194 */ 18195 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18196 /* 18197 * Corresponds to <complexType><simpleContent>... 18198 */ 18199 if ((WXS_IS_COMPLEX(baseType)) && 18200 (baseType->contentTypeDef != NULL) && 18201 (WXS_IS_RESTRICTION(type))) { 18202 xmlSchemaTypePtr contentBase, content; 18203 #ifdef ENABLE_NAMED_LOCALS 18204 char buf[30]; 18205 const xmlChar *tmpname; 18206 #endif 18207 /* 18208 * SPEC (1) If <restriction> + base type is <complexType>, 18209 * "whose own {content type} is a simple type..." 18210 */ 18211 if (type->contentTypeDef != NULL) { 18212 /* 18213 * SPEC (1.1) "the simple type definition corresponding to the 18214 * <simpleType> among the [children] of <restriction> if there 18215 * is one;" 18216 * Note that this "<simpleType> among the [children]" was put 18217 * into ->contentTypeDef during parsing. 18218 */ 18219 contentBase = type->contentTypeDef; 18220 type->contentTypeDef = NULL; 18221 } else { 18222 /* 18223 * (1.2) "...otherwise (<restriction> has no <simpleType> 18224 * among its [children]), the simple type definition which 18225 * is the {content type} of the ... base type." 18226 */ 18227 contentBase = baseType->contentTypeDef; 18228 } 18229 /* 18230 * SPEC 18231 * "... a simple type definition which restricts the simple 18232 * type definition identified in clause 1.1 or clause 1.2 18233 * with a set of facet components" 18234 * 18235 * Create the anonymous simple type, which will be the content 18236 * type of the complex type. 18237 */ 18238 #ifdef ENABLE_NAMED_LOCALS 18239 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18240 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18241 content = xmlSchemaAddType(pctxt, pctxt->schema, 18242 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18243 type->node, 0); 18244 #else 18245 content = xmlSchemaAddType(pctxt, pctxt->schema, 18246 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18247 type->node, 0); 18248 #endif 18249 if (content == NULL) 18250 goto exit_failure; 18251 /* 18252 * We will use the same node as for the <complexType> 18253 * to have it somehow anchored in the schema doc. 18254 */ 18255 content->type = XML_SCHEMA_TYPE_SIMPLE; 18256 content->baseType = contentBase; 18257 /* 18258 * Move the facets, previously anchored on the 18259 * complexType during parsing. 18260 */ 18261 content->facets = type->facets; 18262 type->facets = NULL; 18263 content->facetSet = type->facetSet; 18264 type->facetSet = NULL; 18265 18266 type->contentTypeDef = content; 18267 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18268 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18269 /* 18270 * Fixup the newly created type. We don't need to check 18271 * for circularity here. 18272 */ 18273 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18274 HFAILURE HERROR 18275 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18276 HFAILURE HERROR 18277 18278 } else if ((WXS_IS_COMPLEX(baseType)) && 18279 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18280 (WXS_IS_RESTRICTION(type))) { 18281 /* 18282 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18283 * an emptiable particle, then a simple type definition which 18284 * restricts the <restriction>'s <simpleType> child. 18285 */ 18286 if ((type->contentTypeDef == NULL) || 18287 (type->contentTypeDef->baseType == NULL)) { 18288 /* 18289 * TODO: Check if this ever happens. 18290 */ 18291 xmlSchemaPCustomErr(pctxt, 18292 XML_SCHEMAP_INTERNAL, 18293 WXS_BASIC_CAST type, NULL, 18294 "Internal error: xmlSchemaTypeFixup, " 18295 "complex type '%s': the <simpleContent><restriction> " 18296 "is missing a <simpleType> child, but was not catched " 18297 "by xmlSchemaCheckSRCCT()", type->name); 18298 goto exit_failure; 18299 } 18300 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18301 /* 18302 * SPEC (3) If <extension> + base is <complexType> with 18303 * <simpleType> content, "...then the {content type} of that 18304 * complex type definition" 18305 */ 18306 if (baseType->contentTypeDef == NULL) { 18307 /* 18308 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18309 * should have catched this already. 18310 */ 18311 xmlSchemaPCustomErr(pctxt, 18312 XML_SCHEMAP_INTERNAL, 18313 WXS_BASIC_CAST type, NULL, 18314 "Internal error: xmlSchemaTypeFixup, " 18315 "complex type '%s': the <extension>ed base type is " 18316 "a complex type with no simple content type", 18317 type->name); 18318 goto exit_failure; 18319 } 18320 type->contentTypeDef = baseType->contentTypeDef; 18321 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18322 /* 18323 * SPEC (4) <extension> + base is <simpleType> 18324 * "... then that simple type definition" 18325 */ 18326 type->contentTypeDef = baseType; 18327 } else { 18328 /* 18329 * TODO: Check if this ever happens. 18330 */ 18331 xmlSchemaPCustomErr(pctxt, 18332 XML_SCHEMAP_INTERNAL, 18333 WXS_BASIC_CAST type, NULL, 18334 "Internal error: xmlSchemaTypeFixup, " 18335 "complex type '%s' with <simpleContent>: unhandled " 18336 "derivation case", type->name); 18337 goto exit_failure; 18338 } 18339 } else { 18340 int dummySequence = 0; 18341 xmlSchemaParticlePtr particle = 18342 (xmlSchemaParticlePtr) type->subtypes; 18343 /* 18344 * Corresponds to <complexType><complexContent>... 18345 * 18346 * NOTE that the effective mixed was already set during parsing of 18347 * <complexType> and <complexContent>; its flag value is 18348 * XML_SCHEMAS_TYPE_MIXED. 18349 * 18350 * Compute the "effective content": 18351 * (2.1.1) + (2.1.2) + (2.1.3) 18352 */ 18353 if ((particle == NULL) || 18354 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18355 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18356 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18357 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18358 (particle->minOccurs == 0))) && 18359 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18360 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18361 /* 18362 * SPEC (2.1.4) "If the `effective mixed` is true, then 18363 * a particle whose properties are as follows:..." 18364 * 18365 * Empty sequence model group with 18366 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18367 * NOTE that we sill assign it the <complexType> node to 18368 * somehow anchor it in the doc. 18369 */ 18370 if ((particle == NULL) || 18371 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18372 /* 18373 * Create the particle. 18374 */ 18375 particle = xmlSchemaAddParticle(pctxt, 18376 type->node, 1, 1); 18377 if (particle == NULL) 18378 goto exit_failure; 18379 /* 18380 * Create the model group. 18381 */ /* URGENT TODO: avoid adding to pending items. */ 18382 particle->children = (xmlSchemaTreeItemPtr) 18383 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18384 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18385 if (particle->children == NULL) 18386 goto exit_failure; 18387 18388 type->subtypes = (xmlSchemaTypePtr) particle; 18389 } 18390 dummySequence = 1; 18391 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18392 } else { 18393 /* 18394 * SPEC (2.1.5) "otherwise empty" 18395 */ 18396 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18397 } 18398 } else { 18399 /* 18400 * SPEC (2.2) "otherwise the particle corresponding to the 18401 * <all>, <choice>, <group> or <sequence> among the 18402 * [children]." 18403 */ 18404 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18405 } 18406 /* 18407 * Compute the "content type". 18408 */ 18409 if (WXS_IS_RESTRICTION(type)) { 18410 /* 18411 * SPEC (3.1) "If <restriction>..." 18412 * (3.1.1) + (3.1.2) */ 18413 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18414 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18415 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18416 } 18417 } else { 18418 /* 18419 * SPEC (3.2) "If <extension>..." 18420 */ 18421 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18422 /* 18423 * SPEC (3.2.1) 18424 * "If the `effective content` is empty, then the 18425 * {content type} of the [...] base ..." 18426 */ 18427 type->contentType = baseType->contentType; 18428 type->subtypes = baseType->subtypes; 18429 /* 18430 * Fixes bug #347316: 18431 * This is the case when the base type has a simple 18432 * type definition as content. 18433 */ 18434 type->contentTypeDef = baseType->contentTypeDef; 18435 /* 18436 * NOTE that the effective mixed is ignored here. 18437 */ 18438 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18439 /* 18440 * SPEC (3.2.2) 18441 */ 18442 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18443 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18444 } else { 18445 /* 18446 * SPEC (3.2.3) 18447 */ 18448 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18449 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18450 /* 18451 * "A model group whose {compositor} is sequence and whose 18452 * {particles} are..." 18453 */ 18454 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18455 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18456 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18457 XML_SCHEMA_TYPE_ALL)) 18458 { 18459 /* 18460 * SPEC cos-all-limited (1) 18461 */ 18462 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18463 /* TODO: error code */ 18464 XML_SCHEMAP_COS_ALL_LIMITED, 18465 WXS_ITEM_NODE(type), NULL, 18466 "The type has an 'all' model group in its " 18467 "{content type} and thus cannot be derived from " 18468 "a non-empty type, since this would produce a " 18469 "'sequence' model group containing the 'all' " 18470 "model group; 'all' model groups are not " 18471 "allowed to appear inside other model groups", 18472 NULL, NULL); 18473 18474 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18475 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18476 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18477 XML_SCHEMA_TYPE_ALL)) 18478 { 18479 /* 18480 * SPEC cos-all-limited (1) 18481 */ 18482 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18483 /* TODO: error code */ 18484 XML_SCHEMAP_COS_ALL_LIMITED, 18485 WXS_ITEM_NODE(type), NULL, 18486 "A type cannot be derived by extension from a type " 18487 "which has an 'all' model group in its " 18488 "{content type}, since this would produce a " 18489 "'sequence' model group containing the 'all' " 18490 "model group; 'all' model groups are not " 18491 "allowed to appear inside other model groups", 18492 NULL, NULL); 18493 18494 } else if (! dummySequence) { 18495 xmlSchemaTreeItemPtr effectiveContent = 18496 (xmlSchemaTreeItemPtr) type->subtypes; 18497 /* 18498 * Create the particle. 18499 */ 18500 particle = xmlSchemaAddParticle(pctxt, 18501 type->node, 1, 1); 18502 if (particle == NULL) 18503 goto exit_failure; 18504 /* 18505 * Create the "sequence" model group. 18506 */ 18507 particle->children = (xmlSchemaTreeItemPtr) 18508 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18509 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18510 if (particle->children == NULL) 18511 goto exit_failure; 18512 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18513 /* 18514 * SPEC "the particle of the {content type} of 18515 * the ... base ..." 18516 * Create a duplicate of the base type's particle 18517 * and assign its "term" to it. 18518 */ 18519 particle->children->children = 18520 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18521 type->node, 18522 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs, 18523 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs); 18524 if (particle->children->children == NULL) 18525 goto exit_failure; 18526 particle = (xmlSchemaParticlePtr) 18527 particle->children->children; 18528 particle->children = 18529 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18530 /* 18531 * SPEC "followed by the `effective content`." 18532 */ 18533 particle->next = effectiveContent; 18534 /* 18535 * This all will result in: 18536 * new-particle 18537 * --> new-sequence( 18538 * new-particle 18539 * --> base-model, 18540 * this-particle 18541 * --> this-model 18542 * ) 18543 */ 18544 } else { 18545 /* 18546 * This is the case when there is already an empty 18547 * <sequence> with minOccurs==maxOccurs==1. 18548 * Just add the base types's content type. 18549 * NOTE that, although we miss to add an intermediate 18550 * <sequence>, this should produce no difference to 18551 * neither the regex compilation of the content model, 18552 * nor to the complex type contraints. 18553 */ 18554 particle->children->children = 18555 (xmlSchemaTreeItemPtr) baseType->subtypes; 18556 } 18557 } 18558 } 18559 } 18560 /* 18561 * Now fixup attribute uses: 18562 * - expand attr. group references 18563 * - intersect attribute wildcards 18564 * - inherit attribute uses of the base type 18565 * - inherit or union attr. wildcards if extending 18566 * - apply attr. use prohibitions if restricting 18567 */ 18568 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18569 HFAILURE HERROR 18570 /* 18571 * Apply the complex type component constraints; this will not 18572 * check attributes, since this is done in 18573 * xmlSchemaFixupTypeAttributeUses(). 18574 */ 18575 res = xmlSchemaCheckCTComponent(pctxt, type); 18576 HFAILURE HERROR 18577 18578 #ifdef DEBUG_TYPE 18579 xmlSchemaDebugFixedType(pctxt, type); 18580 #endif 18581 if (olderrs != pctxt->nberrors) 18582 return(pctxt->err); 18583 else 18584 return(0); 18585 18586 exit_error: 18587 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18588 #ifdef DEBUG_TYPE 18589 xmlSchemaDebugFixedType(pctxt, type); 18590 #endif 18591 return(pctxt->err); 18592 18593 exit_failure: 18594 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18595 #ifdef DEBUG_TYPE 18596 xmlSchemaDebugFixedType(pctxt, type); 18597 #endif 18598 return(-1); 18599 } 18600 18601 18602 /** 18603 * xmlSchemaTypeFixup: 18604 * @typeDecl: the schema type definition 18605 * @ctxt: the schema parser context 18606 * 18607 * Fixes the content model of the type. 18608 * URGENT TODO: We need an int result! 18609 */ 18610 static int 18611 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18612 xmlSchemaAbstractCtxtPtr actxt) 18613 { 18614 if (type == NULL) 18615 return(0); 18616 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18617 AERROR_INT("xmlSchemaTypeFixup", 18618 "this function needs a parser context"); 18619 return(-1); 18620 } 18621 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18622 return(0); 18623 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18624 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18625 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18626 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18627 return(0); 18628 } 18629 18630 /** 18631 * xmlSchemaCheckFacet: 18632 * @facet: the facet 18633 * @typeDecl: the schema type definition 18634 * @pctxt: the schema parser context or NULL 18635 * @name: the optional name of the type 18636 * 18637 * Checks and computes the values of facets. 18638 * 18639 * Returns 0 if valid, a positive error code if not valid and 18640 * -1 in case of an internal or API error. 18641 */ 18642 int 18643 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18644 xmlSchemaTypePtr typeDecl, 18645 xmlSchemaParserCtxtPtr pctxt, 18646 const xmlChar * name ATTRIBUTE_UNUSED) 18647 { 18648 int ret = 0, ctxtGiven; 18649 18650 if ((facet == NULL) || (typeDecl == NULL)) 18651 return(-1); 18652 /* 18653 * TODO: will the parser context be given if used from 18654 * the relaxNG module? 18655 */ 18656 if (pctxt == NULL) 18657 ctxtGiven = 0; 18658 else 18659 ctxtGiven = 1; 18660 18661 switch (facet->type) { 18662 case XML_SCHEMA_FACET_MININCLUSIVE: 18663 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18664 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18665 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18666 case XML_SCHEMA_FACET_ENUMERATION: { 18667 /* 18668 * Okay we need to validate the value 18669 * at that point. 18670 */ 18671 xmlSchemaTypePtr base; 18672 18673 /* 4.3.5.5 Constraints on enumeration Schema Components 18674 * Schema Component Constraint: enumeration valid restriction 18675 * It is an `error` if any member of {value} is not in the 18676 * `value space` of {base type definition}. 18677 * 18678 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18679 * The value `must` be in the 18680 * `value space` of the `base type`. 18681 */ 18682 /* 18683 * This function is intended to deliver a compiled value 18684 * on the facet. In this implementation of XML Schemata the 18685 * type holding a facet, won't be a built-in type. 18686 * Thus to ensure that other API 18687 * calls (relaxng) do work, if the given type is a built-in 18688 * type, we will assume that the given built-in type *is 18689 * already* the base type. 18690 */ 18691 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18692 base = typeDecl->baseType; 18693 if (base == NULL) { 18694 PERROR_INT("xmlSchemaCheckFacet", 18695 "a type user derived type has no base type"); 18696 return (-1); 18697 } 18698 } else 18699 base = typeDecl; 18700 18701 if (! ctxtGiven) { 18702 /* 18703 * A context is needed if called from RelaxNG. 18704 */ 18705 pctxt = xmlSchemaNewParserCtxt("*"); 18706 if (pctxt == NULL) 18707 return (-1); 18708 } 18709 /* 18710 * NOTE: This call does not check the content nodes, 18711 * since they are not available: 18712 * facet->node is just the node holding the facet 18713 * definition, *not* the attribute holding the *value* 18714 * of the facet. 18715 */ 18716 ret = xmlSchemaVCheckCVCSimpleType( 18717 ACTXT_CAST pctxt, facet->node, base, 18718 facet->value, &(facet->val), 1, 1, 0); 18719 if (ret != 0) { 18720 if (ret < 0) { 18721 /* No error message for RelaxNG. */ 18722 if (ctxtGiven) { 18723 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18724 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18725 "Internal error: xmlSchemaCheckFacet, " 18726 "failed to validate the value '%s' of the " 18727 "facet '%s' against the base type", 18728 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18729 } 18730 goto internal_error; 18731 } 18732 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18733 /* No error message for RelaxNG. */ 18734 if (ctxtGiven) { 18735 xmlChar *str = NULL; 18736 18737 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18738 ret, facet->node, WXS_BASIC_CAST facet, 18739 "The value '%s' of the facet does not validate " 18740 "against the base type '%s'", 18741 facet->value, 18742 xmlSchemaFormatQName(&str, 18743 base->targetNamespace, base->name)); 18744 FREE_AND_NULL(str); 18745 } 18746 goto exit; 18747 } else if (facet->val == NULL) { 18748 if (ctxtGiven) { 18749 PERROR_INT("xmlSchemaCheckFacet", 18750 "value was not computed"); 18751 } 18752 TODO 18753 } 18754 break; 18755 } 18756 case XML_SCHEMA_FACET_PATTERN: 18757 facet->regexp = xmlRegexpCompile(facet->value); 18758 if (facet->regexp == NULL) { 18759 ret = XML_SCHEMAP_REGEXP_INVALID; 18760 /* No error message for RelaxNG. */ 18761 if (ctxtGiven) { 18762 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18763 ret, facet->node, WXS_BASIC_CAST typeDecl, 18764 "The value '%s' of the facet 'pattern' is not a " 18765 "valid regular expression", 18766 facet->value, NULL); 18767 } 18768 } 18769 break; 18770 case XML_SCHEMA_FACET_TOTALDIGITS: 18771 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18772 case XML_SCHEMA_FACET_LENGTH: 18773 case XML_SCHEMA_FACET_MAXLENGTH: 18774 case XML_SCHEMA_FACET_MINLENGTH: 18775 18776 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18777 ret = xmlSchemaValidatePredefinedType( 18778 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18779 facet->value, &(facet->val)); 18780 } else { 18781 ret = xmlSchemaValidatePredefinedType( 18782 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18783 facet->value, &(facet->val)); 18784 } 18785 if (ret != 0) { 18786 if (ret < 0) { 18787 /* No error message for RelaxNG. */ 18788 if (ctxtGiven) { 18789 PERROR_INT("xmlSchemaCheckFacet", 18790 "validating facet value"); 18791 } 18792 goto internal_error; 18793 } 18794 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18795 /* No error message for RelaxNG. */ 18796 if (ctxtGiven) { 18797 /* error code */ 18798 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18799 ret, facet->node, WXS_BASIC_CAST typeDecl, 18800 "The value '%s' of the facet '%s' is not a valid '%s'", 18801 facet->value, 18802 xmlSchemaFacetTypeToString(facet->type), 18803 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18804 BAD_CAST "nonNegativeInteger" : 18805 BAD_CAST "positiveInteger", 18806 NULL); 18807 } 18808 } 18809 break; 18810 18811 case XML_SCHEMA_FACET_WHITESPACE:{ 18812 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18813 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18814 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18815 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18816 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18817 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18818 } else { 18819 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18820 /* No error message for RelaxNG. */ 18821 if (ctxtGiven) { 18822 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18823 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18824 ret, facet->node, WXS_BASIC_CAST typeDecl, 18825 "The value '%s' of the facet 'whitespace' is not " 18826 "valid", facet->value, NULL); 18827 } 18828 } 18829 } 18830 default: 18831 break; 18832 } 18833 exit: 18834 if ((! ctxtGiven) && (pctxt != NULL)) 18835 xmlSchemaFreeParserCtxt(pctxt); 18836 return (ret); 18837 internal_error: 18838 if ((! ctxtGiven) && (pctxt != NULL)) 18839 xmlSchemaFreeParserCtxt(pctxt); 18840 return (-1); 18841 } 18842 18843 /** 18844 * xmlSchemaCheckFacetValues: 18845 * @typeDecl: the schema type definition 18846 * @ctxt: the schema parser context 18847 * 18848 * Checks the default values types, especially for facets 18849 */ 18850 static int 18851 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18852 xmlSchemaParserCtxtPtr pctxt) 18853 { 18854 int res, olderrs = pctxt->nberrors; 18855 const xmlChar *name = typeDecl->name; 18856 /* 18857 * NOTE: It is intended to use the facets list, instead 18858 * of facetSet. 18859 */ 18860 if (typeDecl->facets != NULL) { 18861 xmlSchemaFacetPtr facet = typeDecl->facets; 18862 18863 /* 18864 * Temporarily assign the "schema" to the validation context 18865 * of the parser context. This is needed for NOTATION validation. 18866 */ 18867 if (pctxt->vctxt == NULL) { 18868 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18869 return(-1); 18870 } 18871 pctxt->vctxt->schema = pctxt->schema; 18872 while (facet != NULL) { 18873 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18874 HFAILURE 18875 facet = facet->next; 18876 } 18877 pctxt->vctxt->schema = NULL; 18878 } 18879 if (olderrs != pctxt->nberrors) 18880 return(pctxt->err); 18881 return(0); 18882 exit_failure: 18883 return(-1); 18884 } 18885 18886 /** 18887 * xmlSchemaGetCircModelGrDefRef: 18888 * @ctxtMGroup: the searched model group 18889 * @selfMGroup: the second searched model group 18890 * @particle: the first particle 18891 * 18892 * This one is intended to be used by 18893 * xmlSchemaCheckGroupDefCircular only. 18894 * 18895 * Returns the particle with the circular model group definition reference, 18896 * otherwise NULL. 18897 */ 18898 static xmlSchemaTreeItemPtr 18899 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18900 xmlSchemaTreeItemPtr particle) 18901 { 18902 xmlSchemaTreeItemPtr circ = NULL; 18903 xmlSchemaTreeItemPtr term; 18904 xmlSchemaModelGroupDefPtr gdef; 18905 18906 for (; particle != NULL; particle = particle->next) { 18907 term = particle->children; 18908 if (term == NULL) 18909 continue; 18910 switch (term->type) { 18911 case XML_SCHEMA_TYPE_GROUP: 18912 gdef = (xmlSchemaModelGroupDefPtr) term; 18913 if (gdef == groupDef) 18914 return (particle); 18915 /* 18916 * Mark this model group definition to avoid infinite 18917 * recursion on circular references not yet examined. 18918 */ 18919 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18920 continue; 18921 if (gdef->children != NULL) { 18922 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18923 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18924 gdef->children->children); 18925 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18926 if (circ != NULL) 18927 return (circ); 18928 } 18929 break; 18930 case XML_SCHEMA_TYPE_SEQUENCE: 18931 case XML_SCHEMA_TYPE_CHOICE: 18932 case XML_SCHEMA_TYPE_ALL: 18933 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18934 if (circ != NULL) 18935 return (circ); 18936 break; 18937 default: 18938 break; 18939 } 18940 } 18941 return (NULL); 18942 } 18943 18944 /** 18945 * xmlSchemaCheckGroupDefCircular: 18946 * @item: the model group definition 18947 * @ctxt: the parser context 18948 * @name: the name 18949 * 18950 * Checks for circular references to model group definitions. 18951 */ 18952 static void 18953 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18954 xmlSchemaParserCtxtPtr ctxt) 18955 { 18956 /* 18957 * Schema Component Constraint: Model Group Correct 18958 * 2 Circular groups are disallowed. That is, within the {particles} 18959 * of a group there must not be at any depth a particle whose {term} 18960 * is the group itself. 18961 */ 18962 if ((item == NULL) || 18963 (item->type != XML_SCHEMA_TYPE_GROUP) || 18964 (item->children == NULL)) 18965 return; 18966 { 18967 xmlSchemaTreeItemPtr circ; 18968 18969 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18970 if (circ != NULL) { 18971 xmlChar *str = NULL; 18972 /* 18973 * TODO: The error report is not adequate: this constraint 18974 * is defined for model groups but not definitions, but since 18975 * there cannot be any circular model groups without a model group 18976 * definition (if not using a construction API), we check those 18977 * defintions only. 18978 */ 18979 xmlSchemaPCustomErr(ctxt, 18980 XML_SCHEMAP_MG_PROPS_CORRECT_2, 18981 NULL, WXS_ITEM_NODE(circ), 18982 "Circular reference to the model group definition '%s' " 18983 "defined", xmlSchemaFormatQName(&str, 18984 item->targetNamespace, item->name)); 18985 FREE_AND_NULL(str) 18986 /* 18987 * NOTE: We will cut the reference to avoid further 18988 * confusion of the processor. This is a fatal error. 18989 */ 18990 circ->children = NULL; 18991 } 18992 } 18993 } 18994 18995 /** 18996 * xmlSchemaModelGroupToModelGroupDefFixup: 18997 * @ctxt: the parser context 18998 * @mg: the model group 18999 * 19000 * Assigns the model group of model group definitions to the "term" 19001 * of the referencing particle. 19002 * In xmlSchemaResolveModelGroupParticleReferences the model group 19003 * definitions were assigned to the "term", since needed for the 19004 * circularity check. 19005 * 19006 * Schema Component Constraint: 19007 * All Group Limited (cos-all-limited) (1.2) 19008 */ 19009 static void 19010 xmlSchemaModelGroupToModelGroupDefFixup( 19011 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 19012 xmlSchemaModelGroupPtr mg) 19013 { 19014 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19015 19016 while (particle != NULL) { 19017 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19018 ((WXS_PARTICLE_TERM(particle))->type != 19019 XML_SCHEMA_TYPE_GROUP)) 19020 { 19021 particle = WXS_PTC_CAST particle->next; 19022 continue; 19023 } 19024 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 19025 /* 19026 * TODO: Remove the particle. 19027 */ 19028 WXS_PARTICLE_TERM(particle) = NULL; 19029 particle = WXS_PTC_CAST particle->next; 19030 continue; 19031 } 19032 /* 19033 * Assign the model group to the {term} of the particle. 19034 */ 19035 WXS_PARTICLE_TERM(particle) = 19036 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 19037 19038 particle = WXS_PTC_CAST particle->next; 19039 } 19040 } 19041 19042 /** 19043 * xmlSchemaCheckAttrGroupCircularRecur: 19044 * @ctxtGr: the searched attribute group 19045 * @attr: the current attribute list to be processed 19046 * 19047 * This one is intended to be used by 19048 * xmlSchemaCheckAttrGroupCircular only. 19049 * 19050 * Returns the circular attribute grou reference, otherwise NULL. 19051 */ 19052 static xmlSchemaQNameRefPtr 19053 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19054 xmlSchemaItemListPtr list) 19055 { 19056 xmlSchemaAttributeGroupPtr gr; 19057 xmlSchemaQNameRefPtr ref, circ; 19058 int i; 19059 /* 19060 * We will search for an attribute group reference which 19061 * references the context attribute group. 19062 */ 19063 for (i = 0; i < list->nbItems; i++) { 19064 ref = list->items[i]; 19065 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19066 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 19067 (ref->item != NULL)) 19068 { 19069 gr = WXS_ATTR_GROUP_CAST ref->item; 19070 if (gr == ctxtGr) 19071 return(ref); 19072 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED) 19073 continue; 19074 /* 19075 * Mark as visited to avoid infinite recursion on 19076 * circular references not yet examined. 19077 */ 19078 if ((gr->attrUses) && 19079 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)) 19080 { 19081 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED; 19082 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr, 19083 (xmlSchemaItemListPtr) gr->attrUses); 19084 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED; 19085 if (circ != NULL) 19086 return (circ); 19087 } 19088 19089 } 19090 } 19091 return (NULL); 19092 } 19093 19094 /** 19095 * xmlSchemaCheckAttrGroupCircular: 19096 * attrGr: the attribute group definition 19097 * @ctxt: the parser context 19098 * @name: the name 19099 * 19100 * Checks for circular references of attribute groups. 19101 */ 19102 static int 19103 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr, 19104 xmlSchemaParserCtxtPtr ctxt) 19105 { 19106 /* 19107 * Schema Representation Constraint: 19108 * Attribute Group Definition Representation OK 19109 * 3 Circular group reference is disallowed outside <redefine>. 19110 * That is, unless this element information item's parent is 19111 * <redefine>, then among the [children], if any, there must 19112 * not be an <attributeGroup> with ref [attribute] which resolves 19113 * to the component corresponding to this <attributeGroup>. Indirect 19114 * circularity is also ruled out. That is, when QName resolution 19115 * (Schema Document) ($3.15.3) is applied to a `QName` arising from 19116 * any <attributeGroup>s with a ref [attribute] among the [children], 19117 * it must not be the case that a `QName` is encountered at any depth 19118 * which resolves to the component corresponding to this <attributeGroup>. 19119 */ 19120 if (attrGr->attrUses == NULL) 19121 return(0); 19122 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0) 19123 return(0); 19124 else { 19125 xmlSchemaQNameRefPtr circ; 19126 19127 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr, 19128 (xmlSchemaItemListPtr) attrGr->attrUses); 19129 if (circ != NULL) { 19130 xmlChar *str = NULL; 19131 /* 19132 * TODO: Report the referenced attr group as QName. 19133 */ 19134 xmlSchemaPCustomErr(ctxt, 19135 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, 19136 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ), 19137 "Circular reference to the attribute group '%s' " 19138 "defined", xmlSchemaGetComponentQName(&str, attrGr)); 19139 FREE_AND_NULL(str); 19140 /* 19141 * NOTE: We will cut the reference to avoid further 19142 * confusion of the processor. 19143 * BADSPEC TODO: The spec should define how to process in this case. 19144 */ 19145 circ->item = NULL; 19146 return(ctxt->err); 19147 } 19148 } 19149 return(0); 19150 } 19151 19152 static int 19153 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19154 xmlSchemaAttributeGroupPtr attrGr); 19155 19156 /** 19157 * xmlSchemaExpandAttributeGroupRefs: 19158 * @pctxt: the parser context 19159 * @node: the node of the component holding the attribute uses 19160 * @completeWild: the intersected wildcard to be returned 19161 * @list: the attribute uses 19162 * 19163 * Substitutes contained attribute group references 19164 * for their attribute uses. Wilcards are intersected. 19165 * Attribute use prohibitions are removed from the list 19166 * and returned via the @prohibs list. 19167 * Pointlessness of attr. prohibs, if a matching attr. decl 19168 * is existent a well, are checked. 19169 */ 19170 static int 19171 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 19172 xmlSchemaBasicItemPtr item, 19173 xmlSchemaWildcardPtr *completeWild, 19174 xmlSchemaItemListPtr list, 19175 xmlSchemaItemListPtr prohibs) 19176 { 19177 xmlSchemaAttributeGroupPtr gr; 19178 xmlSchemaAttributeUsePtr use; 19179 xmlSchemaItemListPtr sublist; 19180 int i, j; 19181 int created = (*completeWild == NULL) ? 0 : 1; 19182 19183 if (prohibs) 19184 prohibs->nbItems = 0; 19185 19186 for (i = 0; i < list->nbItems; i++) { 19187 use = list->items[i]; 19188 19189 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 19190 if (prohibs == NULL) { 19191 PERROR_INT("xmlSchemaExpandAttributeGroupRefs", 19192 "unexpected attr prohibition found"); 19193 return(-1); 19194 } 19195 /* 19196 * Remove from attribute uses. 19197 */ 19198 if (xmlSchemaItemListRemove(list, i) == -1) 19199 return(-1); 19200 i--; 19201 /* 19202 * Note that duplicate prohibitions were already 19203 * handled at parsing time. 19204 */ 19205 /* 19206 * Add to list of prohibitions. 19207 */ 19208 xmlSchemaItemListAddSize(prohibs, 2, use); 19209 continue; 19210 } 19211 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) && 19212 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP)) 19213 { 19214 if ((WXS_QNAME_CAST use)->item == NULL) 19215 return(-1); 19216 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item; 19217 /* 19218 * Expand the referenced attr. group. 19219 * TODO: remove this, this is done in a previous step, so 19220 * already done here. 19221 */ 19222 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { 19223 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1) 19224 return(-1); 19225 } 19226 /* 19227 * Build the 'complete' wildcard; i.e. intersect multiple 19228 * wildcards. 19229 */ 19230 if (gr->attributeWildcard != NULL) { 19231 if (*completeWild == NULL) { 19232 *completeWild = gr->attributeWildcard; 19233 } else { 19234 if (! created) { 19235 xmlSchemaWildcardPtr tmpWild; 19236 19237 /* 19238 * Copy the first encountered wildcard as context, 19239 * except for the annotation. 19240 * 19241 * Although the complete wildcard might not correspond 19242 * to any node in the schema, we will anchor it on 19243 * the node of the owner component. 19244 */ 19245 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema, 19246 XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 19247 WXS_ITEM_NODE(item)); 19248 if (tmpWild == NULL) 19249 return(-1); 19250 if (xmlSchemaCloneWildcardNsConstraints(pctxt, 19251 tmpWild, *completeWild) == -1) 19252 return (-1); 19253 tmpWild->processContents = (*completeWild)->processContents; 19254 *completeWild = tmpWild; 19255 created = 1; 19256 } 19257 19258 if (xmlSchemaIntersectWildcards(pctxt, *completeWild, 19259 gr->attributeWildcard) == -1) 19260 return(-1); 19261 } 19262 } 19263 /* 19264 * Just remove the reference if the referenced group does not 19265 * contain any attribute uses. 19266 */ 19267 sublist = ((xmlSchemaItemListPtr) gr->attrUses); 19268 if ((sublist == NULL) || sublist->nbItems == 0) { 19269 if (xmlSchemaItemListRemove(list, i) == -1) 19270 return(-1); 19271 i--; 19272 continue; 19273 } 19274 /* 19275 * Add the attribute uses. 19276 */ 19277 list->items[i] = sublist->items[0]; 19278 if (sublist->nbItems != 1) { 19279 for (j = 1; j < sublist->nbItems; j++) { 19280 i++; 19281 if (xmlSchemaItemListInsert(list, 19282 sublist->items[j], i) == -1) 19283 return(-1); 19284 } 19285 } 19286 } 19287 19288 } 19289 /* 19290 * Handle pointless prohibitions of declared attributes. 19291 */ 19292 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) { 19293 xmlSchemaAttributeUseProhibPtr prohib; 19294 19295 for (i = prohibs->nbItems -1; i >= 0; i--) { 19296 prohib = prohibs->items[i]; 19297 for (j = 0; j < list->nbItems; j++) { 19298 use = list->items[j]; 19299 19300 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) && 19301 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use))) 19302 { 19303 xmlChar *str = NULL; 19304 19305 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 19306 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 19307 prohib->node, NULL, 19308 "Skipping pointless attribute use prohibition " 19309 "'%s', since a corresponding attribute use " 19310 "exists already in the type definition", 19311 xmlSchemaFormatQName(&str, 19312 prohib->targetNamespace, prohib->name), 19313 NULL, NULL); 19314 FREE_AND_NULL(str); 19315 /* 19316 * Remove the prohibition. 19317 */ 19318 if (xmlSchemaItemListRemove(prohibs, i) == -1) 19319 return(-1); 19320 break; 19321 } 19322 } 19323 } 19324 } 19325 return(0); 19326 } 19327 19328 /** 19329 * xmlSchemaAttributeGroupExpandRefs: 19330 * @pctxt: the parser context 19331 * @attrGr: the attribute group definition 19332 * 19333 * Computation of: 19334 * {attribute uses} property 19335 * {attribute wildcard} property 19336 * 19337 * Substitutes contained attribute group references 19338 * for their attribute uses. Wilcards are intersected. 19339 */ 19340 static int 19341 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt, 19342 xmlSchemaAttributeGroupPtr attrGr) 19343 { 19344 if ((attrGr->attrUses == NULL) || 19345 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)) 19346 return(0); 19347 19348 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; 19349 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr, 19350 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1) 19351 return(-1); 19352 return(0); 19353 } 19354 19355 /** 19356 * xmlSchemaAttributeGroupExpandRefs: 19357 * @pctxt: the parser context 19358 * @attrGr: the attribute group definition 19359 * 19360 * Substitutes contained attribute group references 19361 * for their attribute uses. Wilcards are intersected. 19362 * 19363 * Schema Component Constraint: 19364 * Attribute Group Definition Properties Correct (ag-props-correct) 19365 */ 19366 static int 19367 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19368 xmlSchemaAttributeGroupPtr attrGr) 19369 { 19370 /* 19371 * SPEC ag-props-correct 19372 * (1) "The values of the properties of an attribute group definition 19373 * must be as described in the property tableau in The Attribute 19374 * Group Definition Schema Component ($3.6.1), modulo the impact of 19375 * Missing Sub-components ($5.3);" 19376 */ 19377 19378 if ((attrGr->attrUses != NULL) && 19379 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1) 19380 { 19381 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses; 19382 xmlSchemaAttributeUsePtr use, tmp; 19383 int i, j, hasId = 0; 19384 19385 for (i = uses->nbItems -1; i >= 0; i--) { 19386 use = uses->items[i]; 19387 /* 19388 * SPEC ag-props-correct 19389 * (2) "Two distinct members of the {attribute uses} must not have 19390 * {attribute declaration}s both of whose {name}s match and whose 19391 * {target namespace}s are identical." 19392 */ 19393 if (i > 0) { 19394 for (j = i -1; j >= 0; j--) { 19395 tmp = uses->items[j]; 19396 if ((WXS_ATTRUSE_DECL_NAME(use) == 19397 WXS_ATTRUSE_DECL_NAME(tmp)) && 19398 (WXS_ATTRUSE_DECL_TNS(use) == 19399 WXS_ATTRUSE_DECL_TNS(tmp))) 19400 { 19401 xmlChar *str = NULL; 19402 19403 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19404 XML_SCHEMAP_AG_PROPS_CORRECT, 19405 attrGr->node, WXS_BASIC_CAST attrGr, 19406 "Duplicate %s", 19407 xmlSchemaGetComponentDesignation(&str, use), 19408 NULL); 19409 FREE_AND_NULL(str); 19410 /* 19411 * Remove the duplicate. 19412 */ 19413 if (xmlSchemaItemListRemove(uses, i) == -1) 19414 return(-1); 19415 goto next_use; 19416 } 19417 } 19418 } 19419 /* 19420 * SPEC ag-props-correct 19421 * (3) "Two distinct members of the {attribute uses} must not have 19422 * {attribute declaration}s both of whose {type definition}s are or 19423 * are derived from ID." 19424 * TODO: Does 'derived' include member-types of unions? 19425 */ 19426 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 19427 if (xmlSchemaIsDerivedFromBuiltInType( 19428 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 19429 { 19430 if (hasId) { 19431 xmlChar *str = NULL; 19432 19433 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19434 XML_SCHEMAP_AG_PROPS_CORRECT, 19435 attrGr->node, WXS_BASIC_CAST attrGr, 19436 "There must not exist more than one attribute " 19437 "declaration of type 'xs:ID' " 19438 "(or derived from 'xs:ID'). The %s violates this " 19439 "constraint", 19440 xmlSchemaGetComponentDesignation(&str, use), 19441 NULL); 19442 FREE_AND_NULL(str); 19443 if (xmlSchemaItemListRemove(uses, i) == -1) 19444 return(-1); 19445 } 19446 hasId = 1; 19447 } 19448 } 19449 next_use: {} 19450 } 19451 } 19452 return(0); 19453 } 19454 19455 /** 19456 * xmlSchemaResolveAttrGroupReferences: 19457 * @attrgrpDecl: the schema attribute definition 19458 * @ctxt: the schema parser context 19459 * @name: the attribute name 19460 * 19461 * Resolves references to attribute group definitions. 19462 */ 19463 static int 19464 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref, 19465 xmlSchemaParserCtxtPtr ctxt) 19466 { 19467 xmlSchemaAttributeGroupPtr group; 19468 19469 if (ref->item != NULL) 19470 return(0); 19471 group = xmlSchemaGetAttributeGroup(ctxt->schema, 19472 ref->name, 19473 ref->targetNamespace); 19474 if (group == NULL) { 19475 xmlSchemaPResCompAttrErr(ctxt, 19476 XML_SCHEMAP_SRC_RESOLVE, 19477 NULL, ref->node, 19478 "ref", ref->name, ref->targetNamespace, 19479 ref->itemType, NULL); 19480 return(ctxt->err); 19481 } 19482 ref->item = WXS_BASIC_CAST group; 19483 return(0); 19484 } 19485 19486 /** 19487 * xmlSchemaCheckAttrPropsCorrect: 19488 * @item: an schema attribute declaration/use 19489 * @ctxt: a schema parser context 19490 * @name: the name of the attribute 19491 * 19492 * 19493 * Schema Component Constraint: 19494 * Attribute Declaration Properties Correct (a-props-correct) 19495 * 19496 * Validates the value constraints of an attribute declaration/use. 19497 * NOTE that this needs the simle type definitions to be already 19498 * builded and checked. 19499 */ 19500 static int 19501 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19502 xmlSchemaAttributePtr attr) 19503 { 19504 19505 /* 19506 * SPEC a-props-correct (1) 19507 * "The values of the properties of an attribute declaration must 19508 * be as described in the property tableau in The Attribute 19509 * Declaration Schema Component ($3.2.1), modulo the impact of 19510 * Missing Sub-components ($5.3)." 19511 */ 19512 19513 if (WXS_ATTR_TYPEDEF(attr) == NULL) 19514 return(0); 19515 19516 if (attr->defValue != NULL) { 19517 int ret; 19518 19519 /* 19520 * SPEC a-props-correct (3) 19521 * "If the {type definition} is or is derived from ID then there 19522 * must not be a {value constraint}." 19523 */ 19524 if (xmlSchemaIsDerivedFromBuiltInType( 19525 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID)) 19526 { 19527 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19528 XML_SCHEMAP_A_PROPS_CORRECT_3, 19529 NULL, WXS_BASIC_CAST attr, 19530 "Value constraints are not allowed if the type definition " 19531 "is or is derived from xs:ID", 19532 NULL, NULL); 19533 return(pctxt->err); 19534 } 19535 /* 19536 * SPEC a-props-correct (2) 19537 * "if there is a {value constraint}, the canonical lexical 19538 * representation of its value must be `valid` with respect 19539 * to the {type definition} as defined in String Valid ($3.14.4)." 19540 * TODO: Don't care about the *canonical* stuff here, this requirement 19541 * will be removed in WXS 1.1 anyway. 19542 */ 19543 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, 19544 attr->node, WXS_ATTR_TYPEDEF(attr), 19545 attr->defValue, &(attr->defVal), 19546 1, 1, 0); 19547 if (ret != 0) { 19548 if (ret < 0) { 19549 PERROR_INT("xmlSchemaCheckAttrPropsCorrect", 19550 "calling xmlSchemaVCheckCVCSimpleType()"); 19551 return(-1); 19552 } 19553 xmlSchemaCustomErr(ACTXT_CAST pctxt, 19554 XML_SCHEMAP_A_PROPS_CORRECT_2, 19555 NULL, WXS_BASIC_CAST attr, 19556 "The value of the value constraint is not valid", 19557 NULL, NULL); 19558 return(pctxt->err); 19559 } 19560 } 19561 19562 return(0); 19563 } 19564 19565 static xmlSchemaElementPtr 19566 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl, 19567 xmlSchemaElementPtr ancestor) 19568 { 19569 xmlSchemaElementPtr ret; 19570 19571 if (WXS_SUBST_HEAD(ancestor) == NULL) 19572 return (NULL); 19573 if (WXS_SUBST_HEAD(ancestor) == elemDecl) 19574 return (ancestor); 19575 19576 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR) 19577 return (NULL); 19578 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR; 19579 ret = xmlSchemaCheckSubstGroupCircular(elemDecl, 19580 WXS_SUBST_HEAD(ancestor)); 19581 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR; 19582 19583 return (ret); 19584 } 19585 19586 /** 19587 * xmlSchemaCheckElemPropsCorrect: 19588 * @ctxt: a schema parser context 19589 * @decl: the element declaration 19590 * @name: the name of the attribute 19591 * 19592 * Schema Component Constraint: 19593 * Element Declaration Properties Correct (e-props-correct) 19594 * 19595 * STATUS: 19596 * missing: (6) 19597 */ 19598 static int 19599 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 19600 xmlSchemaElementPtr elemDecl) 19601 { 19602 int ret = 0; 19603 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl); 19604 /* 19605 * SPEC (1) "The values of the properties of an element declaration 19606 * must be as described in the property tableau in The Element 19607 * Declaration Schema Component ($3.3.1), modulo the impact of Missing 19608 * Sub-components ($5.3)." 19609 */ 19610 if (WXS_SUBST_HEAD(elemDecl) != NULL) { 19611 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ; 19612 19613 xmlSchemaCheckElementDeclComponent(head, pctxt); 19614 /* 19615 * SPEC (3) "If there is a non-`absent` {substitution group 19616 * affiliation}, then {scope} must be global." 19617 */ 19618 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) { 19619 xmlSchemaPCustomErr(pctxt, 19620 XML_SCHEMAP_E_PROPS_CORRECT_3, 19621 WXS_BASIC_CAST elemDecl, NULL, 19622 "Only global element declarations can have a " 19623 "substitution group affiliation", NULL); 19624 ret = XML_SCHEMAP_E_PROPS_CORRECT_3; 19625 } 19626 /* 19627 * TODO: SPEC (6) "Circular substitution groups are disallowed. 19628 * That is, it must not be possible to return to an element declaration 19629 * by repeatedly following the {substitution group affiliation} 19630 * property." 19631 */ 19632 if (head == elemDecl) 19633 circ = head; 19634 else if (WXS_SUBST_HEAD(head) != NULL) 19635 circ = xmlSchemaCheckSubstGroupCircular(head, head); 19636 else 19637 circ = NULL; 19638 if (circ != NULL) { 19639 xmlChar *strA = NULL, *strB = NULL; 19640 19641 xmlSchemaPCustomErrExt(pctxt, 19642 XML_SCHEMAP_E_PROPS_CORRECT_6, 19643 WXS_BASIC_CAST circ, NULL, 19644 "The element declaration '%s' defines a circular " 19645 "substitution group to element declaration '%s'", 19646 xmlSchemaGetComponentQName(&strA, circ), 19647 xmlSchemaGetComponentQName(&strB, head), 19648 NULL); 19649 FREE_AND_NULL(strA) 19650 FREE_AND_NULL(strB) 19651 ret = XML_SCHEMAP_E_PROPS_CORRECT_6; 19652 } 19653 /* 19654 * SPEC (4) "If there is a {substitution group affiliation}, 19655 * the {type definition} 19656 * of the element declaration must be validly derived from the {type 19657 * definition} of the {substitution group affiliation}, given the value 19658 * of the {substitution group exclusions} of the {substitution group 19659 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6) 19660 * (if the {type definition} is complex) or as defined in 19661 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is 19662 * simple)." 19663 * 19664 * NOTE: {substitution group exclusions} means the values of the 19665 * attribute "final". 19666 */ 19667 19668 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) { 19669 int set = 0; 19670 19671 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION) 19672 set |= SUBSET_EXTENSION; 19673 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION) 19674 set |= SUBSET_RESTRICTION; 19675 19676 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef, 19677 WXS_ELEM_TYPEDEF(head), set) != 0) { 19678 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 19679 19680 ret = XML_SCHEMAP_E_PROPS_CORRECT_4; 19681 xmlSchemaPCustomErrExt(pctxt, 19682 XML_SCHEMAP_E_PROPS_CORRECT_4, 19683 WXS_BASIC_CAST elemDecl, NULL, 19684 "The type definition '%s' was " 19685 "either rejected by the substitution group " 19686 "affiliation '%s', or not validly derived from its type " 19687 "definition '%s'", 19688 xmlSchemaGetComponentQName(&strA, typeDef), 19689 xmlSchemaGetComponentQName(&strB, head), 19690 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head))); 19691 FREE_AND_NULL(strA) 19692 FREE_AND_NULL(strB) 19693 FREE_AND_NULL(strC) 19694 } 19695 } 19696 } 19697 /* 19698 * SPEC (5) "If the {type definition} or {type definition}'s 19699 * {content type} 19700 * is or is derived from ID then there must not be a {value constraint}. 19701 * Note: The use of ID as a type definition for elements goes beyond 19702 * XML 1.0, and should be avoided if backwards compatibility is desired" 19703 */ 19704 if ((elemDecl->value != NULL) && 19705 ((WXS_IS_SIMPLE(typeDef) && 19706 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) || 19707 (WXS_IS_COMPLEX(typeDef) && 19708 WXS_HAS_SIMPLE_CONTENT(typeDef) && 19709 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef, 19710 XML_SCHEMAS_ID)))) { 19711 19712 ret = XML_SCHEMAP_E_PROPS_CORRECT_5; 19713 xmlSchemaPCustomErr(pctxt, 19714 XML_SCHEMAP_E_PROPS_CORRECT_5, 19715 WXS_BASIC_CAST elemDecl, NULL, 19716 "The type definition (or type definition's content type) is or " 19717 "is derived from ID; value constraints are not allowed in " 19718 "conjunction with such a type definition", NULL); 19719 } else if (elemDecl->value != NULL) { 19720 int vcret; 19721 xmlNodePtr node = NULL; 19722 19723 /* 19724 * SPEC (2) "If there is a {value constraint}, the canonical lexical 19725 * representation of its value must be `valid` with respect to the 19726 * {type definition} as defined in Element Default Valid (Immediate) 19727 * ($3.3.6)." 19728 */ 19729 if (typeDef == NULL) { 19730 xmlSchemaPErr(pctxt, elemDecl->node, 19731 XML_SCHEMAP_INTERNAL, 19732 "Internal error: xmlSchemaCheckElemPropsCorrect, " 19733 "type is missing... skipping validation of " 19734 "the value constraint", NULL, NULL); 19735 return (-1); 19736 } 19737 if (elemDecl->node != NULL) { 19738 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) 19739 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19740 BAD_CAST "fixed"); 19741 else 19742 node = (xmlNodePtr) xmlHasProp(elemDecl->node, 19743 BAD_CAST "default"); 19744 } 19745 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node, 19746 typeDef, elemDecl->value, &(elemDecl->defVal)); 19747 if (vcret != 0) { 19748 if (vcret < 0) { 19749 PERROR_INT("xmlSchemaElemCheckValConstr", 19750 "failed to validate the value constraint of an " 19751 "element declaration"); 19752 return (-1); 19753 } 19754 return (vcret); 19755 } 19756 } 19757 19758 return (ret); 19759 } 19760 19761 /** 19762 * xmlSchemaCheckElemSubstGroup: 19763 * @ctxt: a schema parser context 19764 * @decl: the element declaration 19765 * @name: the name of the attribute 19766 * 19767 * Schema Component Constraint: 19768 * Substitution Group (cos-equiv-class) 19769 * 19770 * In Libxml2 the subst. groups will be precomputed, in terms of that 19771 * a list will be built for each subst. group head, holding all direct 19772 * referents to this head. 19773 * NOTE that this function needs: 19774 * 1. circular subst. groups to be checked beforehand 19775 * 2. the declaration's type to be derived from the head's type 19776 * 19777 * STATUS: 19778 * 19779 */ 19780 static void 19781 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt, 19782 xmlSchemaElementPtr elemDecl) 19783 { 19784 if ((WXS_SUBST_HEAD(elemDecl) == NULL) || 19785 /* SPEC (1) "Its {abstract} is false." */ 19786 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)) 19787 return; 19788 { 19789 xmlSchemaElement