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 48 /* To avoid EBCDIC trouble when parsing on zOS */ 49 #if defined(__MVS__) 50 #pragma convert("ISO8859-1") 51 #endif 52 53 #define IN_LIBXML 54 #include "libxml.h" 55 56 #ifdef LIBXML_SCHEMAS_ENABLED 57 58 #include <string.h> 59 #include <libxml/xmlmemory.h> 60 #include <libxml/parser.h> 61 #include <libxml/parserInternals.h> 62 #include <libxml/hash.h> 63 #include <libxml/uri.h> 64 #include <libxml/xmlschemas.h> 65 #include <libxml/schemasInternals.h> 66 #include <libxml/xmlschemastypes.h> 67 #include <libxml/xmlautomata.h> 68 #include <libxml/xmlregexp.h> 69 #include <libxml/dict.h> 70 #include <libxml/encoding.h> 71 #include <libxml/xmlIO.h> 72 #ifdef LIBXML_PATTERN_ENABLED 73 #include <libxml/pattern.h> 74 #endif 75 #ifdef LIBXML_READER_ENABLED 76 #include <libxml/xmlreader.h> 77 #endif 78 79 /* #define DEBUG 1 */ 80 81 /* #define DEBUG_CONTENT 1 */ 82 83 /* #define DEBUG_TYPE 1 */ 84 85 /* #define DEBUG_CONTENT_REGEXP 1 */ 86 87 /* #define DEBUG_AUTOMATA 1 */ 88 89 /* #define DEBUG_IDC */ 90 91 /* #define DEBUG_IDC_NODE_TABLE */ 92 93 /* #define WXS_ELEM_DECL_CONS_ENABLED */ 94 95 #ifdef DEBUG_IDC 96 #ifndef DEBUG_IDC_NODE_TABLE 97 #define DEBUG_IDC_NODE_TABLE 98 #endif 99 #endif 100 101 /* #define ENABLE_PARTICLE_RESTRICTION 1 */ 102 103 #define ENABLE_REDEFINE 104 105 /* #define ENABLE_NAMED_LOCALS */ 106 107 /* #define ENABLE_IDC_NODE_TABLES_TEST */ 108 109 #define DUMP_CONTENT_MODEL 110 111 #ifdef LIBXML_READER_ENABLED 112 /* #define XML_SCHEMA_READER_ENABLED */ 113 #endif 114 115 #define UNBOUNDED (1 << 30) 116 #define TODO \ 117 xmlGenericError(xmlGenericErrorContext, \ 118 "Unimplemented block at %s:%d\n", \ 119 __FILE__, __LINE__); 120 121 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##" 122 123 /* 124 * The XML Schemas namespaces 125 */ 126 static const xmlChar *xmlSchemaNs = (const xmlChar *) 127 "http://www.w3.org/2001/XMLSchema"; 128 129 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *) 130 "http://www.w3.org/2001/XMLSchema-instance"; 131 132 static const xmlChar *xmlNamespaceNs = (const xmlChar *) 133 "http://www.w3.org/2000/xmlns/"; 134 135 /* 136 * Come casting macros. 137 */ 138 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr) 139 #define PCTXT_CAST (xmlSchemaParserCtxtPtr) 140 #define VCTXT_CAST (xmlSchemaValidCtxtPtr) 141 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr) 142 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr) 143 #define WXS_PTC_CAST (xmlSchemaParticlePtr) 144 #define WXS_TYPE_CAST (xmlSchemaTypePtr) 145 #define WXS_ELEM_CAST (xmlSchemaElementPtr) 146 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr) 147 #define WXS_ATTR_CAST (xmlSchemaAttributePtr) 148 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr) 149 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr) 150 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr) 151 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr) 152 #define WXS_IDC_CAST (xmlSchemaIDCPtr) 153 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr) 154 #define WXS_LIST_CAST (xmlSchemaItemListPtr) 155 156 /* 157 * Macros to query common properties of components. 158 */ 159 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i)) 160 161 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i)) 162 /* 163 * Macros for element declarations. 164 */ 165 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes 166 167 #define WXS_SUBST_HEAD(item) (item)->refDecl 168 /* 169 * Macros for attribute declarations. 170 */ 171 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes 172 /* 173 * Macros for attribute uses. 174 */ 175 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl 176 177 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) 178 179 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name 180 181 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace 182 /* 183 * Macros for attribute groups. 184 */ 185 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) 186 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) 187 /* 188 * Macros for particles. 189 */ 190 #define WXS_PARTICLE(p) WXS_PTC_CAST (p) 191 192 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children 193 194 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p)) 195 196 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children 197 /* 198 * Macros for model groups definitions. 199 */ 200 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children 201 /* 202 * Macros for model groups. 203 */ 204 #define WXS_IS_MODEL_GROUP(i) \ 205 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \ 206 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \ 207 ((i)->type == XML_SCHEMA_TYPE_ALL)) 208 209 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children 210 /* 211 * Macros for schema buckets. 212 */ 213 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \ 214 ((t) == XML_SCHEMA_SCHEMA_REDEFINE)) 215 216 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \ 217 ((t) == XML_SCHEMA_SCHEMA_IMPORT)) 218 219 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b)) 220 221 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b)) 222 /* 223 * Macros for complex/simple types. 224 */ 225 #define WXS_IS_ANYTYPE(i) \ 226 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \ 227 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE)) 228 229 #define WXS_IS_COMPLEX(i) \ 230 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \ 231 ((i)->builtInType == XML_SCHEMAS_ANYTYPE)) 232 233 #define WXS_IS_SIMPLE(item) \ 234 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \ 235 ((item->type == XML_SCHEMA_TYPE_BASIC) && \ 236 (item->builtInType != XML_SCHEMAS_ANYTYPE))) 237 238 #define WXS_IS_ANY_SIMPLE_TYPE(i) \ 239 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \ 240 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) 241 242 #define WXS_IS_RESTRICTION(t) \ 243 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) 244 245 #define WXS_IS_EXTENSION(t) \ 246 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) 247 248 #define WXS_IS_TYPE_NOT_FIXED(i) \ 249 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \ 250 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0)) 251 252 #define WXS_IS_TYPE_NOT_FIXED_1(item) \ 253 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \ 254 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0)) 255 256 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) 257 258 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) 259 /* 260 * Macros for exclusively for complex types. 261 */ 262 #define WXS_HAS_COMPLEX_CONTENT(item) \ 263 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \ 264 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \ 265 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) 266 267 #define WXS_HAS_SIMPLE_CONTENT(item) \ 268 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \ 269 (item->contentType == XML_SCHEMA_CONTENT_BASIC)) 270 271 #define WXS_HAS_MIXED_CONTENT(item) \ 272 (item->contentType == XML_SCHEMA_CONTENT_MIXED) 273 274 #define WXS_EMPTIABLE(t) \ 275 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes)) 276 277 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes 278 279 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes 280 281 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t)) 282 /* 283 * Macros for exclusively for simple types. 284 */ 285 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes 286 287 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC) 288 289 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) 290 291 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) 292 /* 293 * Misc parser context macros. 294 */ 295 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor 296 297 #define WXS_HAS_BUCKETS(ctx) \ 298 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \ 299 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) ) 300 301 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups 302 303 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket 304 305 #define WXS_SCHEMA(ctx) (ctx)->schema 306 307 #define WXS_ADD_LOCAL(ctx, item) \ 308 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item) 309 310 #define WXS_ADD_GLOBAL(ctx, item) \ 311 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item) 312 313 #define WXS_ADD_PENDING(ctx, item) \ 314 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item) 315 /* 316 * xmlSchemaItemList macros. 317 */ 318 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0)) 319 /* 320 * Misc macros. 321 */ 322 #define IS_SCHEMA(node, type) \ 323 ((node != NULL) && (node->ns != NULL) && \ 324 (xmlStrEqual(node->name, (const xmlChar *) type)) && \ 325 (xmlStrEqual(node->ns->href, xmlSchemaNs))) 326 327 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; } 328 329 /* 330 * Since we put the default/fixed values into the dict, we can 331 * use pointer comparison for those values. 332 * REMOVED: (xmlStrEqual((v1), (v2))) 333 */ 334 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2)) 335 336 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED) 337 338 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0)) 339 340 #define HFAILURE if (res == -1) goto exit_failure; 341 342 #define HERROR if (res != 0) goto exit_error; 343 344 #define HSTOP(ctx) if ((ctx)->stop) goto exit; 345 /* 346 * Some flags used for various schema constraints. 347 */ 348 #define SUBSET_RESTRICTION 1<<0 349 #define SUBSET_EXTENSION 1<<1 350 #define SUBSET_SUBSTITUTION 1<<2 351 #define SUBSET_LIST 1<<3 352 #define SUBSET_UNION 1<<4 353 354 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo; 355 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr; 356 357 typedef struct _xmlSchemaItemList xmlSchemaItemList; 358 typedef xmlSchemaItemList *xmlSchemaItemListPtr; 359 struct _xmlSchemaItemList { 360 void **items; /* used for dynamic addition of schemata */ 361 int nbItems; /* used for dynamic addition of schemata */ 362 int sizeItems; /* used for dynamic addition of schemata */ 363 }; 364 365 #define XML_SCHEMA_CTXT_PARSER 1 366 #define XML_SCHEMA_CTXT_VALIDATOR 2 367 368 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; 369 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; 370 struct _xmlSchemaAbstractCtxt { 371 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ 372 void *dummy; /* Fix alignment issues */ 373 }; 374 375 typedef struct _xmlSchemaBucket xmlSchemaBucket; 376 typedef xmlSchemaBucket *xmlSchemaBucketPtr; 377 378 #define XML_SCHEMA_SCHEMA_MAIN 0 379 #define XML_SCHEMA_SCHEMA_IMPORT 1 380 #define XML_SCHEMA_SCHEMA_INCLUDE 2 381 #define XML_SCHEMA_SCHEMA_REDEFINE 3 382 383 /** 384 * xmlSchemaSchemaRelation: 385 * 386 * Used to create a graph of schema relationships. 387 */ 388 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation; 389 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr; 390 struct _xmlSchemaSchemaRelation { 391 xmlSchemaSchemaRelationPtr next; 392 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */ 393 const xmlChar *importNamespace; 394 xmlSchemaBucketPtr bucket; 395 }; 396 397 #define XML_SCHEMA_BUCKET_MARKED 1<<0 398 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1 399 400 struct _xmlSchemaBucket { 401 int type; 402 int flags; 403 const xmlChar *schemaLocation; 404 const xmlChar *origTargetNamespace; 405 const xmlChar *targetNamespace; 406 xmlDocPtr doc; 407 xmlSchemaSchemaRelationPtr relations; 408 int located; 409 int parsed; 410 int imported; 411 int preserveDoc; 412 xmlSchemaItemListPtr globals; /* Global components. */ 413 xmlSchemaItemListPtr locals; /* Local components. */ 414 }; 415 416 /** 417 * xmlSchemaImport: 418 * (extends xmlSchemaBucket) 419 * 420 * Reflects a schema. Holds some information 421 * about the schema and its toplevel components. Duplicate 422 * toplevel components are not checked at this level. 423 */ 424 typedef struct _xmlSchemaImport xmlSchemaImport; 425 typedef xmlSchemaImport *xmlSchemaImportPtr; 426 struct _xmlSchemaImport { 427 int type; /* Main OR import OR include. */ 428 int flags; 429 const xmlChar *schemaLocation; /* The URI of the schema document. */ 430 /* For chameleon includes, @origTargetNamespace will be NULL */ 431 const xmlChar *origTargetNamespace; 432 /* 433 * For chameleon includes, @targetNamespace will be the 434 * targetNamespace of the including schema. 435 */ 436 const xmlChar *targetNamespace; 437 xmlDocPtr doc; /* The schema node-tree. */ 438 /* @relations will hold any included/imported/redefined schemas. */ 439 xmlSchemaSchemaRelationPtr relations; 440 int located; 441 int parsed; 442 int imported; 443 int preserveDoc; 444 xmlSchemaItemListPtr globals; 445 xmlSchemaItemListPtr locals; 446 /* The imported schema. */ 447 xmlSchemaPtr schema; 448 }; 449 450 /* 451 * (extends xmlSchemaBucket) 452 */ 453 typedef struct _xmlSchemaInclude xmlSchemaInclude; 454 typedef xmlSchemaInclude *xmlSchemaIncludePtr; 455 struct _xmlSchemaInclude { 456 int type; 457 int flags; 458 const xmlChar *schemaLocation; 459 const xmlChar *origTargetNamespace; 460 const xmlChar *targetNamespace; 461 xmlDocPtr doc; 462 xmlSchemaSchemaRelationPtr relations; 463 int located; 464 int parsed; 465 int imported; 466 int preserveDoc; 467 xmlSchemaItemListPtr globals; /* Global components. */ 468 xmlSchemaItemListPtr locals; /* Local components. */ 469 470 /* The owning main or import schema bucket. */ 471 xmlSchemaImportPtr ownerImport; 472 }; 473 474 /** 475 * xmlSchemaBasicItem: 476 * 477 * The abstract base type for schema components. 478 */ 479 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; 480 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; 481 struct _xmlSchemaBasicItem { 482 xmlSchemaTypeType type; 483 void *dummy; /* Fix alignment issues */ 484 }; 485 486 /** 487 * xmlSchemaAnnotItem: 488 * 489 * The abstract base type for annotated schema components. 490 * (Extends xmlSchemaBasicItem) 491 */ 492 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem; 493 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr; 494 struct _xmlSchemaAnnotItem { 495 xmlSchemaTypeType type; 496 xmlSchemaAnnotPtr annot; 497 }; 498 499 /** 500 * xmlSchemaTreeItem: 501 * 502 * The abstract base type for tree-like structured schema components. 503 * (Extends xmlSchemaAnnotItem) 504 */ 505 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem; 506 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr; 507 struct _xmlSchemaTreeItem { 508 xmlSchemaTypeType type; 509 xmlSchemaAnnotPtr annot; 510 xmlSchemaTreeItemPtr next; 511 xmlSchemaTreeItemPtr children; 512 }; 513 514 515 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0 516 /** 517 * xmlSchemaAttributeUsePtr: 518 * 519 * The abstract base type for tree-like structured schema components. 520 * (Extends xmlSchemaTreeItem) 521 */ 522 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse; 523 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr; 524 struct _xmlSchemaAttributeUse { 525 xmlSchemaTypeType type; 526 xmlSchemaAnnotPtr annot; 527 xmlSchemaAttributeUsePtr next; /* The next attr. use. */ 528 /* 529 * The attr. decl. OR a QName-ref. to an attr. decl. OR 530 * a QName-ref. to an attribute group definition. 531 */ 532 xmlSchemaAttributePtr attrDecl; 533 534 int flags; 535 xmlNodePtr node; 536 int occurs; /* required, optional */ 537 const xmlChar * defValue; 538 xmlSchemaValPtr defVal; 539 }; 540 541 /** 542 * xmlSchemaAttributeUseProhibPtr: 543 * 544 * A helper component to reflect attribute prohibitions. 545 * (Extends xmlSchemaBasicItem) 546 */ 547 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib; 548 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr; 549 struct _xmlSchemaAttributeUseProhib { 550 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */ 551 xmlNodePtr node; 552 const xmlChar *name; 553 const xmlChar *targetNamespace; 554 int isRef; 555 }; 556 557 /** 558 * xmlSchemaRedef: 559 */ 560 typedef struct _xmlSchemaRedef xmlSchemaRedef; 561 typedef xmlSchemaRedef *xmlSchemaRedefPtr; 562 struct _xmlSchemaRedef { 563 xmlSchemaRedefPtr next; 564 xmlSchemaBasicItemPtr item; /* The redefining component. */ 565 xmlSchemaBasicItemPtr reference; /* The referencing component. */ 566 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */ 567 const xmlChar *refName; /* The name of the to-be-redefined component. */ 568 const xmlChar *refTargetNs; /* The target namespace of the 569 to-be-redefined comp. */ 570 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */ 571 }; 572 573 /** 574 * xmlSchemaConstructionCtxt: 575 */ 576 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt; 577 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr; 578 struct _xmlSchemaConstructionCtxt { 579 xmlSchemaPtr mainSchema; /* The main schema. */ 580 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */ 581 xmlDictPtr dict; 582 xmlSchemaItemListPtr buckets; /* List of schema buckets. */ 583 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */ 584 xmlSchemaBucketPtr bucket; /* The current schema bucket */ 585 xmlSchemaItemListPtr pending; /* All Components of all schemas that 586 need to be fixed. */ 587 xmlHashTablePtr substGroups; 588 xmlSchemaRedefPtr redefs; 589 xmlSchemaRedefPtr lastRedef; 590 }; 591 592 #define XML_SCHEMAS_PARSE_ERROR 1 593 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT 594 595 struct _xmlSchemaParserCtxt { 596 int type; 597 void *errCtxt; /* user specific error context */ 598 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 599 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 600 int err; 601 int nberrors; 602 xmlStructuredErrorFunc serror; 603 604 xmlSchemaConstructionCtxtPtr constructor; 605 int ownsConstructor; /* TODO: Move this to parser *flags*. */ 606 607 /* xmlSchemaPtr topschema; */ 608 /* xmlHashTablePtr namespaces; */ 609 610 xmlSchemaPtr schema; /* The main schema in use */ 611 int counter; 612 613 const xmlChar *URL; 614 xmlDocPtr doc; 615 int preserve; /* Whether the doc should be freed */ 616 617 const char *buffer; 618 int size; 619 620 /* 621 * Used to build complex element content models 622 */ 623 xmlAutomataPtr am; 624 xmlAutomataStatePtr start; 625 xmlAutomataStatePtr end; 626 xmlAutomataStatePtr state; 627 628 xmlDictPtr dict; /* dictionary for interned string names */ 629 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ 630 int options; 631 xmlSchemaValidCtxtPtr vctxt; 632 int isS4S; 633 int isRedefine; 634 int xsiAssemble; 635 int stop; /* If the parser should stop; i.e. a critical error. */ 636 const xmlChar *targetNamespace; 637 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */ 638 639 xmlSchemaRedefPtr redef; /* Used for redefinitions. */ 640 int redefCounter; /* Used for redefinitions. */ 641 xmlSchemaItemListPtr attrProhibs; 642 }; 643 644 /** 645 * xmlSchemaQNameRef: 646 * 647 * A component reference item (not a schema component) 648 * (Extends xmlSchemaBasicItem) 649 */ 650 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef; 651 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr; 652 struct _xmlSchemaQNameRef { 653 xmlSchemaTypeType type; 654 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */ 655 xmlSchemaTypeType itemType; 656 const xmlChar *name; 657 const xmlChar *targetNamespace; 658 xmlNodePtr node; 659 }; 660 661 /** 662 * xmlSchemaParticle: 663 * 664 * A particle component. 665 * (Extends xmlSchemaTreeItem) 666 */ 667 typedef struct _xmlSchemaParticle xmlSchemaParticle; 668 typedef xmlSchemaParticle *xmlSchemaParticlePtr; 669 struct _xmlSchemaParticle { 670 xmlSchemaTypeType type; 671 xmlSchemaAnnotPtr annot; 672 xmlSchemaTreeItemPtr next; /* next particle */ 673 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group, 674 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference), 675 etc.) */ 676 int minOccurs; 677 int maxOccurs; 678 xmlNodePtr node; 679 }; 680 681 /** 682 * xmlSchemaModelGroup: 683 * 684 * A model group component. 685 * (Extends xmlSchemaTreeItem) 686 */ 687 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup; 688 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr; 689 struct _xmlSchemaModelGroup { 690 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */ 691 xmlSchemaAnnotPtr annot; 692 xmlSchemaTreeItemPtr next; /* not used */ 693 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */ 694 xmlNodePtr node; 695 }; 696 697 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0 698 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1 699 /** 700 * xmlSchemaModelGroupDef: 701 * 702 * A model group definition component. 703 * (Extends xmlSchemaTreeItem) 704 */ 705 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef; 706 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr; 707 struct _xmlSchemaModelGroupDef { 708 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */ 709 xmlSchemaAnnotPtr annot; 710 xmlSchemaTreeItemPtr next; /* not used */ 711 xmlSchemaTreeItemPtr children; /* the "model group" */ 712 const xmlChar *name; 713 const xmlChar *targetNamespace; 714 xmlNodePtr node; 715 int flags; 716 }; 717 718 typedef struct _xmlSchemaIDC xmlSchemaIDC; 719 typedef xmlSchemaIDC *xmlSchemaIDCPtr; 720 721 /** 722 * xmlSchemaIDCSelect: 723 * 724 * The identity-constraint "field" and "selector" item, holding the 725 * XPath expression. 726 */ 727 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect; 728 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr; 729 struct _xmlSchemaIDCSelect { 730 xmlSchemaIDCSelectPtr next; 731 xmlSchemaIDCPtr idc; 732 int index; /* an index position if significant for IDC key-sequences */ 733 const xmlChar *xpath; /* the XPath expression */ 734 void *xpathComp; /* the compiled XPath expression */ 735 }; 736 737 /** 738 * xmlSchemaIDC: 739 * 740 * The identity-constraint definition component. 741 * (Extends xmlSchemaAnnotItem) 742 */ 743 744 struct _xmlSchemaIDC { 745 xmlSchemaTypeType type; 746 xmlSchemaAnnotPtr annot; 747 xmlSchemaIDCPtr next; 748 xmlNodePtr node; 749 const xmlChar *name; 750 const xmlChar *targetNamespace; 751 xmlSchemaIDCSelectPtr selector; 752 xmlSchemaIDCSelectPtr fields; 753 int nbFields; 754 xmlSchemaQNameRefPtr ref; 755 }; 756 757 /** 758 * xmlSchemaIDCAug: 759 * 760 * The augmented IDC information used for validation. 761 */ 762 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug; 763 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr; 764 struct _xmlSchemaIDCAug { 765 xmlSchemaIDCAugPtr next; /* next in a list */ 766 xmlSchemaIDCPtr def; /* the IDC definition */ 767 int keyrefDepth; /* the lowest tree level to which IDC 768 tables need to be bubbled upwards */ 769 }; 770 771 /** 772 * xmlSchemaPSVIIDCKeySequence: 773 * 774 * The key sequence of a node table item. 775 */ 776 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey; 777 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr; 778 struct _xmlSchemaPSVIIDCKey { 779 xmlSchemaTypePtr type; 780 xmlSchemaValPtr val; 781 }; 782 783 /** 784 * xmlSchemaPSVIIDCNode: 785 * 786 * The node table item of a node table. 787 */ 788 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode; 789 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr; 790 struct _xmlSchemaPSVIIDCNode { 791 xmlNodePtr node; 792 xmlSchemaPSVIIDCKeyPtr *keys; 793 int nodeLine; 794 int nodeQNameID; 795 796 }; 797 798 /** 799 * xmlSchemaPSVIIDCBinding: 800 * 801 * The identity-constraint binding item of the [identity-constraint table]. 802 */ 803 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding; 804 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr; 805 struct _xmlSchemaPSVIIDCBinding { 806 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */ 807 xmlSchemaIDCPtr definition; /* the IDC definition */ 808 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */ 809 int nbNodes; /* number of entries in the node table */ 810 int sizeNodes; /* size of the node table */ 811 xmlSchemaItemListPtr dupls; 812 }; 813 814 815 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1 816 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2 817 818 #define XPATH_STATE_OBJ_MATCHES -2 819 #define XPATH_STATE_OBJ_BLOCKED -3 820 821 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher; 822 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr; 823 824 /** 825 * xmlSchemaIDCStateObj: 826 * 827 * The state object used to evaluate XPath expressions. 828 */ 829 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj; 830 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr; 831 struct _xmlSchemaIDCStateObj { 832 int type; 833 xmlSchemaIDCStateObjPtr next; /* next if in a list */ 834 int depth; /* depth of creation */ 835 int *history; /* list of (depth, state-id) tuples */ 836 int nbHistory; 837 int sizeHistory; 838 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector 839 matcher */ 840 xmlSchemaIDCSelectPtr sel; 841 void *xpathCtxt; 842 }; 843 844 #define IDC_MATCHER 0 845 846 /** 847 * xmlSchemaIDCMatcher: 848 * 849 * Used to evaluate IDC selectors (and fields). 850 */ 851 struct _xmlSchemaIDCMatcher { 852 int type; 853 int depth; /* the tree depth at creation time */ 854 xmlSchemaIDCMatcherPtr next; /* next in the list */ 855 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */ 856 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */ 857 int idcType; 858 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target 859 elements */ 860 int sizeKeySeqs; 861 xmlSchemaItemListPtr targets; /* list of target-node 862 (xmlSchemaPSVIIDCNodePtr) entries */ 863 }; 864 865 /* 866 * Element info flags. 867 */ 868 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0 869 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1 870 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2 871 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3 872 873 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4 874 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5 875 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6 876 877 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7 878 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8 879 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9 880 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10 881 882 /** 883 * xmlSchemaNodeInfo: 884 * 885 * Holds information of an element node. 886 */ 887 struct _xmlSchemaNodeInfo { 888 int nodeType; 889 xmlNodePtr node; 890 int nodeLine; 891 const xmlChar *localName; 892 const xmlChar *nsName; 893 const xmlChar *value; 894 xmlSchemaValPtr val; /* the pre-computed value if any */ 895 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 896 897 int flags; /* combination of node info flags */ 898 899 int valNeeded; 900 int normVal; 901 902 xmlSchemaElementPtr decl; /* the element/attribute declaration */ 903 int depth; 904 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings 905 for the scope element*/ 906 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope 907 element */ 908 xmlRegExecCtxtPtr regexCtxt; 909 910 const xmlChar **nsBindings; /* Namespace bindings on this element */ 911 int nbNsBindings; 912 int sizeNsBindings; 913 914 int hasKeyrefs; 915 int appliedXPath; /* Indicates that an XPath has been applied. */ 916 }; 917 918 #define XML_SCHEMAS_ATTR_UNKNOWN 1 919 #define XML_SCHEMAS_ATTR_ASSESSED 2 920 #define XML_SCHEMAS_ATTR_PROHIBITED 3 921 #define XML_SCHEMAS_ATTR_ERR_MISSING 4 922 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5 923 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6 924 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7 925 #define XML_SCHEMAS_ATTR_DEFAULT 8 926 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9 927 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10 928 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11 929 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12 930 #define XML_SCHEMAS_ATTR_WILD_SKIP 13 931 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14 932 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15 933 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16 934 #define XML_SCHEMAS_ATTR_META 17 935 /* 936 * @metaType values of xmlSchemaAttrInfo. 937 */ 938 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1 939 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2 940 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3 941 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4 942 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5 943 944 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo; 945 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr; 946 struct _xmlSchemaAttrInfo { 947 int nodeType; 948 xmlNodePtr node; 949 int nodeLine; 950 const xmlChar *localName; 951 const xmlChar *nsName; 952 const xmlChar *value; 953 xmlSchemaValPtr val; /* the pre-computed value if any */ 954 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */ 955 int flags; /* combination of node info flags */ 956 957 xmlSchemaAttributePtr decl; /* the attribute declaration */ 958 xmlSchemaAttributeUsePtr use; /* the attribute use */ 959 int state; 960 int metaType; 961 const xmlChar *vcValue; /* the value constraint value */ 962 xmlSchemaNodeInfoPtr parent; 963 }; 964 965 966 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1 967 /** 968 * xmlSchemaValidCtxt: 969 * 970 * A Schemas validation context 971 */ 972 struct _xmlSchemaValidCtxt { 973 int type; 974 void *errCtxt; /* user specific data block */ 975 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */ 976 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */ 977 xmlStructuredErrorFunc serror; 978 979 xmlSchemaPtr schema; /* The schema in use */ 980 xmlDocPtr doc; 981 xmlParserInputBufferPtr input; 982 xmlCharEncoding enc; 983 xmlSAXHandlerPtr sax; 984 xmlParserCtxtPtr parserCtxt; 985 void *user_data; /* TODO: What is this for? */ 986 char *filename; 987 988 int err; 989 int nberrors; 990 991 xmlNodePtr node; 992 xmlNodePtr cur; 993 /* xmlSchemaTypePtr type; */ 994 995 xmlRegExecCtxtPtr regexp; 996 xmlSchemaValPtr value; 997 998 int valueWS; 999 int options; 1000 xmlNodePtr validationRoot; 1001 xmlSchemaParserCtxtPtr pctxt; 1002 int xsiAssemble; 1003 1004 int depth; 1005 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */ 1006 int sizeElemInfos; 1007 xmlSchemaNodeInfoPtr inode; /* the current element information */ 1008 1009 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */ 1010 1011 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */ 1012 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */ 1013 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */ 1014 1015 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/ 1016 int nbIdcNodes; 1017 int sizeIdcNodes; 1018 1019 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */ 1020 int nbIdcKeys; 1021 int sizeIdcKeys; 1022 1023 int flags; 1024 1025 xmlDictPtr dict; 1026 1027 #ifdef LIBXML_READER_ENABLED 1028 xmlTextReaderPtr reader; 1029 #endif 1030 1031 xmlSchemaAttrInfoPtr *attrInfos; 1032 int nbAttrInfos; 1033 int sizeAttrInfos; 1034 1035 int skipDepth; 1036 xmlSchemaItemListPtr nodeQNames; 1037 int hasKeyrefs; 1038 int createIDCNodeTables; 1039 int psviExposeIDCNodeTables; 1040 1041 /* Locator for error reporting in streaming mode */ 1042 xmlSchemaValidityLocatorFunc locFunc; 1043 void *locCtxt; 1044 }; 1045 1046 /** 1047 * xmlSchemaSubstGroup: 1048 * 1049 * 1050 */ 1051 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup; 1052 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr; 1053 struct _xmlSchemaSubstGroup { 1054 xmlSchemaElementPtr head; 1055 xmlSchemaItemListPtr members; 1056 }; 1057 1058 /************************************************************************ 1059 * * 1060 * Some predeclarations * 1061 * * 1062 ************************************************************************/ 1063 1064 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, 1065 xmlSchemaPtr schema, 1066 xmlNodePtr node); 1067 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt, 1068 xmlSchemaPtr schema, 1069 xmlNodePtr node); 1070 static int 1071 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 1072 xmlSchemaAbstractCtxtPtr ctxt); 1073 static const xmlChar * 1074 xmlSchemaFacetTypeToString(xmlSchemaTypeType type); 1075 static int 1076 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1077 xmlNodePtr node); 1078 static int 1079 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 1080 xmlSchemaParserCtxtPtr ctxt); 1081 static void 1082 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt); 1083 static xmlSchemaWhitespaceValueType 1084 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type); 1085 static xmlSchemaTreeItemPtr 1086 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 1087 xmlNodePtr node, xmlSchemaTypeType type, 1088 int withParticle); 1089 static const xmlChar * 1090 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item); 1091 static xmlSchemaTypeLinkPtr 1092 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); 1093 static void 1094 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 1095 const char *funcName, 1096 const char *message) LIBXML_ATTR_FORMAT(3,0); 1097 static int 1098 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, 1099 xmlSchemaTypePtr type, 1100 xmlSchemaTypePtr baseType, 1101 int subset); 1102 static void 1103 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl, 1104 xmlSchemaParserCtxtPtr ctxt); 1105 static void 1106 xmlSchemaComponentListFree(xmlSchemaItemListPtr list); 1107 static xmlSchemaQNameRefPtr 1108 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 1109 xmlSchemaPtr schema, 1110 xmlNodePtr node); 1111 1112 /************************************************************************ 1113 * * 1114 * Helper functions * 1115 * * 1116 ************************************************************************/ 1117 1118 /** 1119 * xmlSchemaItemTypeToStr: 1120 * @type: the type of the schema item 1121 * 1122 * Returns the component name of a schema item. 1123 */ 1124 static const xmlChar * 1125 xmlSchemaItemTypeToStr(xmlSchemaTypeType type) 1126 { 1127 switch (type) { 1128 case XML_SCHEMA_TYPE_BASIC: 1129 return(BAD_CAST "simple type definition"); 1130 case XML_SCHEMA_TYPE_SIMPLE: 1131 return(BAD_CAST "simple type definition"); 1132 case XML_SCHEMA_TYPE_COMPLEX: 1133 return(BAD_CAST "complex type definition"); 1134 case XML_SCHEMA_TYPE_ELEMENT: 1135 return(BAD_CAST "element declaration"); 1136 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1137 return(BAD_CAST "attribute use"); 1138 case XML_SCHEMA_TYPE_ATTRIBUTE: 1139 return(BAD_CAST "attribute declaration"); 1140 case XML_SCHEMA_TYPE_GROUP: 1141 return(BAD_CAST "model group definition"); 1142 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1143 return(BAD_CAST "attribute group definition"); 1144 case XML_SCHEMA_TYPE_NOTATION: 1145 return(BAD_CAST "notation declaration"); 1146 case XML_SCHEMA_TYPE_SEQUENCE: 1147 return(BAD_CAST "model group (sequence)"); 1148 case XML_SCHEMA_TYPE_CHOICE: 1149 return(BAD_CAST "model group (choice)"); 1150 case XML_SCHEMA_TYPE_ALL: 1151 return(BAD_CAST "model group (all)"); 1152 case XML_SCHEMA_TYPE_PARTICLE: 1153 return(BAD_CAST "particle"); 1154 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1155 return(BAD_CAST "unique identity-constraint"); 1156 /* return(BAD_CAST "IDC (unique)"); */ 1157 case XML_SCHEMA_TYPE_IDC_KEY: 1158 return(BAD_CAST "key identity-constraint"); 1159 /* return(BAD_CAST "IDC (key)"); */ 1160 case XML_SCHEMA_TYPE_IDC_KEYREF: 1161 return(BAD_CAST "keyref identity-constraint"); 1162 /* return(BAD_CAST "IDC (keyref)"); */ 1163 case XML_SCHEMA_TYPE_ANY: 1164 return(BAD_CAST "wildcard (any)"); 1165 case XML_SCHEMA_EXTRA_QNAMEREF: 1166 return(BAD_CAST "[helper component] QName reference"); 1167 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 1168 return(BAD_CAST "[helper component] attribute use prohibition"); 1169 default: 1170 return(BAD_CAST "Not a schema component"); 1171 } 1172 } 1173 1174 /** 1175 * xmlSchemaGetComponentTypeStr: 1176 * @type: the type of the schema item 1177 * 1178 * Returns the component name of a schema item. 1179 */ 1180 static const xmlChar * 1181 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item) 1182 { 1183 switch (item->type) { 1184 case XML_SCHEMA_TYPE_BASIC: 1185 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item)) 1186 return(BAD_CAST "complex type definition"); 1187 else 1188 return(BAD_CAST "simple type definition"); 1189 default: 1190 return(xmlSchemaItemTypeToStr(item->type)); 1191 } 1192 } 1193 1194 /** 1195 * xmlSchemaGetComponentNode: 1196 * @item: a schema component 1197 * 1198 * Returns node associated with the schema component. 1199 * NOTE that such a node need not be available; plus, a component's 1200 * node need not to reflect the component directly, since there is no 1201 * one-to-one relationship between the XML Schema representation and 1202 * the component representation. 1203 */ 1204 static xmlNodePtr 1205 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item) 1206 { 1207 switch (item->type) { 1208 case XML_SCHEMA_TYPE_ELEMENT: 1209 return (((xmlSchemaElementPtr) item)->node); 1210 case XML_SCHEMA_TYPE_ATTRIBUTE: 1211 return (((xmlSchemaAttributePtr) item)->node); 1212 case XML_SCHEMA_TYPE_COMPLEX: 1213 case XML_SCHEMA_TYPE_SIMPLE: 1214 return (((xmlSchemaTypePtr) item)->node); 1215 case XML_SCHEMA_TYPE_ANY: 1216 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1217 return (((xmlSchemaWildcardPtr) item)->node); 1218 case XML_SCHEMA_TYPE_PARTICLE: 1219 return (((xmlSchemaParticlePtr) item)->node); 1220 case XML_SCHEMA_TYPE_SEQUENCE: 1221 case XML_SCHEMA_TYPE_CHOICE: 1222 case XML_SCHEMA_TYPE_ALL: 1223 return (((xmlSchemaModelGroupPtr) item)->node); 1224 case XML_SCHEMA_TYPE_GROUP: 1225 return (((xmlSchemaModelGroupDefPtr) item)->node); 1226 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1227 return (((xmlSchemaAttributeGroupPtr) item)->node); 1228 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1229 case XML_SCHEMA_TYPE_IDC_KEY: 1230 case XML_SCHEMA_TYPE_IDC_KEYREF: 1231 return (((xmlSchemaIDCPtr) item)->node); 1232 case XML_SCHEMA_EXTRA_QNAMEREF: 1233 return(((xmlSchemaQNameRefPtr) item)->node); 1234 /* TODO: What to do with NOTATIONs? 1235 case XML_SCHEMA_TYPE_NOTATION: 1236 return (((xmlSchemaNotationPtr) item)->node); 1237 */ 1238 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1239 return (((xmlSchemaAttributeUsePtr) item)->node); 1240 default: 1241 return (NULL); 1242 } 1243 } 1244 1245 #if 0 1246 /** 1247 * xmlSchemaGetNextComponent: 1248 * @item: a schema component 1249 * 1250 * Returns the next sibling of the schema component. 1251 */ 1252 static xmlSchemaBasicItemPtr 1253 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item) 1254 { 1255 switch (item->type) { 1256 case XML_SCHEMA_TYPE_ELEMENT: 1257 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next); 1258 case XML_SCHEMA_TYPE_ATTRIBUTE: 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next); 1260 case XML_SCHEMA_TYPE_COMPLEX: 1261 case XML_SCHEMA_TYPE_SIMPLE: 1262 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next); 1263 case XML_SCHEMA_TYPE_ANY: 1264 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1265 return (NULL); 1266 case XML_SCHEMA_TYPE_PARTICLE: 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next); 1268 case XML_SCHEMA_TYPE_SEQUENCE: 1269 case XML_SCHEMA_TYPE_CHOICE: 1270 case XML_SCHEMA_TYPE_ALL: 1271 return (NULL); 1272 case XML_SCHEMA_TYPE_GROUP: 1273 return (NULL); 1274 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1275 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next); 1276 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1277 case XML_SCHEMA_TYPE_IDC_KEY: 1278 case XML_SCHEMA_TYPE_IDC_KEYREF: 1279 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next); 1280 default: 1281 return (NULL); 1282 } 1283 } 1284 #endif 1285 1286 1287 /** 1288 * xmlSchemaFormatQName: 1289 * @buf: the string buffer 1290 * @namespaceName: the namespace name 1291 * @localName: the local name 1292 * 1293 * Returns the given QName in the format "{namespaceName}localName" or 1294 * just "localName" if @namespaceName is NULL. 1295 * 1296 * Returns the localName if @namespaceName is NULL, a formatted 1297 * string otherwise. 1298 */ 1299 static const xmlChar* 1300 xmlSchemaFormatQName(xmlChar **buf, 1301 const xmlChar *namespaceName, 1302 const xmlChar *localName) 1303 { 1304 FREE_AND_NULL(*buf) 1305 if (namespaceName != NULL) { 1306 *buf = xmlStrdup(BAD_CAST "{"); 1307 *buf = xmlStrcat(*buf, namespaceName); 1308 *buf = xmlStrcat(*buf, BAD_CAST "}"); 1309 } 1310 if (localName != NULL) { 1311 if (namespaceName == NULL) 1312 return(localName); 1313 *buf = xmlStrcat(*buf, localName); 1314 } else { 1315 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)"); 1316 } 1317 return ((const xmlChar *) *buf); 1318 } 1319 1320 static const xmlChar* 1321 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName) 1322 { 1323 if (ns != NULL) 1324 return (xmlSchemaFormatQName(buf, ns->href, localName)); 1325 else 1326 return (xmlSchemaFormatQName(buf, NULL, localName)); 1327 } 1328 1329 static const xmlChar * 1330 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) 1331 { 1332 switch (item->type) { 1333 case XML_SCHEMA_TYPE_ELEMENT: 1334 return (((xmlSchemaElementPtr) item)->name); 1335 case XML_SCHEMA_TYPE_ATTRIBUTE: 1336 return (((xmlSchemaAttributePtr) item)->name); 1337 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1338 return (((xmlSchemaAttributeGroupPtr) item)->name); 1339 case XML_SCHEMA_TYPE_BASIC: 1340 case XML_SCHEMA_TYPE_SIMPLE: 1341 case XML_SCHEMA_TYPE_COMPLEX: 1342 return (((xmlSchemaTypePtr) item)->name); 1343 case XML_SCHEMA_TYPE_GROUP: 1344 return (((xmlSchemaModelGroupDefPtr) item)->name); 1345 case XML_SCHEMA_TYPE_IDC_KEY: 1346 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1347 case XML_SCHEMA_TYPE_IDC_KEYREF: 1348 return (((xmlSchemaIDCPtr) item)->name); 1349 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1350 if (WXS_ATTRUSE_DECL(item) != NULL) { 1351 return(xmlSchemaGetComponentName( 1352 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1353 } else 1354 return(NULL); 1355 case XML_SCHEMA_EXTRA_QNAMEREF: 1356 return (((xmlSchemaQNameRefPtr) item)->name); 1357 case XML_SCHEMA_TYPE_NOTATION: 1358 return (((xmlSchemaNotationPtr) item)->name); 1359 default: 1360 /* 1361 * Other components cannot have names. 1362 */ 1363 break; 1364 } 1365 return (NULL); 1366 } 1367 1368 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name 1369 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace 1370 /* 1371 static const xmlChar * 1372 xmlSchemaGetQNameRefName(void *ref) 1373 { 1374 return(((xmlSchemaQNameRefPtr) ref)->name); 1375 } 1376 1377 static const xmlChar * 1378 xmlSchemaGetQNameRefTargetNs(void *ref) 1379 { 1380 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace); 1381 } 1382 */ 1383 1384 static const xmlChar * 1385 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) 1386 { 1387 switch (item->type) { 1388 case XML_SCHEMA_TYPE_ELEMENT: 1389 return (((xmlSchemaElementPtr) item)->targetNamespace); 1390 case XML_SCHEMA_TYPE_ATTRIBUTE: 1391 return (((xmlSchemaAttributePtr) item)->targetNamespace); 1392 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1393 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace); 1394 case XML_SCHEMA_TYPE_BASIC: 1395 return (BAD_CAST "http://www.w3.org/2001/XMLSchema"); 1396 case XML_SCHEMA_TYPE_SIMPLE: 1397 case XML_SCHEMA_TYPE_COMPLEX: 1398 return (((xmlSchemaTypePtr) item)->targetNamespace); 1399 case XML_SCHEMA_TYPE_GROUP: 1400 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace); 1401 case XML_SCHEMA_TYPE_IDC_KEY: 1402 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1403 case XML_SCHEMA_TYPE_IDC_KEYREF: 1404 return (((xmlSchemaIDCPtr) item)->targetNamespace); 1405 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 1406 if (WXS_ATTRUSE_DECL(item) != NULL) { 1407 return(xmlSchemaGetComponentTargetNs( 1408 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item))); 1409 } 1410 /* TODO: Will returning NULL break something? */ 1411 break; 1412 case XML_SCHEMA_EXTRA_QNAMEREF: 1413 return (((xmlSchemaQNameRefPtr) item)->targetNamespace); 1414 case XML_SCHEMA_TYPE_NOTATION: 1415 return (((xmlSchemaNotationPtr) item)->targetNamespace); 1416 default: 1417 /* 1418 * Other components cannot have names. 1419 */ 1420 break; 1421 } 1422 return (NULL); 1423 } 1424 1425 static const xmlChar* 1426 xmlSchemaGetComponentQName(xmlChar **buf, 1427 void *item) 1428 { 1429 return (xmlSchemaFormatQName(buf, 1430 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item), 1431 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item))); 1432 } 1433 1434 static const xmlChar* 1435 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item) 1436 { 1437 xmlChar *str = NULL; 1438 1439 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item)); 1440 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1441 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, 1442 (xmlSchemaBasicItemPtr) item)); 1443 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1444 FREE_AND_NULL(str); 1445 return(*buf); 1446 } 1447 1448 static const xmlChar* 1449 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc) 1450 { 1451 return(xmlSchemaGetComponentDesignation(buf, idc)); 1452 } 1453 1454 /** 1455 * xmlSchemaWildcardPCToString: 1456 * @pc: the type of processContents 1457 * 1458 * Returns a string representation of the type of 1459 * processContents. 1460 */ 1461 static const xmlChar * 1462 xmlSchemaWildcardPCToString(int pc) 1463 { 1464 switch (pc) { 1465 case XML_SCHEMAS_ANY_SKIP: 1466 return (BAD_CAST "skip"); 1467 case XML_SCHEMAS_ANY_LAX: 1468 return (BAD_CAST "lax"); 1469 case XML_SCHEMAS_ANY_STRICT: 1470 return (BAD_CAST "strict"); 1471 default: 1472 return (BAD_CAST "invalid process contents"); 1473 } 1474 } 1475 1476 /** 1477 * xmlSchemaGetCanonValueWhtspExt: 1478 * @val: the precomputed value 1479 * @retValue: the returned value 1480 * @ws: the whitespace type of the value 1481 * 1482 * Get a the canonical representation of the value. 1483 * The caller has to free the returned retValue. 1484 * 1485 * Returns 0 if the value could be built and -1 in case of 1486 * API errors or if the value type is not supported yet. 1487 */ 1488 static int 1489 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val, 1490 xmlSchemaWhitespaceValueType ws, 1491 xmlChar **retValue) 1492 { 1493 int list; 1494 xmlSchemaValType valType; 1495 const xmlChar *value, *value2 = NULL; 1496 1497 1498 if ((retValue == NULL) || (val == NULL)) 1499 return (-1); 1500 list = xmlSchemaValueGetNext(val) ? 1 : 0; 1501 *retValue = NULL; 1502 do { 1503 value = NULL; 1504 valType = xmlSchemaGetValType(val); 1505 switch (valType) { 1506 case XML_SCHEMAS_STRING: 1507 case XML_SCHEMAS_NORMSTRING: 1508 case XML_SCHEMAS_ANYSIMPLETYPE: 1509 value = xmlSchemaValueGetAsString(val); 1510 if (value != NULL) { 1511 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) 1512 value2 = xmlSchemaCollapseString(value); 1513 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE) 1514 value2 = xmlSchemaWhiteSpaceReplace(value); 1515 if (value2 != NULL) 1516 value = value2; 1517 } 1518 break; 1519 default: 1520 if (xmlSchemaGetCanonValue(val, &value2) == -1) { 1521 if (value2 != NULL) 1522 xmlFree((xmlChar *) value2); 1523 goto internal_error; 1524 } 1525 value = value2; 1526 } 1527 if (*retValue == NULL) 1528 if (value == NULL) { 1529 if (! list) 1530 *retValue = xmlStrdup(BAD_CAST ""); 1531 } else 1532 *retValue = xmlStrdup(value); 1533 else if (value != NULL) { 1534 /* List. */ 1535 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " "); 1536 *retValue = xmlStrcat((xmlChar *) *retValue, value); 1537 } 1538 FREE_AND_NULL(value2) 1539 val = xmlSchemaValueGetNext(val); 1540 } while (val != NULL); 1541 1542 return (0); 1543 internal_error: 1544 if (*retValue != NULL) 1545 xmlFree((xmlChar *) (*retValue)); 1546 if (value2 != NULL) 1547 xmlFree((xmlChar *) value2); 1548 return (-1); 1549 } 1550 1551 /** 1552 * xmlSchemaFormatItemForReport: 1553 * @buf: the string buffer 1554 * @itemDes: the designation of the item 1555 * @itemName: the name of the item 1556 * @item: the item as an object 1557 * @itemNode: the node of the item 1558 * @local: the local name 1559 * @parsing: if the function is used during the parse 1560 * 1561 * Returns a representation of the given item used 1562 * for error reports. 1563 * 1564 * The following order is used to build the resulting 1565 * designation if the arguments are not NULL: 1566 * 1a. If itemDes not NULL -> itemDes 1567 * 1b. If (itemDes not NULL) and (itemName not NULL) 1568 * -> itemDes + itemName 1569 * 2. If the preceding was NULL and (item not NULL) -> item 1570 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode 1571 * 1572 * If the itemNode is an attribute node, the name of the attribute 1573 * will be appended to the result. 1574 * 1575 * Returns the formatted string and sets @buf to the resulting value. 1576 */ 1577 static xmlChar* 1578 xmlSchemaFormatItemForReport(xmlChar **buf, 1579 const xmlChar *itemDes, 1580 xmlSchemaBasicItemPtr item, 1581 xmlNodePtr itemNode) 1582 { 1583 xmlChar *str = NULL; 1584 int named = 1; 1585 1586 if (*buf != NULL) { 1587 xmlFree(*buf); 1588 *buf = NULL; 1589 } 1590 1591 if (itemDes != NULL) { 1592 *buf = xmlStrdup(itemDes); 1593 } else if (item != NULL) { 1594 switch (item->type) { 1595 case XML_SCHEMA_TYPE_BASIC: { 1596 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1597 1598 if (WXS_IS_ATOMIC(type)) 1599 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:"); 1600 else if (WXS_IS_LIST(type)) 1601 *buf = xmlStrdup(BAD_CAST "list type 'xs:"); 1602 else if (WXS_IS_UNION(type)) 1603 *buf = xmlStrdup(BAD_CAST "union type 'xs:"); 1604 else 1605 *buf = xmlStrdup(BAD_CAST "simple type 'xs:"); 1606 *buf = xmlStrcat(*buf, type->name); 1607 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1608 } 1609 break; 1610 case XML_SCHEMA_TYPE_SIMPLE: { 1611 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1612 1613 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1614 *buf = xmlStrdup(BAD_CAST""); 1615 } else { 1616 *buf = xmlStrdup(BAD_CAST "local "); 1617 } 1618 if (WXS_IS_ATOMIC(type)) 1619 *buf = xmlStrcat(*buf, BAD_CAST "atomic type"); 1620 else if (WXS_IS_LIST(type)) 1621 *buf = xmlStrcat(*buf, BAD_CAST "list type"); 1622 else if (WXS_IS_UNION(type)) 1623 *buf = xmlStrcat(*buf, BAD_CAST "union type"); 1624 else 1625 *buf = xmlStrcat(*buf, BAD_CAST "simple type"); 1626 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1627 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1628 *buf = xmlStrcat(*buf, type->name); 1629 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1630 } 1631 } 1632 break; 1633 case XML_SCHEMA_TYPE_COMPLEX: { 1634 xmlSchemaTypePtr type = WXS_TYPE_CAST item; 1635 1636 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) 1637 *buf = xmlStrdup(BAD_CAST ""); 1638 else 1639 *buf = xmlStrdup(BAD_CAST "local "); 1640 *buf = xmlStrcat(*buf, BAD_CAST "complex type"); 1641 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) { 1642 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1643 *buf = xmlStrcat(*buf, type->name); 1644 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1645 } 1646 } 1647 break; 1648 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: { 1649 xmlSchemaAttributeUsePtr ause; 1650 1651 ause = WXS_ATTR_USE_CAST item; 1652 *buf = xmlStrdup(BAD_CAST "attribute use "); 1653 if (WXS_ATTRUSE_DECL(ause) != NULL) { 1654 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1655 *buf = xmlStrcat(*buf, 1656 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause))); 1657 FREE_AND_NULL(str) 1658 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1659 } else { 1660 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)"); 1661 } 1662 } 1663 break; 1664 case XML_SCHEMA_TYPE_ATTRIBUTE: { 1665 xmlSchemaAttributePtr attr; 1666 1667 attr = (xmlSchemaAttributePtr) item; 1668 *buf = xmlStrdup(BAD_CAST "attribute decl."); 1669 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1670 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1671 attr->targetNamespace, attr->name)); 1672 FREE_AND_NULL(str) 1673 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1674 } 1675 break; 1676 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 1677 xmlSchemaGetComponentDesignation(buf, item); 1678 break; 1679 case XML_SCHEMA_TYPE_ELEMENT: { 1680 xmlSchemaElementPtr elem; 1681 1682 elem = (xmlSchemaElementPtr) item; 1683 *buf = xmlStrdup(BAD_CAST "element decl."); 1684 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1685 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1686 elem->targetNamespace, elem->name)); 1687 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1688 } 1689 break; 1690 case XML_SCHEMA_TYPE_IDC_UNIQUE: 1691 case XML_SCHEMA_TYPE_IDC_KEY: 1692 case XML_SCHEMA_TYPE_IDC_KEYREF: 1693 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE) 1694 *buf = xmlStrdup(BAD_CAST "unique '"); 1695 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY) 1696 *buf = xmlStrdup(BAD_CAST "key '"); 1697 else 1698 *buf = xmlStrdup(BAD_CAST "keyRef '"); 1699 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name); 1700 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1701 break; 1702 case XML_SCHEMA_TYPE_ANY: 1703 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 1704 *buf = xmlStrdup(xmlSchemaWildcardPCToString( 1705 ((xmlSchemaWildcardPtr) item)->processContents)); 1706 *buf = xmlStrcat(*buf, BAD_CAST " wildcard"); 1707 break; 1708 case XML_SCHEMA_FACET_MININCLUSIVE: 1709 case XML_SCHEMA_FACET_MINEXCLUSIVE: 1710 case XML_SCHEMA_FACET_MAXINCLUSIVE: 1711 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 1712 case XML_SCHEMA_FACET_TOTALDIGITS: 1713 case XML_SCHEMA_FACET_FRACTIONDIGITS: 1714 case XML_SCHEMA_FACET_PATTERN: 1715 case XML_SCHEMA_FACET_ENUMERATION: 1716 case XML_SCHEMA_FACET_WHITESPACE: 1717 case XML_SCHEMA_FACET_LENGTH: 1718 case XML_SCHEMA_FACET_MAXLENGTH: 1719 case XML_SCHEMA_FACET_MINLENGTH: 1720 *buf = xmlStrdup(BAD_CAST "facet '"); 1721 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type)); 1722 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1723 break; 1724 case XML_SCHEMA_TYPE_GROUP: { 1725 *buf = xmlStrdup(BAD_CAST "model group def."); 1726 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1727 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1728 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1729 FREE_AND_NULL(str) 1730 } 1731 break; 1732 case XML_SCHEMA_TYPE_SEQUENCE: 1733 case XML_SCHEMA_TYPE_CHOICE: 1734 case XML_SCHEMA_TYPE_ALL: 1735 case XML_SCHEMA_TYPE_PARTICLE: 1736 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1737 break; 1738 case XML_SCHEMA_TYPE_NOTATION: { 1739 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item)); 1740 *buf = xmlStrcat(*buf, BAD_CAST " '"); 1741 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item)); 1742 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1743 FREE_AND_NULL(str); 1744 } 1745 /* Falls through. */ 1746 default: 1747 named = 0; 1748 } 1749 } else 1750 named = 0; 1751 1752 if ((named == 0) && (itemNode != NULL)) { 1753 xmlNodePtr elem; 1754 1755 if (itemNode->type == XML_ATTRIBUTE_NODE) 1756 elem = itemNode->parent; 1757 else 1758 elem = itemNode; 1759 *buf = xmlStrdup(BAD_CAST "Element '"); 1760 if (elem->ns != NULL) { 1761 *buf = xmlStrcat(*buf, 1762 xmlSchemaFormatQName(&str, elem->ns->href, elem->name)); 1763 FREE_AND_NULL(str) 1764 } else 1765 *buf = xmlStrcat(*buf, elem->name); 1766 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1767 1768 } 1769 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) { 1770 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '"); 1771 if (itemNode->ns != NULL) { 1772 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str, 1773 itemNode->ns->href, itemNode->name)); 1774 FREE_AND_NULL(str) 1775 } else 1776 *buf = xmlStrcat(*buf, itemNode->name); 1777 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1778 } 1779 FREE_AND_NULL(str) 1780 1781 return (xmlEscapeFormatString(buf)); 1782 } 1783 1784 /** 1785 * xmlSchemaFormatFacetEnumSet: 1786 * @buf: the string buffer 1787 * @type: the type holding the enumeration facets 1788 * 1789 * Builds a string consisting of all enumeration elements. 1790 * 1791 * Returns a string of all enumeration elements. 1792 */ 1793 static const xmlChar * 1794 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt, 1795 xmlChar **buf, xmlSchemaTypePtr type) 1796 { 1797 xmlSchemaFacetPtr facet; 1798 xmlSchemaWhitespaceValueType ws; 1799 xmlChar *value = NULL; 1800 int res, found = 0; 1801 1802 if (*buf != NULL) 1803 xmlFree(*buf); 1804 *buf = NULL; 1805 1806 do { 1807 /* 1808 * Use the whitespace type of the base type. 1809 */ 1810 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType); 1811 for (facet = type->facets; facet != NULL; facet = facet->next) { 1812 if (facet->type != XML_SCHEMA_FACET_ENUMERATION) 1813 continue; 1814 found = 1; 1815 res = xmlSchemaGetCanonValueWhtspExt(facet->val, 1816 ws, &value); 1817 if (res == -1) { 1818 xmlSchemaInternalErr(actxt, 1819 "xmlSchemaFormatFacetEnumSet", 1820 "compute the canonical lexical representation"); 1821 if (*buf != NULL) 1822 xmlFree(*buf); 1823 *buf = NULL; 1824 return (NULL); 1825 } 1826 if (*buf == NULL) 1827 *buf = xmlStrdup(BAD_CAST "'"); 1828 else 1829 *buf = xmlStrcat(*buf, BAD_CAST ", '"); 1830 *buf = xmlStrcat(*buf, BAD_CAST value); 1831 *buf = xmlStrcat(*buf, BAD_CAST "'"); 1832 if (value != NULL) { 1833 xmlFree((xmlChar *)value); 1834 value = NULL; 1835 } 1836 } 1837 /* 1838 * The enumeration facet of a type restricts the enumeration 1839 * facet of the ancestor type; i.e., such restricted enumerations 1840 * do not belong to the set of the given type. Thus we break 1841 * on the first found enumeration. 1842 */ 1843 if (found) 1844 break; 1845 type = type->baseType; 1846 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC)); 1847 1848 return ((const xmlChar *) *buf); 1849 } 1850 1851 /************************************************************************ 1852 * * 1853 * Error functions * 1854 * * 1855 ************************************************************************/ 1856 1857 #if 0 1858 static void 1859 xmlSchemaErrMemory(const char *msg) 1860 { 1861 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1862 msg); 1863 } 1864 #endif 1865 1866 static void 1867 xmlSchemaPSimpleErr(const char *msg) 1868 { 1869 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL, 1870 msg); 1871 } 1872 1873 /** 1874 * xmlSchemaPErrMemory: 1875 * @node: a context node 1876 * @extra: extra informations 1877 * 1878 * Handle an out of memory condition 1879 */ 1880 static void 1881 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, 1882 const char *extra, xmlNodePtr node) 1883 { 1884 if (ctxt != NULL) 1885 ctxt->nberrors++; 1886 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL, 1887 extra); 1888 } 1889 1890 /** 1891 * xmlSchemaPErr: 1892 * @ctxt: the parsing context 1893 * @node: the context node 1894 * @error: the error code 1895 * @msg: the error message 1896 * @str1: extra data 1897 * @str2: extra data 1898 * 1899 * Handle a parser error 1900 */ 1901 static void LIBXML_ATTR_FORMAT(4,0) 1902 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1903 const char *msg, const xmlChar * str1, const xmlChar * str2) 1904 { 1905 xmlGenericErrorFunc channel = NULL; 1906 xmlStructuredErrorFunc schannel = NULL; 1907 void *data = NULL; 1908 1909 if (ctxt != NULL) { 1910 ctxt->nberrors++; 1911 ctxt->err = error; 1912 channel = ctxt->error; 1913 data = ctxt->errCtxt; 1914 schannel = ctxt->serror; 1915 } 1916 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1917 error, XML_ERR_ERROR, NULL, 0, 1918 (const char *) str1, (const char *) str2, NULL, 0, 0, 1919 msg, str1, str2); 1920 } 1921 1922 /** 1923 * xmlSchemaPErr2: 1924 * @ctxt: the parsing context 1925 * @node: the context node 1926 * @node: the current child 1927 * @error: the error code 1928 * @msg: the error message 1929 * @str1: extra data 1930 * @str2: extra data 1931 * 1932 * Handle a parser error 1933 */ 1934 static void LIBXML_ATTR_FORMAT(5,0) 1935 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 1936 xmlNodePtr child, int error, 1937 const char *msg, const xmlChar * str1, const xmlChar * str2) 1938 { 1939 if (child != NULL) 1940 xmlSchemaPErr(ctxt, child, error, msg, str1, str2); 1941 else 1942 xmlSchemaPErr(ctxt, node, error, msg, str1, str2); 1943 } 1944 1945 1946 /** 1947 * xmlSchemaPErrExt: 1948 * @ctxt: the parsing context 1949 * @node: the context node 1950 * @error: the error code 1951 * @strData1: extra data 1952 * @strData2: extra data 1953 * @strData3: extra data 1954 * @msg: the message 1955 * @str1: extra parameter for the message display 1956 * @str2: extra parameter for the message display 1957 * @str3: extra parameter for the message display 1958 * @str4: extra parameter for the message display 1959 * @str5: extra parameter for the message display 1960 * 1961 * Handle a parser error 1962 */ 1963 static void LIBXML_ATTR_FORMAT(7,0) 1964 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, 1965 const xmlChar * strData1, const xmlChar * strData2, 1966 const xmlChar * strData3, const char *msg, const xmlChar * str1, 1967 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4, 1968 const xmlChar * str5) 1969 { 1970 1971 xmlGenericErrorFunc channel = NULL; 1972 xmlStructuredErrorFunc schannel = NULL; 1973 void *data = NULL; 1974 1975 if (ctxt != NULL) { 1976 ctxt->nberrors++; 1977 ctxt->err = error; 1978 channel = ctxt->error; 1979 data = ctxt->errCtxt; 1980 schannel = ctxt->serror; 1981 } 1982 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, 1983 error, XML_ERR_ERROR, NULL, 0, 1984 (const char *) strData1, (const char *) strData2, 1985 (const char *) strData3, 0, 0, msg, str1, str2, 1986 str3, str4, str5); 1987 } 1988 1989 /************************************************************************ 1990 * * 1991 * Allround error functions * 1992 * * 1993 ************************************************************************/ 1994 1995 /** 1996 * xmlSchemaVTypeErrMemory: 1997 * @node: a context node 1998 * @extra: extra informations 1999 * 2000 * Handle an out of memory condition 2001 */ 2002 static void 2003 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, 2004 const char *extra, xmlNodePtr node) 2005 { 2006 if (ctxt != NULL) { 2007 ctxt->nberrors++; 2008 ctxt->err = XML_SCHEMAV_INTERNAL; 2009 } 2010 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL, 2011 extra); 2012 } 2013 2014 static void LIBXML_ATTR_FORMAT(2,0) 2015 xmlSchemaPSimpleInternalErr(xmlNodePtr node, 2016 const char *msg, const xmlChar *str) 2017 { 2018 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node, 2019 msg, (const char *) str); 2020 } 2021 2022 #define WXS_ERROR_TYPE_ERROR 1 2023 #define WXS_ERROR_TYPE_WARNING 2 2024 /** 2025 * xmlSchemaErr4Line: 2026 * @ctxt: the validation context 2027 * @errorLevel: the error level 2028 * @error: the error code 2029 * @node: the context node 2030 * @line: the line number 2031 * @msg: the error message 2032 * @str1: extra data 2033 * @str2: extra data 2034 * @str3: extra data 2035 * @str4: extra data 2036 * 2037 * Handle a validation error 2038 */ 2039 static void LIBXML_ATTR_FORMAT(6,0) 2040 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, 2041 xmlErrorLevel errorLevel, 2042 int error, xmlNodePtr node, int line, const char *msg, 2043 const xmlChar *str1, const xmlChar *str2, 2044 const xmlChar *str3, const xmlChar *str4) 2045 { 2046 xmlStructuredErrorFunc schannel = NULL; 2047 xmlGenericErrorFunc channel = NULL; 2048 void *data = NULL; 2049 2050 if (ctxt != NULL) { 2051 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2052 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt; 2053 const char *file = NULL; 2054 int col = 0; 2055 if (errorLevel != XML_ERR_WARNING) { 2056 vctxt->nberrors++; 2057 vctxt->err = error; 2058 channel = vctxt->error; 2059 } else { 2060 channel = vctxt->warning; 2061 } 2062 schannel = vctxt->serror; 2063 data = vctxt->errCtxt; 2064 2065 /* 2066 * Error node. If we specify a line number, then 2067 * do not channel any node to the error function. 2068 */ 2069 if (line == 0) { 2070 if ((node == NULL) && 2071 (vctxt->depth >= 0) && 2072 (vctxt->inode != NULL)) { 2073 node = vctxt->inode->node; 2074 } 2075 /* 2076 * Get filename and line if no node-tree. 2077 */ 2078 if ((node == NULL) && 2079 (vctxt->parserCtxt != NULL) && 2080 (vctxt->parserCtxt->input != NULL)) { 2081 file = vctxt->parserCtxt->input->filename; 2082 line = vctxt->parserCtxt->input->line; 2083 col = vctxt->parserCtxt->input->col; 2084 } 2085 } else { 2086 /* 2087 * Override the given node's (if any) position 2088 * and channel only the given line number. 2089 */ 2090 node = NULL; 2091 /* 2092 * Get filename. 2093 */ 2094 if (vctxt->doc != NULL) 2095 file = (const char *) vctxt->doc->URL; 2096 else if ((vctxt->parserCtxt != NULL) && 2097 (vctxt->parserCtxt->input != NULL)) 2098 file = vctxt->parserCtxt->input->filename; 2099 } 2100 if (vctxt->locFunc != NULL) { 2101 if ((file == NULL) || (line == 0)) { 2102 unsigned long l; 2103 const char *f; 2104 vctxt->locFunc(vctxt->locCtxt, &f, &l); 2105 if (file == NULL) 2106 file = f; 2107 if (line == 0) 2108 line = (int) l; 2109 } 2110 } 2111 if ((file == NULL) && (vctxt->filename != NULL)) 2112 file = vctxt->filename; 2113 2114 __xmlRaiseError(schannel, channel, data, ctxt, 2115 node, XML_FROM_SCHEMASV, 2116 error, errorLevel, file, line, 2117 (const char *) str1, (const char *) str2, 2118 (const char *) str3, 0, col, msg, str1, str2, str3, str4); 2119 2120 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { 2121 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; 2122 if (errorLevel != XML_ERR_WARNING) { 2123 pctxt->nberrors++; 2124 pctxt->err = error; 2125 channel = pctxt->error; 2126 } else { 2127 channel = pctxt->warning; 2128 } 2129 schannel = pctxt->serror; 2130 data = pctxt->errCtxt; 2131 __xmlRaiseError(schannel, channel, data, ctxt, 2132 node, XML_FROM_SCHEMASP, error, 2133 errorLevel, NULL, 0, 2134 (const char *) str1, (const char *) str2, 2135 (const char *) str3, 0, 0, msg, str1, str2, str3, str4); 2136 } else { 2137 TODO 2138 } 2139 } 2140 } 2141 2142 /** 2143 * xmlSchemaErr3: 2144 * @ctxt: the validation context 2145 * @node: the context node 2146 * @error: the error code 2147 * @msg: the error message 2148 * @str1: extra data 2149 * @str2: extra data 2150 * @str3: extra data 2151 * 2152 * Handle a validation error 2153 */ 2154 static void LIBXML_ATTR_FORMAT(4,0) 2155 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, 2156 int error, xmlNodePtr node, const char *msg, 2157 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) 2158 { 2159 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2160 msg, str1, str2, str3, NULL); 2161 } 2162 2163 static void LIBXML_ATTR_FORMAT(4,0) 2164 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, 2165 int error, xmlNodePtr node, const char *msg, 2166 const xmlChar *str1, const xmlChar *str2, 2167 const xmlChar *str3, const xmlChar *str4) 2168 { 2169 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0, 2170 msg, str1, str2, str3, str4); 2171 } 2172 2173 static void LIBXML_ATTR_FORMAT(4,0) 2174 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, 2175 int error, xmlNodePtr node, const char *msg, 2176 const xmlChar *str1, const xmlChar *str2) 2177 { 2178 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL); 2179 } 2180 2181 static xmlChar * 2182 xmlSchemaFormatNodeForError(xmlChar ** msg, 2183 xmlSchemaAbstractCtxtPtr actxt, 2184 xmlNodePtr node) 2185 { 2186 xmlChar *str = NULL; 2187 2188 *msg = NULL; 2189 if ((node != NULL) && 2190 (node->type != XML_ELEMENT_NODE) && 2191 (node->type != XML_ATTRIBUTE_NODE)) 2192 { 2193 /* 2194 * Don't try to format other nodes than element and 2195 * attribute nodes. 2196 * Play safe and return an empty string. 2197 */ 2198 *msg = xmlStrdup(BAD_CAST ""); 2199 return(*msg); 2200 } 2201 if (node != NULL) { 2202 /* 2203 * Work on tree nodes. 2204 */ 2205 if (node->type == XML_ATTRIBUTE_NODE) { 2206 xmlNodePtr elem = node->parent; 2207 2208 *msg = xmlStrdup(BAD_CAST "Element '"); 2209 if (elem->ns != NULL) 2210 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2211 elem->ns->href, elem->name)); 2212 else 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2214 NULL, elem->name)); 2215 FREE_AND_NULL(str); 2216 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2217 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2218 } else { 2219 *msg = xmlStrdup(BAD_CAST "Element '"); 2220 } 2221 if (node->ns != NULL) 2222 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2223 node->ns->href, node->name)); 2224 else 2225 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2226 NULL, node->name)); 2227 FREE_AND_NULL(str); 2228 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2229 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) { 2230 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt; 2231 /* 2232 * Work on node infos. 2233 */ 2234 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) { 2235 xmlSchemaNodeInfoPtr ielem = 2236 vctxt->elemInfos[vctxt->depth]; 2237 2238 *msg = xmlStrdup(BAD_CAST "Element '"); 2239 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2240 ielem->nsName, ielem->localName)); 2241 FREE_AND_NULL(str); 2242 *msg = xmlStrcat(*msg, BAD_CAST "', "); 2243 *msg = xmlStrcat(*msg, BAD_CAST "attribute '"); 2244 } else { 2245 *msg = xmlStrdup(BAD_CAST "Element '"); 2246 } 2247 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str, 2248 vctxt->inode->nsName, vctxt->inode->localName)); 2249 FREE_AND_NULL(str); 2250 *msg = xmlStrcat(*msg, BAD_CAST "': "); 2251 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) { 2252 /* 2253 * Hmm, no node while parsing? 2254 * Return an empty string, in case NULL will break something. 2255 */ 2256 *msg = xmlStrdup(BAD_CAST ""); 2257 } else { 2258 TODO 2259 return (NULL); 2260 } 2261 2262 /* 2263 * xmlSchemaFormatItemForReport() also returns an escaped format 2264 * string, so do this before calling it below (in the future). 2265 */ 2266 xmlEscapeFormatString(msg); 2267 2268 /* 2269 * VAL TODO: The output of the given schema component is currently 2270 * disabled. 2271 */ 2272 #if 0 2273 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) { 2274 *msg = xmlStrcat(*msg, BAD_CAST " ["); 2275 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str, 2276 NULL, type, NULL, 0)); 2277 FREE_AND_NULL(str) 2278 *msg = xmlStrcat(*msg, BAD_CAST "]"); 2279 } 2280 #endif 2281 return (*msg); 2282 } 2283 2284 static void LIBXML_ATTR_FORMAT(3,0) 2285 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, 2286 const char *funcName, 2287 const char *message, 2288 const xmlChar *str1, 2289 const xmlChar *str2) 2290 { 2291 xmlChar *msg = NULL; 2292 2293 if (actxt == NULL) 2294 return; 2295 msg = xmlStrdup(BAD_CAST "Internal error: %s, "); 2296 msg = xmlStrcat(msg, BAD_CAST message); 2297 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2298 2299 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) 2300 xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, 2301 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2302 else if (actxt->type == XML_SCHEMA_CTXT_PARSER) 2303 xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, 2304 (const char *) msg, (const xmlChar *) funcName, str1, str2); 2305 2306 FREE_AND_NULL(msg) 2307 } 2308 2309 static void LIBXML_ATTR_FORMAT(3,0) 2310 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, 2311 const char *funcName, 2312 const char *message) 2313 { 2314 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL); 2315 } 2316 2317 #if 0 2318 static void LIBXML_ATTR_FORMAT(3,0) 2319 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, 2320 const char *funcName, 2321 const char *message, 2322 const xmlChar *str1, 2323 const xmlChar *str2) 2324 { 2325 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message, 2326 str1, str2); 2327 } 2328 #endif 2329 2330 static void LIBXML_ATTR_FORMAT(5,0) 2331 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, 2332 xmlParserErrors error, 2333 xmlNodePtr node, 2334 xmlSchemaBasicItemPtr item, 2335 const char *message, 2336 const xmlChar *str1, const xmlChar *str2, 2337 const xmlChar *str3, const xmlChar *str4) 2338 { 2339 xmlChar *msg = NULL; 2340 2341 if ((node == NULL) && (item != NULL) && 2342 (actxt->type == XML_SCHEMA_CTXT_PARSER)) { 2343 node = WXS_ITEM_NODE(item); 2344 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL); 2345 msg = xmlStrcat(msg, BAD_CAST ": "); 2346 } else 2347 xmlSchemaFormatNodeForError(&msg, actxt, node); 2348 msg = xmlStrcat(msg, (const xmlChar *) message); 2349 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2350 xmlSchemaErr4(actxt, error, node, 2351 (const char *) msg, str1, str2, str3, str4); 2352 FREE_AND_NULL(msg) 2353 } 2354 2355 static void LIBXML_ATTR_FORMAT(5,0) 2356 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, 2357 xmlParserErrors error, 2358 xmlNodePtr node, 2359 xmlSchemaBasicItemPtr item, 2360 const char *message, 2361 const xmlChar *str1, 2362 const xmlChar *str2) 2363 { 2364 xmlSchemaCustomErr4(actxt, error, node, item, 2365 message, str1, str2, NULL, NULL); 2366 } 2367 2368 2369 2370 static void LIBXML_ATTR_FORMAT(5,0) 2371 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, 2372 xmlParserErrors error, 2373 xmlNodePtr node, 2374 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2375 const char *message, 2376 const xmlChar *str1, 2377 const xmlChar *str2, 2378 const xmlChar *str3) 2379 { 2380 xmlChar *msg = NULL; 2381 2382 xmlSchemaFormatNodeForError(&msg, actxt, node); 2383 msg = xmlStrcat(msg, (const xmlChar *) message); 2384 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2385 2386 /* URGENT TODO: Set the error code to something sane. */ 2387 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, 2388 (const char *) msg, str1, str2, str3, NULL); 2389 2390 FREE_AND_NULL(msg) 2391 } 2392 2393 2394 2395 static void LIBXML_ATTR_FORMAT(5,0) 2396 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, 2397 xmlParserErrors error, 2398 xmlSchemaPSVIIDCNodePtr idcNode, 2399 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2400 const char *message, 2401 const xmlChar *str1, 2402 const xmlChar *str2) 2403 { 2404 xmlChar *msg = NULL, *qname = NULL; 2405 2406 msg = xmlStrdup(BAD_CAST "Element '%s': "); 2407 msg = xmlStrcat(msg, (const xmlChar *) message); 2408 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2409 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, 2410 error, NULL, idcNode->nodeLine, (const char *) msg, 2411 xmlSchemaFormatQName(&qname, 2412 vctxt->nodeQNames->items[idcNode->nodeQNameID +1], 2413 vctxt->nodeQNames->items[idcNode->nodeQNameID]), 2414 str1, str2, NULL); 2415 FREE_AND_NULL(qname); 2416 FREE_AND_NULL(msg); 2417 } 2418 2419 static int 2420 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt, 2421 xmlNodePtr node) 2422 { 2423 if (node != NULL) 2424 return (node->type); 2425 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) && 2426 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL)) 2427 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType); 2428 return (-1); 2429 } 2430 2431 static int 2432 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item) 2433 { 2434 switch (item->type) { 2435 case XML_SCHEMA_TYPE_COMPLEX: 2436 case XML_SCHEMA_TYPE_SIMPLE: 2437 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) 2438 return(1); 2439 break; 2440 case XML_SCHEMA_TYPE_GROUP: 2441 return (1); 2442 case XML_SCHEMA_TYPE_ELEMENT: 2443 if ( ((xmlSchemaElementPtr) item)->flags & 2444 XML_SCHEMAS_ELEM_GLOBAL) 2445 return(1); 2446 break; 2447 case XML_SCHEMA_TYPE_ATTRIBUTE: 2448 if ( ((xmlSchemaAttributePtr) item)->flags & 2449 XML_SCHEMAS_ATTR_GLOBAL) 2450 return(1); 2451 break; 2452 /* Note that attribute groups are always global. */ 2453 default: 2454 return(1); 2455 } 2456 return (0); 2457 } 2458 2459 static void 2460 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2461 xmlParserErrors error, 2462 xmlNodePtr node, 2463 const xmlChar *value, 2464 xmlSchemaTypePtr type, 2465 int displayValue) 2466 { 2467 xmlChar *msg = NULL; 2468 2469 xmlSchemaFormatNodeForError(&msg, actxt, node); 2470 2471 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2472 XML_ATTRIBUTE_NODE)) 2473 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 2474 else 2475 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid " 2476 "value of "); 2477 2478 if (! xmlSchemaIsGlobalItem(type)) 2479 msg = xmlStrcat(msg, BAD_CAST "the local "); 2480 else 2481 msg = xmlStrcat(msg, BAD_CAST "the "); 2482 2483 if (WXS_IS_ATOMIC(type)) 2484 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 2485 else if (WXS_IS_LIST(type)) 2486 msg = xmlStrcat(msg, BAD_CAST "list type"); 2487 else if (WXS_IS_UNION(type)) 2488 msg = xmlStrcat(msg, BAD_CAST "union type"); 2489 2490 if (xmlSchemaIsGlobalItem(type)) { 2491 xmlChar *str = NULL; 2492 msg = xmlStrcat(msg, BAD_CAST " '"); 2493 if (type->builtInType != 0) { 2494 msg = xmlStrcat(msg, BAD_CAST "xs:"); 2495 str = xmlStrdup(type->name); 2496 } else { 2497 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 2498 if (!str) 2499 str = xmlStrdup(qName); 2500 } 2501 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2502 msg = xmlStrcat(msg, BAD_CAST "'"); 2503 FREE_AND_NULL(str); 2504 } 2505 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2506 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == 2507 XML_ATTRIBUTE_NODE)) 2508 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2509 else 2510 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2511 FREE_AND_NULL(msg) 2512 } 2513 2514 static const xmlChar * 2515 xmlSchemaFormatErrorNodeQName(xmlChar ** str, 2516 xmlSchemaNodeInfoPtr ni, 2517 xmlNodePtr node) 2518 { 2519 if (node != NULL) { 2520 if (node->ns != NULL) 2521 return (xmlSchemaFormatQName(str, node->ns->href, node->name)); 2522 else 2523 return (xmlSchemaFormatQName(str, NULL, node->name)); 2524 } else if (ni != NULL) 2525 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName)); 2526 return (NULL); 2527 } 2528 2529 static void 2530 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, 2531 xmlParserErrors error, 2532 xmlSchemaAttrInfoPtr ni, 2533 xmlNodePtr node) 2534 { 2535 xmlChar *msg = NULL, *str = NULL; 2536 2537 xmlSchemaFormatNodeForError(&msg, actxt, node); 2538 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); 2539 xmlSchemaErr(actxt, error, node, (const char *) msg, 2540 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), 2541 NULL); 2542 FREE_AND_NULL(str) 2543 FREE_AND_NULL(msg) 2544 } 2545 2546 static void LIBXML_ATTR_FORMAT(5,0) 2547 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, 2548 xmlParserErrors error, 2549 xmlNodePtr node, 2550 xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 2551 const char *message, 2552 int nbval, 2553 int nbneg, 2554 xmlChar **values) 2555 { 2556 xmlChar *str = NULL, *msg = NULL; 2557 xmlChar *localName, *nsName; 2558 const xmlChar *cur, *end; 2559 int i; 2560 2561 xmlSchemaFormatNodeForError(&msg, actxt, node); 2562 msg = xmlStrcat(msg, (const xmlChar *) message); 2563 msg = xmlStrcat(msg, BAD_CAST "."); 2564 /* 2565 * Note that is does not make sense to report that we have a 2566 * wildcard here, since the wildcard might be unfolded into 2567 * multiple transitions. 2568 */ 2569 if (nbval + nbneg > 0) { 2570 if (nbval + nbneg > 1) { 2571 str = xmlStrdup(BAD_CAST " Expected is one of ( "); 2572 } else 2573 str = xmlStrdup(BAD_CAST " Expected is ( "); 2574 nsName = NULL; 2575 2576 for (i = 0; i < nbval + nbneg; i++) { 2577 cur = values[i]; 2578 if (cur == NULL) 2579 continue; 2580 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') && 2581 (cur[3] == ' ')) { 2582 cur += 4; 2583 str = xmlStrcat(str, BAD_CAST "##other"); 2584 } 2585 /* 2586 * Get the local name. 2587 */ 2588 localName = NULL; 2589 2590 end = cur; 2591 if (*end == '*') { 2592 localName = xmlStrdup(BAD_CAST "*"); 2593 end++; 2594 } else { 2595 while ((*end != 0) && (*end != '|')) 2596 end++; 2597 localName = xmlStrncat(localName, BAD_CAST cur, end - cur); 2598 } 2599 if (*end != 0) { 2600 end++; 2601 /* 2602 * Skip "*|*" if they come with negated expressions, since 2603 * they represent the same negated wildcard. 2604 */ 2605 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) { 2606 /* 2607 * Get the namespace name. 2608 */ 2609 cur = end; 2610 if (*end == '*') { 2611 nsName = xmlStrdup(BAD_CAST "{*}"); 2612 } else { 2613 while (*end != 0) 2614 end++; 2615 2616 if (i >= nbval) 2617 nsName = xmlStrdup(BAD_CAST "{##other:"); 2618 else 2619 nsName = xmlStrdup(BAD_CAST "{"); 2620 2621 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur); 2622 nsName = xmlStrcat(nsName, BAD_CAST "}"); 2623 } 2624 str = xmlStrcat(str, BAD_CAST nsName); 2625 FREE_AND_NULL(nsName) 2626 } else { 2627 FREE_AND_NULL(localName); 2628 continue; 2629 } 2630 } 2631 str = xmlStrcat(str, BAD_CAST localName); 2632 FREE_AND_NULL(localName); 2633 2634 if (i < nbval + nbneg -1) 2635 str = xmlStrcat(str, BAD_CAST ", "); 2636 } 2637 str = xmlStrcat(str, BAD_CAST " ).\n"); 2638 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 2639 FREE_AND_NULL(str) 2640 } else 2641 msg = xmlStrcat(msg, BAD_CAST "\n"); 2642 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2643 xmlFree(msg); 2644 } 2645 2646 static void LIBXML_ATTR_FORMAT(8,0) 2647 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, 2648 xmlParserErrors error, 2649 xmlNodePtr node, 2650 const xmlChar *value, 2651 unsigned long length, 2652 xmlSchemaTypePtr type, 2653 xmlSchemaFacetPtr facet, 2654 const char *message, 2655 const xmlChar *str1, 2656 const xmlChar *str2) 2657 { 2658 xmlChar *str = NULL, *msg = NULL; 2659 xmlSchemaTypeType facetType; 2660 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node); 2661 2662 xmlSchemaFormatNodeForError(&msg, actxt, node); 2663 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) { 2664 facetType = XML_SCHEMA_FACET_ENUMERATION; 2665 /* 2666 * If enumerations are validated, one must not expect the 2667 * facet to be given. 2668 */ 2669 } else 2670 facetType = facet->type; 2671 msg = xmlStrcat(msg, BAD_CAST "["); 2672 msg = xmlStrcat(msg, BAD_CAST "facet '"); 2673 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType)); 2674 msg = xmlStrcat(msg, BAD_CAST "'] "); 2675 if (message == NULL) { 2676 /* 2677 * Use a default message. 2678 */ 2679 if ((facetType == XML_SCHEMA_FACET_LENGTH) || 2680 (facetType == XML_SCHEMA_FACET_MINLENGTH) || 2681 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) { 2682 2683 char len[25], actLen[25]; 2684 2685 /* FIXME, TODO: What is the max expected string length of the 2686 * this value? 2687 */ 2688 if (nodeType == XML_ATTRIBUTE_NODE) 2689 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; "); 2690 else 2691 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; "); 2692 2693 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet)); 2694 snprintf(actLen, 24, "%lu", length); 2695 2696 if (facetType == XML_SCHEMA_FACET_LENGTH) 2697 msg = xmlStrcat(msg, 2698 BAD_CAST "this differs from the allowed length of '%s'.\n"); 2699 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH) 2700 msg = xmlStrcat(msg, 2701 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n"); 2702 else if (facetType == XML_SCHEMA_FACET_MINLENGTH) 2703 msg = xmlStrcat(msg, 2704 BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); 2705 2706 if (nodeType == XML_ATTRIBUTE_NODE) 2707 xmlSchemaErr3(actxt, error, node, (const char *) msg, 2708 value, (const xmlChar *) actLen, (const xmlChar *) len); 2709 else 2710 xmlSchemaErr(actxt, error, node, (const char *) msg, 2711 (const xmlChar *) actLen, (const xmlChar *) len); 2712 2713 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) { 2714 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element " 2715 "of the set {%s}.\n"); 2716 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2717 xmlSchemaFormatFacetEnumSet(actxt, &str, type)); 2718 } else if (facetType == XML_SCHEMA_FACET_PATTERN) { 2719 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted " 2720 "by the pattern '%s'.\n"); 2721 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2722 facet->value); 2723 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) { 2724 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the " 2725 "minimum value allowed ('%s').\n"); 2726 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2727 facet->value); 2728 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) { 2729 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the " 2730 "maximum value allowed ('%s').\n"); 2731 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2732 facet->value); 2733 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) { 2734 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than " 2735 "'%s'.\n"); 2736 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2737 facet->value); 2738 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) { 2739 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than " 2740 "'%s'.\n"); 2741 xmlSchemaErr(actxt, error, node, (const char *) msg, value, 2742 facet->value); 2743 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) { 2744 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more " 2745 "digits than are allowed ('%s').\n"); 2746 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2747 facet->value); 2748 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) { 2749 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional " 2750 "digits than are allowed ('%s').\n"); 2751 xmlSchemaErr(actxt, error, node, (const char*) msg, value, 2752 facet->value); 2753 } else if (nodeType == XML_ATTRIBUTE_NODE) { 2754 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n"); 2755 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); 2756 } else { 2757 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n"); 2758 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); 2759 } 2760 } else { 2761 msg = xmlStrcat(msg, (const xmlChar *) message); 2762 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2763 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); 2764 } 2765 FREE_AND_NULL(str) 2766 xmlFree(msg); 2767 } 2768 2769 #define VERROR(err, type, msg) \ 2770 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL); 2771 2772 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg); 2773 2774 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg); 2775 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg); 2776 2777 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg); 2778 2779 2780 /** 2781 * xmlSchemaPMissingAttrErr: 2782 * @ctxt: the schema validation context 2783 * @ownerDes: the designation of the owner 2784 * @ownerName: the name of the owner 2785 * @ownerItem: the owner as a schema object 2786 * @ownerElem: the owner as an element node 2787 * @node: the parent element node of the missing attribute node 2788 * @type: the corresponding type of the attribute node 2789 * 2790 * Reports an illegal attribute. 2791 */ 2792 static void 2793 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt, 2794 xmlParserErrors error, 2795 xmlSchemaBasicItemPtr ownerItem, 2796 xmlNodePtr ownerElem, 2797 const char *name, 2798 const char *message) 2799 { 2800 xmlChar *des = NULL; 2801 2802 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2803 2804 if (message != NULL) 2805 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message); 2806 else 2807 xmlSchemaPErr(ctxt, ownerElem, error, 2808 "%s: The attribute '%s' is required but missing.\n", 2809 BAD_CAST des, BAD_CAST name); 2810 FREE_AND_NULL(des); 2811 } 2812 2813 2814 /** 2815 * xmlSchemaPResCompAttrErr: 2816 * @ctxt: the schema validation context 2817 * @error: the error code 2818 * @ownerDes: the designation of the owner 2819 * @ownerItem: the owner as a schema object 2820 * @ownerElem: the owner as an element node 2821 * @name: the name of the attribute holding the QName 2822 * @refName: the referenced local name 2823 * @refURI: the referenced namespace URI 2824 * @message: optional message 2825 * 2826 * Used to report QName attribute values that failed to resolve 2827 * to schema components. 2828 */ 2829 static void 2830 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, 2831 xmlParserErrors error, 2832 xmlSchemaBasicItemPtr ownerItem, 2833 xmlNodePtr ownerElem, 2834 const char *name, 2835 const xmlChar *refName, 2836 const xmlChar *refURI, 2837 xmlSchemaTypeType refType, 2838 const char *refTypeStr) 2839 { 2840 xmlChar *des = NULL, *strA = NULL; 2841 2842 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 2843 if (refTypeStr == NULL) 2844 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); 2845 xmlSchemaPErrExt(ctxt, ownerElem, error, 2846 NULL, NULL, NULL, 2847 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " 2848 "%s.\n", BAD_CAST des, BAD_CAST name, 2849 xmlSchemaFormatQName(&strA, refURI, refName), 2850 BAD_CAST refTypeStr, NULL); 2851 FREE_AND_NULL(des) 2852 FREE_AND_NULL(strA) 2853 } 2854 2855 /** 2856 * xmlSchemaPCustomAttrErr: 2857 * @ctxt: the schema parser context 2858 * @error: the error code 2859 * @ownerDes: the designation of the owner 2860 * @ownerItem: the owner as a schema object 2861 * @attr: the illegal attribute node 2862 * 2863 * Reports an illegal attribute during the parse. 2864 */ 2865 static void 2866 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt, 2867 xmlParserErrors error, 2868 xmlChar **ownerDes, 2869 xmlSchemaBasicItemPtr ownerItem, 2870 xmlAttrPtr attr, 2871 const char *msg) 2872 { 2873 xmlChar *des = NULL; 2874 2875 if (ownerDes == NULL) 2876 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent); 2877 else if (*ownerDes == NULL) { 2878 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent); 2879 des = *ownerDes; 2880 } else 2881 des = *ownerDes; 2882 if (attr == NULL) { 2883 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL, 2884 "%s, attribute '%s': %s.\n", 2885 BAD_CAST des, (const xmlChar *) "Unknown", 2886 (const xmlChar *) msg, NULL, NULL); 2887 } else { 2888 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 2889 "%s, attribute '%s': %s.\n", 2890 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL); 2891 } 2892 if (ownerDes == NULL) 2893 FREE_AND_NULL(des); 2894 } 2895 2896 /** 2897 * xmlSchemaPIllegalAttrErr: 2898 * @ctxt: the schema parser context 2899 * @error: the error code 2900 * @ownerDes: the designation of the attribute's owner 2901 * @ownerItem: the attribute's owner item 2902 * @attr: the illegal attribute node 2903 * 2904 * Reports an illegal attribute during the parse. 2905 */ 2906 static void 2907 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, 2908 xmlParserErrors error, 2909 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED, 2910 xmlAttrPtr attr) 2911 { 2912 xmlChar *strA = NULL, *strB = NULL; 2913 2914 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent); 2915 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr, 2916 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA, 2917 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name), 2918 NULL, NULL); 2919 FREE_AND_NULL(strA); 2920 FREE_AND_NULL(strB); 2921 } 2922 2923 /** 2924 * xmlSchemaPCustomErr: 2925 * @ctxt: the schema parser context 2926 * @error: the error code 2927 * @itemDes: the designation of the schema item 2928 * @item: the schema item 2929 * @itemElem: the node of the schema item 2930 * @message: the error message 2931 * @str1: an optional param for the error message 2932 * @str2: an optional param for the error message 2933 * @str3: an optional param for the error message 2934 * 2935 * Reports an error during parsing. 2936 */ 2937 static void LIBXML_ATTR_FORMAT(5,0) 2938 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, 2939 xmlParserErrors error, 2940 xmlSchemaBasicItemPtr item, 2941 xmlNodePtr itemElem, 2942 const char *message, 2943 const xmlChar *str1, 2944 const xmlChar *str2, 2945 const xmlChar *str3) 2946 { 2947 xmlChar *des = NULL, *msg = NULL; 2948 2949 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem); 2950 msg = xmlStrdup(BAD_CAST "%s: "); 2951 msg = xmlStrcat(msg, (const xmlChar *) message); 2952 msg = xmlStrcat(msg, BAD_CAST ".\n"); 2953 if ((itemElem == NULL) && (item != NULL)) 2954 itemElem = WXS_ITEM_NODE(item); 2955 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, 2956 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL); 2957 FREE_AND_NULL(des); 2958 FREE_AND_NULL(msg); 2959 } 2960 2961 /** 2962 * xmlSchemaPCustomErr: 2963 * @ctxt: the schema parser context 2964 * @error: the error code 2965 * @itemDes: the designation of the schema item 2966 * @item: the schema item 2967 * @itemElem: the node of the schema item 2968 * @message: the error message 2969 * @str1: the optional param for the error message 2970 * 2971 * Reports an error during parsing. 2972 */ 2973 static void LIBXML_ATTR_FORMAT(5,0) 2974 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, 2975 xmlParserErrors error, 2976 xmlSchemaBasicItemPtr item, 2977 xmlNodePtr itemElem, 2978 const char *message, 2979 const xmlChar *str1) 2980 { 2981 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message, 2982 str1, NULL, NULL); 2983 } 2984 2985 /** 2986 * xmlSchemaPAttrUseErr: 2987 * @ctxt: the schema parser context 2988 * @error: the error code 2989 * @itemDes: the designation of the schema type 2990 * @item: the schema type 2991 * @itemElem: the node of the schema type 2992 * @attr: the invalid schema attribute 2993 * @message: the error message 2994 * @str1: the optional param for the error message 2995 * 2996 * Reports an attribute use error during parsing. 2997 */ 2998 static void LIBXML_ATTR_FORMAT(6,0) 2999 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, 3000 xmlParserErrors error, 3001 xmlNodePtr node, 3002 xmlSchemaBasicItemPtr ownerItem, 3003 const xmlSchemaAttributeUsePtr attruse, 3004 const char *message, 3005 const xmlChar *str1, const xmlChar *str2, 3006 const xmlChar *str3,const xmlChar *str4) 3007 { 3008 xmlChar *str = NULL, *msg = NULL; 3009 3010 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL); 3011 msg = xmlStrcat(msg, BAD_CAST ", "); 3012 msg = xmlStrcat(msg, 3013 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL, 3014 WXS_BASIC_CAST attruse, NULL)); 3015 FREE_AND_NULL(str); 3016 msg = xmlStrcat(msg, BAD_CAST ": "); 3017 msg = xmlStrcat(msg, (const xmlChar *) message); 3018 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3019 xmlSchemaErr4(ACTXT_CAST ctxt, error, node, 3020 (const char *) msg, str1, str2, str3, str4); 3021 xmlFree(msg); 3022 } 3023 3024 /** 3025 * xmlSchemaPIllegalFacetAtomicErr: 3026 * @ctxt: the schema parser context 3027 * @error: the error code 3028 * @type: the schema type 3029 * @baseType: the base type of type 3030 * @facet: the illegal facet 3031 * 3032 * Reports an illegal facet for atomic simple types. 3033 */ 3034 static void 3035 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt, 3036 xmlParserErrors error, 3037 xmlSchemaTypePtr type, 3038 xmlSchemaTypePtr baseType, 3039 xmlSchemaFacetPtr facet) 3040 { 3041 xmlChar *des = NULL, *strT = NULL; 3042 3043 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node); 3044 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL, 3045 "%s: The facet '%s' is not allowed on types derived from the " 3046 "type %s.\n", 3047 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type), 3048 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL), 3049 NULL, NULL); 3050 FREE_AND_NULL(des); 3051 FREE_AND_NULL(strT); 3052 } 3053 3054 /** 3055 * xmlSchemaPIllegalFacetListUnionErr: 3056 * @ctxt: the schema parser context 3057 * @error: the error code 3058 * @itemDes: the designation of the schema item involved 3059 * @item: the schema item involved 3060 * @facet: the illegal facet 3061 * 3062 * Reports an illegal facet for <list> and <union>. 3063 */ 3064 static void 3065 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt, 3066 xmlParserErrors error, 3067 xmlSchemaTypePtr type, 3068 xmlSchemaFacetPtr facet) 3069 { 3070 xmlChar *des = NULL; 3071 3072 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, 3073 type->node); 3074 xmlSchemaPErr(ctxt, type->node, error, 3075 "%s: The facet '%s' is not allowed.\n", 3076 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type)); 3077 FREE_AND_NULL(des); 3078 } 3079 3080 /** 3081 * xmlSchemaPMutualExclAttrErr: 3082 * @ctxt: the schema validation context 3083 * @error: the error code 3084 * @elemDes: the designation of the parent element node 3085 * @attr: the bad attribute node 3086 * @type: the corresponding type of the attribute node 3087 * 3088 * Reports an illegal attribute. 3089 */ 3090 static void 3091 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, 3092 xmlParserErrors error, 3093 xmlSchemaBasicItemPtr ownerItem, 3094 xmlAttrPtr attr, 3095 const char *name1, 3096 const char *name2) 3097 { 3098 xmlChar *des = NULL; 3099 3100 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent); 3101 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL, 3102 "%s: The attributes '%s' and '%s' are mutually exclusive.\n", 3103 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL); 3104 FREE_AND_NULL(des); 3105 } 3106 3107 /** 3108 * xmlSchemaPSimpleTypeErr: 3109 * @ctxt: the schema validation context 3110 * @error: the error code 3111 * @type: the type specifier 3112 * @ownerDes: the designation of the owner 3113 * @ownerItem: the schema object if existent 3114 * @node: the validated node 3115 * @value: the validated value 3116 * 3117 * Reports a simple type validation error. 3118 * TODO: Should this report the value of an element as well? 3119 */ 3120 static void LIBXML_ATTR_FORMAT(8,0) 3121 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, 3122 xmlParserErrors error, 3123 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, 3124 xmlNodePtr node, 3125 xmlSchemaTypePtr type, 3126 const char *expected, 3127 const xmlChar *value, 3128 const char *message, 3129 const xmlChar *str1, 3130 const xmlChar *str2) 3131 { 3132 xmlChar *msg = NULL; 3133 3134 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node); 3135 if (message == NULL) { 3136 /* 3137 * Use default messages. 3138 */ 3139 if (type != NULL) { 3140 if (node->type == XML_ATTRIBUTE_NODE) 3141 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of "); 3142 else 3143 msg = xmlStrcat(msg, BAD_CAST "The character content is not a " 3144 "valid value of "); 3145 if (! xmlSchemaIsGlobalItem(type)) 3146 msg = xmlStrcat(msg, BAD_CAST "the local "); 3147 else 3148 msg = xmlStrcat(msg, BAD_CAST "the "); 3149 3150 if (WXS_IS_ATOMIC(type)) 3151 msg = xmlStrcat(msg, BAD_CAST "atomic type"); 3152 else if (WXS_IS_LIST(type)) 3153 msg = xmlStrcat(msg, BAD_CAST "list type"); 3154 else if (WXS_IS_UNION(type)) 3155 msg = xmlStrcat(msg, BAD_CAST "union type"); 3156 3157 if (xmlSchemaIsGlobalItem(type)) { 3158 xmlChar *str = NULL; 3159 msg = xmlStrcat(msg, BAD_CAST " '"); 3160 if (type->builtInType != 0) { 3161 msg = xmlStrcat(msg, BAD_CAST "xs:"); 3162 str = xmlStrdup(type->name); 3163 } else { 3164 const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); 3165 if (!str) 3166 str = xmlStrdup(qName); 3167 } 3168 msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); 3169 msg = xmlStrcat(msg, BAD_CAST "'."); 3170 FREE_AND_NULL(str); 3171 } 3172 } else { 3173 if (node->type == XML_ATTRIBUTE_NODE) 3174 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid."); 3175 else 3176 msg = xmlStrcat(msg, BAD_CAST "The character content is not " 3177 "valid."); 3178 } 3179 if (expected) { 3180 xmlChar *expectedEscaped = xmlCharStrdup(expected); 3181 msg = xmlStrcat(msg, BAD_CAST " Expected is '"); 3182 msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped)); 3183 FREE_AND_NULL(expectedEscaped); 3184 msg = xmlStrcat(msg, BAD_CAST "'.\n"); 3185 } else 3186 msg = xmlStrcat(msg, BAD_CAST "\n"); 3187 if (node->type == XML_ATTRIBUTE_NODE) 3188 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); 3189 else 3190 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); 3191 } else { 3192 msg = xmlStrcat(msg, BAD_CAST message); 3193 msg = xmlStrcat(msg, BAD_CAST ".\n"); 3194 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, 3195 (const char*) msg, str1, str2, NULL, NULL, NULL); 3196 } 3197 /* Cleanup. */ 3198 FREE_AND_NULL(msg) 3199 } 3200 3201 /** 3202 * xmlSchemaPContentErr: 3203 * @ctxt: the schema parser context 3204 * @error: the error code 3205 * @onwerDes: the designation of the holder of the content 3206 * @ownerItem: the owner item of the holder of the content 3207 * @ownerElem: the node of the holder of the content 3208 * @child: the invalid child node 3209 * @message: the optional error message 3210 * @content: the optional string describing the correct content 3211 * 3212 * Reports an error concerning the content of a schema element. 3213 */ 3214 static void 3215 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt, 3216 xmlParserErrors error, 3217 xmlSchemaBasicItemPtr ownerItem, 3218 xmlNodePtr ownerElem, 3219 xmlNodePtr child, 3220 const char *message, 3221 const char *content) 3222 { 3223 xmlChar *des = NULL; 3224 3225 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); 3226 if (message != NULL) 3227 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3228 "%s: %s.\n", 3229 BAD_CAST des, BAD_CAST message); 3230 else { 3231 if (content != NULL) { 3232 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3233 "%s: The content is not valid. Expected is %s.\n", 3234 BAD_CAST des, BAD_CAST content); 3235 } else { 3236 xmlSchemaPErr2(ctxt, ownerElem, child, error, 3237 "%s: The content is not valid.\n", 3238 BAD_CAST des, NULL); 3239 } 3240 } 3241 FREE_AND_NULL(des) 3242 } 3243 3244 /************************************************************************ 3245 * * 3246 * Streamable error functions * 3247 * * 3248 ************************************************************************/ 3249 3250 3251 3252 3253 /************************************************************************ 3254 * * 3255 * Validation helper functions * 3256 * * 3257 ************************************************************************/ 3258 3259 3260 /************************************************************************ 3261 * * 3262 * Allocation functions * 3263 * * 3264 ************************************************************************/ 3265 3266 /** 3267 * xmlSchemaNewSchemaForParserCtxt: 3268 * @ctxt: a schema validation context 3269 * 3270 * Allocate a new Schema structure. 3271 * 3272 * Returns the newly allocated structure or NULL in case or error 3273 */ 3274 static xmlSchemaPtr 3275 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) 3276 { 3277 xmlSchemaPtr ret; 3278 3279 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema)); 3280 if (ret == NULL) { 3281 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL); 3282 return (NULL); 3283 } 3284 memset(ret, 0, sizeof(xmlSchema)); 3285 ret->dict = ctxt->dict; 3286 xmlDictReference(ret->dict); 3287 3288 return (ret); 3289 } 3290 3291 /** 3292 * xmlSchemaNewFacet: 3293 * 3294 * Allocate a new Facet structure. 3295 * 3296 * Returns the newly allocated structure or NULL in case or error 3297 */ 3298 xmlSchemaFacetPtr 3299 xmlSchemaNewFacet(void) 3300 { 3301 xmlSchemaFacetPtr ret; 3302 3303 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); 3304 if (ret == NULL) { 3305 return (NULL); 3306 } 3307 memset(ret, 0, sizeof(xmlSchemaFacet)); 3308 3309 return (ret); 3310 } 3311 3312 /** 3313 * xmlSchemaNewAnnot: 3314 * @ctxt: a schema validation context 3315 * @node: a node 3316 * 3317 * Allocate a new annotation structure. 3318 * 3319 * Returns the newly allocated structure or NULL in case or error 3320 */ 3321 static xmlSchemaAnnotPtr 3322 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 3323 { 3324 xmlSchemaAnnotPtr ret; 3325 3326 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot)); 3327 if (ret == NULL) { 3328 xmlSchemaPErrMemory(ctxt, "allocating annotation", node); 3329 return (NULL); 3330 } 3331 memset(ret, 0, sizeof(xmlSchemaAnnot)); 3332 ret->content = node; 3333 return (ret); 3334 } 3335 3336 static xmlSchemaItemListPtr 3337 xmlSchemaItemListCreate(void) 3338 { 3339 xmlSchemaItemListPtr ret; 3340 3341 ret = xmlMalloc(sizeof(xmlSchemaItemList)); 3342 if (ret == NULL) { 3343 xmlSchemaPErrMemory(NULL, 3344 "allocating an item list structure", NULL); 3345 return (NULL); 3346 } 3347 memset(ret, 0, sizeof(xmlSchemaItemList)); 3348 return (ret); 3349 } 3350 3351 static void 3352 xmlSchemaItemListClear(xmlSchemaItemListPtr list) 3353 { 3354 if (list->items != NULL) { 3355 xmlFree(list->items); 3356 list->items = NULL; 3357 } 3358 list->nbItems = 0; 3359 list->sizeItems = 0; 3360 } 3361 3362 static int 3363 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item) 3364 { 3365 if (list->items == NULL) { 3366 list->items = (void **) xmlMalloc( 3367 20 * sizeof(void *)); 3368 if (list->items == NULL) { 3369 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3370 return(-1); 3371 } 3372 list->sizeItems = 20; 3373 } else if (list->sizeItems <= list->nbItems) { 3374 list->sizeItems *= 2; 3375 list->items = (void **) xmlRealloc(list->items, 3376 list->sizeItems * sizeof(void *)); 3377 if (list->items == NULL) { 3378 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3379 list->sizeItems = 0; 3380 return(-1); 3381 } 3382 } 3383 list->items[list->nbItems++] = item; 3384 return(0); 3385 } 3386 3387 static int 3388 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list, 3389 int initialSize, 3390 void *item) 3391 { 3392 if (list->items == NULL) { 3393 if (initialSize <= 0) 3394 initialSize = 1; 3395 list->items = (void **) xmlMalloc( 3396 initialSize * sizeof(void *)); 3397 if (list->items == NULL) { 3398 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3399 return(-1); 3400 } 3401 list->sizeItems = initialSize; 3402 } else if (list->sizeItems <= list->nbItems) { 3403 list->sizeItems *= 2; 3404 list->items = (void **) xmlRealloc(list->items, 3405 list->sizeItems * sizeof(void *)); 3406 if (list->items == NULL) { 3407 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3408 list->sizeItems = 0; 3409 return(-1); 3410 } 3411 } 3412 list->items[list->nbItems++] = item; 3413 return(0); 3414 } 3415 3416 static int 3417 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx) 3418 { 3419 if (list->items == NULL) { 3420 list->items = (void **) xmlMalloc( 3421 20 * sizeof(void *)); 3422 if (list->items == NULL) { 3423 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3424 return(-1); 3425 } 3426 list->sizeItems = 20; 3427 } else if (list->sizeItems <= list->nbItems) { 3428 list->sizeItems *= 2; 3429 list->items = (void **) xmlRealloc(list->items, 3430 list->sizeItems * sizeof(void *)); 3431 if (list->items == NULL) { 3432 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3433 list->sizeItems = 0; 3434 return(-1); 3435 } 3436 } 3437 /* 3438 * Just append if the index is greater/equal than the item count. 3439 */ 3440 if (idx >= list->nbItems) { 3441 list->items[list->nbItems++] = item; 3442 } else { 3443 int i; 3444 for (i = list->nbItems; i > idx; i--) 3445 list->items[i] = list->items[i-1]; 3446 list->items[idx] = item; 3447 list->nbItems++; 3448 } 3449 return(0); 3450 } 3451 3452 #if 0 /* enable if ever needed */ 3453 static int 3454 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list, 3455 int initialSize, 3456 void *item, 3457 int idx) 3458 { 3459 if (list->items == NULL) { 3460 if (initialSize <= 0) 3461 initialSize = 1; 3462 list->items = (void **) xmlMalloc( 3463 initialSize * sizeof(void *)); 3464 if (list->items == NULL) { 3465 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL); 3466 return(-1); 3467 } 3468 list->sizeItems = initialSize; 3469 } else if (list->sizeItems <= list->nbItems) { 3470 list->sizeItems *= 2; 3471 list->items = (void **) xmlRealloc(list->items, 3472 list->sizeItems * sizeof(void *)); 3473 if (list->items == NULL) { 3474 xmlSchemaPErrMemory(NULL, "growing item list", NULL); 3475 list->sizeItems = 0; 3476 return(-1); 3477 } 3478 } 3479 /* 3480 * Just append if the index is greater/equal than the item count. 3481 */ 3482 if (idx >= list->nbItems) { 3483 list->items[list->nbItems++] = item; 3484 } else { 3485 int i; 3486 for (i = list->nbItems; i > idx; i--) 3487 list->items[i] = list->items[i-1]; 3488 list->items[idx] = item; 3489 list->nbItems++; 3490 } 3491 return(0); 3492 } 3493 #endif 3494 3495 static int 3496 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx) 3497 { 3498 int i; 3499 if ((list->items == NULL) || (idx >= list->nbItems)) { 3500 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, " 3501 "index error.\n"); 3502 return(-1); 3503 } 3504 3505 if (list->nbItems == 1) { 3506 /* TODO: Really free the list? */ 3507 xmlFree(list->items); 3508 list->items = NULL; 3509 list->nbItems = 0; 3510 list->sizeItems = 0; 3511 } else if (list->nbItems -1 == idx) { 3512 list->nbItems--; 3513 } else { 3514 for (i = idx; i < list->nbItems -1; i++) 3515 list->items[i] = list->items[i+1]; 3516 list->nbItems--; 3517 } 3518 return(0); 3519 } 3520 3521 /** 3522 * xmlSchemaItemListFree: 3523 * @annot: a schema type structure 3524 * 3525 * Deallocate a annotation structure 3526 */ 3527 static void 3528 xmlSchemaItemListFree(xmlSchemaItemListPtr list) 3529 { 3530 if (list == NULL) 3531 return; 3532 if (list->items != NULL) 3533 xmlFree(list->items); 3534 xmlFree(list); 3535 } 3536 3537 static void 3538 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) 3539 { 3540 if (bucket == NULL) 3541 return; 3542 if (bucket->globals != NULL) { 3543 xmlSchemaComponentListFree(bucket->globals); 3544 xmlSchemaItemListFree(bucket->globals); 3545 } 3546 if (bucket->locals != NULL) { 3547 xmlSchemaComponentListFree(bucket->locals); 3548 xmlSchemaItemListFree(bucket->locals); 3549 } 3550 if (bucket->relations != NULL) { 3551 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations; 3552 do { 3553 prev = cur; 3554 cur = cur->next; 3555 xmlFree(prev); 3556 } while (cur != NULL); 3557 } 3558 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) { 3559 xmlFreeDoc(bucket->doc); 3560 } 3561 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) { 3562 if (WXS_IMPBUCKET(bucket)->schema != NULL) 3563 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema); 3564 } 3565 xmlFree(bucket); 3566 } 3567 3568 static void 3569 xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED) 3570 { 3571 xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket); 3572 } 3573 3574 static xmlSchemaBucketPtr 3575 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, 3576 int type, const xmlChar *targetNamespace) 3577 { 3578 xmlSchemaBucketPtr ret; 3579 int size; 3580 xmlSchemaPtr mainSchema; 3581 3582 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) { 3583 PERROR_INT("xmlSchemaBucketCreate", 3584 "no main schema on constructor"); 3585 return(NULL); 3586 } 3587 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema; 3588 /* Create the schema bucket. */ 3589 if (WXS_IS_BUCKET_INCREDEF(type)) 3590 size = sizeof(xmlSchemaInclude); 3591 else 3592 size = sizeof(xmlSchemaImport); 3593 ret = (xmlSchemaBucketPtr) xmlMalloc(size); 3594 if (ret == NULL) { 3595 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL); 3596 return(NULL); 3597 } 3598 memset(ret, 0, size); 3599 ret->targetNamespace = targetNamespace; 3600 ret->type = type; 3601 ret->globals = xmlSchemaItemListCreate(); 3602 if (ret->globals == NULL) { 3603 xmlFree(ret); 3604 return(NULL); 3605 } 3606 ret->locals = xmlSchemaItemListCreate(); 3607 if (ret->locals == NULL) { 3608 xmlFree(ret); 3609 return(NULL); 3610 } 3611 /* 3612 * The following will assure that only the first bucket is marked as 3613 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema. 3614 * For each following import buckets an xmlSchema will be created. 3615 * An xmlSchema will be created for every distinct targetNamespace. 3616 * We assign the targetNamespace to the schemata here. 3617 */ 3618 if (! WXS_HAS_BUCKETS(pctxt)) { 3619 if (WXS_IS_BUCKET_INCREDEF(type)) { 3620 PERROR_INT("xmlSchemaBucketCreate", 3621 "first bucket but it's an include or redefine"); 3622 xmlSchemaBucketFree(ret); 3623 return(NULL); 3624 } 3625 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */ 3626 ret->type = XML_SCHEMA_SCHEMA_MAIN; 3627 /* Point to the *main* schema. */ 3628 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret; 3629 WXS_IMPBUCKET(ret)->schema = mainSchema; 3630 /* 3631 * Ensure that the main schema gets a targetNamespace. 3632 */ 3633 mainSchema->targetNamespace = targetNamespace; 3634 } else { 3635 if (type == XML_SCHEMA_SCHEMA_MAIN) { 3636 PERROR_INT("xmlSchemaBucketCreate", 3637 "main bucket but it's not the first one"); 3638 xmlSchemaBucketFree(ret); 3639 return(NULL); 3640 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) { 3641 /* 3642 * Create a schema for imports and assign the 3643 * targetNamespace. 3644 */ 3645 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt); 3646 if (WXS_IMPBUCKET(ret)->schema == NULL) { 3647 xmlSchemaBucketFree(ret); 3648 return(NULL); 3649 } 3650 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace; 3651 } 3652 } 3653 if (WXS_IS_BUCKET_IMPMAIN(type)) { 3654 int res; 3655 /* 3656 * Imports go into the "schemasImports" slot of the main *schema*. 3657 * Note that we create an import entry for the main schema as well; i.e., 3658 * even if there's only one schema, we'll get an import. 3659 */ 3660 if (mainSchema->schemasImports == NULL) { 3661 mainSchema->schemasImports = xmlHashCreateDict(5, 3662 WXS_CONSTRUCTOR(pctxt)->dict); 3663 if (mainSchema->schemasImports == NULL) { 3664 xmlSchemaBucketFree(ret); 3665 return(NULL); 3666 } 3667 } 3668 if (targetNamespace == NULL) 3669 res = xmlHashAddEntry(mainSchema->schemasImports, 3670 XML_SCHEMAS_NO_NAMESPACE, ret); 3671 else 3672 res = xmlHashAddEntry(mainSchema->schemasImports, 3673 targetNamespace, ret); 3674 if (res != 0) { 3675 PERROR_INT("xmlSchemaBucketCreate", 3676 "failed to add the schema bucket to the hash"); 3677 xmlSchemaBucketFree(ret); 3678 return(NULL); 3679 } 3680 } else { 3681 /* Set the @ownerImport of an include bucket. */ 3682 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type)) 3683 WXS_INCBUCKET(ret)->ownerImport = 3684 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket); 3685 else 3686 WXS_INCBUCKET(ret)->ownerImport = 3687 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport; 3688 3689 /* Includes got into the "includes" slot of the *main* schema. */ 3690 if (mainSchema->includes == NULL) { 3691 mainSchema->includes = xmlSchemaItemListCreate(); 3692 if (mainSchema->includes == NULL) { 3693 xmlSchemaBucketFree(ret); 3694 return(NULL); 3695 } 3696 } 3697 xmlSchemaItemListAdd(mainSchema->includes, ret); 3698 } 3699 /* 3700 * Add to list of all buckets; this is used for lookup 3701 * during schema construction time only. 3702 */ 3703 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1) 3704 return(NULL); 3705 return(ret); 3706 } 3707 3708 static int 3709 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item) 3710 { 3711 if (*list == NULL) { 3712 *list = xmlSchemaItemListCreate(); 3713 if (*list == NULL) 3714 return(-1); 3715 } 3716 xmlSchemaItemListAddSize(*list, initialSize, item); 3717 return(0); 3718 } 3719 3720 /** 3721 * xmlSchemaFreeAnnot: 3722 * @annot: a schema type structure 3723 * 3724 * Deallocate a annotation structure 3725 */ 3726 static void 3727 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot) 3728 { 3729 if (annot == NULL) 3730 return; 3731 if (annot->next == NULL) { 3732 xmlFree(annot); 3733 } else { 3734 xmlSchemaAnnotPtr prev; 3735 3736 do { 3737 prev = annot; 3738 annot = annot->next; 3739 xmlFree(prev); 3740 } while (annot != NULL); 3741 } 3742 } 3743 3744 /** 3745 * xmlSchemaFreeNotation: 3746 * @schema: a schema notation structure 3747 * 3748 * Deallocate a Schema Notation structure. 3749 */ 3750 static void 3751 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota) 3752 { 3753 if (nota == NULL) 3754 return; 3755 xmlFree(nota); 3756 } 3757 3758 /** 3759 * xmlSchemaFreeAttribute: 3760 * @attr: an attribute declaration 3761 * 3762 * Deallocates an attribute declaration structure. 3763 */ 3764 static void 3765 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr) 3766 { 3767 if (attr == NULL) 3768 return; 3769 if (attr->annot != NULL) 3770 xmlSchemaFreeAnnot(attr->annot); 3771 if (attr->defVal != NULL) 3772 xmlSchemaFreeValue(attr->defVal); 3773 xmlFree(attr); 3774 } 3775 3776 /** 3777 * xmlSchemaFreeAttributeUse: 3778 * @use: an attribute use 3779 * 3780 * Deallocates an attribute use structure. 3781 */ 3782 static void 3783 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use) 3784 { 3785 if (use == NULL) 3786 return; 3787 if (use->annot != NULL) 3788 xmlSchemaFreeAnnot(use->annot); 3789 if (use->defVal != NULL) 3790 xmlSchemaFreeValue(use->defVal); 3791 xmlFree(use); 3792 } 3793 3794 /** 3795 * xmlSchemaFreeAttributeUseProhib: 3796 * @prohib: an attribute use prohibition 3797 * 3798 * Deallocates an attribute use structure. 3799 */ 3800 static void 3801 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib) 3802 { 3803 if (prohib == NULL) 3804 return; 3805 xmlFree(prohib); 3806 } 3807 3808 /** 3809 * xmlSchemaFreeWildcardNsSet: 3810 * set: a schema wildcard namespace 3811 * 3812 * Deallocates a list of wildcard constraint structures. 3813 */ 3814 static void 3815 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set) 3816 { 3817 xmlSchemaWildcardNsPtr next; 3818 3819 while (set != NULL) { 3820 next = set->next; 3821 xmlFree(set); 3822 set = next; 3823 } 3824 } 3825 3826 /** 3827 * xmlSchemaFreeWildcard: 3828 * @wildcard: a wildcard structure 3829 * 3830 * Deallocates a wildcard structure. 3831 */ 3832 void 3833 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard) 3834 { 3835 if (wildcard == NULL) 3836 return; 3837 if (wildcard->annot != NULL) 3838 xmlSchemaFreeAnnot(wildcard->annot); 3839 if (wildcard->nsSet != NULL) 3840 xmlSchemaFreeWildcardNsSet(wildcard->nsSet); 3841 if (wildcard->negNsSet != NULL) 3842 xmlFree(wildcard->negNsSet); 3843 xmlFree(wildcard); 3844 } 3845 3846 /** 3847 * xmlSchemaFreeAttributeGroup: 3848 * @schema: a schema attribute group structure 3849 * 3850 * Deallocate a Schema Attribute Group structure. 3851 */ 3852 static void 3853 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr) 3854 { 3855 if (attrGr == NULL) 3856 return; 3857 if (attrGr->annot != NULL) 3858 xmlSchemaFreeAnnot(attrGr->annot); 3859 if (attrGr->attrUses != NULL) 3860 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses); 3861 xmlFree(attrGr); 3862 } 3863 3864 /** 3865 * xmlSchemaFreeQNameRef: 3866 * @item: a QName reference structure 3867 * 3868 * Deallocatea a QName reference structure. 3869 */ 3870 static void 3871 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item) 3872 { 3873 xmlFree(item); 3874 } 3875 3876 /** 3877 * xmlSchemaFreeTypeLinkList: 3878 * @alink: a type link 3879 * 3880 * Deallocate a list of types. 3881 */ 3882 static void 3883 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link) 3884 { 3885 xmlSchemaTypeLinkPtr next; 3886 3887 while (link != NULL) { 3888 next = link->next; 3889 xmlFree(link); 3890 link = next; 3891 } 3892 } 3893 3894 static void 3895 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto) 3896 { 3897 xmlSchemaIDCStateObjPtr next; 3898 while (sto != NULL) { 3899 next = sto->next; 3900 if (sto->history != NULL) 3901 xmlFree(sto->history); 3902 if (sto->xpathCtxt != NULL) 3903 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt); 3904 xmlFree(sto); 3905 sto = next; 3906 } 3907 } 3908 3909 /** 3910 * xmlSchemaFreeIDC: 3911 * @idc: a identity-constraint definition 3912 * 3913 * Deallocates an identity-constraint definition. 3914 */ 3915 static void 3916 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef) 3917 { 3918 xmlSchemaIDCSelectPtr cur, prev; 3919 3920 if (idcDef == NULL) 3921 return; 3922 if (idcDef->annot != NULL) 3923 xmlSchemaFreeAnnot(idcDef->annot); 3924 /* Selector */ 3925 if (idcDef->selector != NULL) { 3926 if (idcDef->selector->xpathComp != NULL) 3927 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp); 3928 xmlFree(idcDef->selector); 3929 } 3930 /* Fields */ 3931 if (idcDef->fields != NULL) { 3932 cur = idcDef->fields; 3933 do { 3934 prev = cur; 3935 cur = cur->next; 3936 if (prev->xpathComp != NULL) 3937 xmlFreePattern((xmlPatternPtr) prev->xpathComp); 3938 xmlFree(prev); 3939 } while (cur != NULL); 3940 } 3941 xmlFree(idcDef); 3942 } 3943 3944 /** 3945 * xmlSchemaFreeElement: 3946 * @schema: a schema element structure 3947 * 3948 * Deallocate a Schema Element structure. 3949 */ 3950 static void 3951 xmlSchemaFreeElement(xmlSchemaElementPtr elem) 3952 { 3953 if (elem == NULL) 3954 return; 3955 if (elem->annot != NULL) 3956 xmlSchemaFreeAnnot(elem->annot); 3957 if (elem->contModel != NULL) 3958 xmlRegFreeRegexp(elem->contModel); 3959 if (elem->defVal != NULL) 3960 xmlSchemaFreeValue(elem->defVal); 3961 xmlFree(elem); 3962 } 3963 3964 /** 3965 * xmlSchemaFreeFacet: 3966 * @facet: a schema facet structure 3967 * 3968 * Deallocate a Schema Facet structure. 3969 */ 3970 void 3971 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) 3972 { 3973 if (facet == NULL) 3974 return; 3975 if (facet->val != NULL) 3976 xmlSchemaFreeValue(facet->val); 3977 if (facet->regexp != NULL) 3978 xmlRegFreeRegexp(facet->regexp); 3979 if (facet->annot != NULL) 3980 xmlSchemaFreeAnnot(facet->annot); 3981 xmlFree(facet); 3982 } 3983 3984 /** 3985 * xmlSchemaFreeType: 3986 * @type: a schema type structure 3987 * 3988 * Deallocate a Schema Type structure. 3989 */ 3990 void 3991 xmlSchemaFreeType(xmlSchemaTypePtr type) 3992 { 3993 if (type == NULL) 3994 return; 3995 if (type->annot != NULL) 3996 xmlSchemaFreeAnnot(type->annot); 3997 if (type->facets != NULL) { 3998 xmlSchemaFacetPtr facet, next; 3999 4000 facet = type->facets; 4001 while (facet != NULL) { 4002 next = facet->next; 4003 xmlSchemaFreeFacet(facet); 4004 facet = next; 4005 } 4006 } 4007 if (type->attrUses != NULL) 4008 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses); 4009 if (type->memberTypes != NULL) 4010 xmlSchemaFreeTypeLinkList(type->memberTypes); 4011 if (type->facetSet != NULL) { 4012 xmlSchemaFacetLinkPtr next, link; 4013 4014 link = type->facetSet; 4015 do { 4016 next = link->next; 4017 xmlFree(link); 4018 link = next; 4019 } while (link != NULL); 4020 } 4021 if (type->contModel != NULL) 4022 xmlRegFreeRegexp(type->contModel); 4023 xmlFree(type); 4024 } 4025 4026 /** 4027 * xmlSchemaFreeModelGroupDef: 4028 * @item: a schema model group definition 4029 * 4030 * Deallocates a schema model group definition. 4031 */ 4032 static void 4033 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item) 4034 { 4035 if (item->annot != NULL) 4036 xmlSchemaFreeAnnot(item->annot); 4037 xmlFree(item); 4038 } 4039 4040 /** 4041 * xmlSchemaFreeModelGroup: 4042 * @item: a schema model group 4043 * 4044 * Deallocates a schema model group structure. 4045 */ 4046 static void 4047 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item) 4048 { 4049 if (item->annot != NULL) 4050 xmlSchemaFreeAnnot(item->annot); 4051 xmlFree(item); 4052 } 4053 4054 static void 4055 xmlSchemaComponentListFree(xmlSchemaItemListPtr list) 4056 { 4057 if ((list == NULL) || (list->nbItems == 0)) 4058 return; 4059 { 4060 xmlSchemaTreeItemPtr item; 4061 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items; 4062 int i; 4063 4064 for (i = 0; i < list->nbItems; i++) { 4065 item = items[i]; 4066 if (item == NULL) 4067 continue; 4068 switch (item->type) { 4069 case XML_SCHEMA_TYPE_SIMPLE: 4070 case XML_SCHEMA_TYPE_COMPLEX: 4071 xmlSchemaFreeType((xmlSchemaTypePtr) item); 4072 break; 4073 case XML_SCHEMA_TYPE_ATTRIBUTE: 4074 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item); 4075 break; 4076 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: 4077 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item); 4078 break; 4079 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB: 4080 xmlSchemaFreeAttributeUseProhib( 4081 (xmlSchemaAttributeUseProhibPtr) item); 4082 break; 4083 case XML_SCHEMA_TYPE_ELEMENT: 4084 xmlSchemaFreeElement((xmlSchemaElementPtr) item); 4085 break; 4086 case XML_SCHEMA_TYPE_PARTICLE: 4087 if (item->annot != NULL) 4088 xmlSchemaFreeAnnot(item->annot); 4089 xmlFree(item); 4090 break; 4091 case XML_SCHEMA_TYPE_SEQUENCE: 4092 case XML_SCHEMA_TYPE_CHOICE: 4093 case XML_SCHEMA_TYPE_ALL: 4094 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item); 4095 break; 4096 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 4097 xmlSchemaFreeAttributeGroup( 4098 (xmlSchemaAttributeGroupPtr) item); 4099 break; 4100 case XML_SCHEMA_TYPE_GROUP: 4101 xmlSchemaFreeModelGroupDef( 4102 (xmlSchemaModelGroupDefPtr) item); 4103 break; 4104 case XML_SCHEMA_TYPE_ANY: 4105 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 4106 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item); 4107 break; 4108 case XML_SCHEMA_TYPE_IDC_KEY: 4109 case XML_SCHEMA_TYPE_IDC_UNIQUE: 4110 case XML_SCHEMA_TYPE_IDC_KEYREF: 4111 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item); 4112 break; 4113 case XML_SCHEMA_TYPE_NOTATION: 4114 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item); 4115 break; 4116 case XML_SCHEMA_EXTRA_QNAMEREF: 4117 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item); 4118 break; 4119 default: { 4120 /* TODO: This should never be hit. */ 4121 xmlSchemaPSimpleInternalErr(NULL, 4122 "Internal error: xmlSchemaComponentListFree, " 4123 "unexpected component type '%s'\n", 4124 (const xmlChar *) WXS_ITEM_TYPE_NAME(item)); 4125 } 4126 break; 4127 } 4128 } 4129 list->nbItems = 0; 4130 } 4131 } 4132 4133 /** 4134 * xmlSchemaFree: 4135 * @schema: a schema structure 4136 * 4137 * Deallocate a Schema structure. 4138 */ 4139 void 4140 xmlSchemaFree(xmlSchemaPtr schema) 4141 { 4142 if (schema == NULL) 4143 return; 4144 /* @volatiles is not used anymore :-/ */ 4145 if (schema->volatiles != NULL) 4146 TODO 4147 /* 4148 * Note that those slots are not responsible for freeing 4149 * schema components anymore; this will now be done by 4150 * the schema buckets. 4151 */ 4152 if (schema->notaDecl != NULL) 4153 xmlHashFree(schema->notaDecl, NULL); 4154 if (schema->attrDecl != NULL) 4155 xmlHashFree(schema->attrDecl, NULL); 4156 if (schema->attrgrpDecl != NULL) 4157 xmlHashFree(schema->attrgrpDecl, NULL); 4158 if (schema->elemDecl != NULL) 4159 xmlHashFree(schema->elemDecl, NULL); 4160 if (schema->typeDecl != NULL) 4161 xmlHashFree(schema->typeDecl, NULL); 4162 if (schema->groupDecl != NULL) 4163 xmlHashFree(schema->groupDecl, NULL); 4164 if (schema->idcDef != NULL) 4165 xmlHashFree(schema->idcDef, NULL); 4166 4167 if (schema->schemasImports != NULL) 4168 xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry); 4169 if (schema->includes != NULL) { 4170 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; 4171 int i; 4172 for (i = 0; i < list->nbItems; i++) { 4173 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]); 4174 } 4175 xmlSchemaItemListFree(list); 4176 } 4177 if (schema->annot != NULL) 4178 xmlSchemaFreeAnnot(schema->annot); 4179 /* Never free the doc here, since this will be done by the buckets. */ 4180 4181 xmlDictFree(schema->dict); 4182 xmlFree(schema); 4183 } 4184 4185 /************************************************************************ 4186 * * 4187 * Debug functions * 4188 * * 4189 ************************************************************************/ 4190 4191 #ifdef LIBXML_OUTPUT_ENABLED 4192 4193 static void 4194 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ 4195 4196 /** 4197 * xmlSchemaElementDump: 4198 * @elem: an element 4199 * @output: the file output 4200 * 4201 * Dump the element 4202 */ 4203 static void 4204 xmlSchemaElementDump(void *payload, void *data, 4205 const xmlChar * name ATTRIBUTE_UNUSED, 4206 const xmlChar * namespace ATTRIBUTE_UNUSED, 4207 const xmlChar * context ATTRIBUTE_UNUSED) 4208 { 4209 xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload; 4210 FILE *output = (FILE *) data; 4211 if (elem == NULL) 4212 return; 4213 4214 4215 fprintf(output, "Element"); 4216 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL) 4217 fprintf(output, " (global)"); 4218 fprintf(output, ": '%s' ", elem->name); 4219 if (namespace != NULL) 4220 fprintf(output, "ns '%s'", namespace); 4221 fprintf(output, "\n"); 4222 #if 0 4223 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) { 4224 fprintf(output, " min %d ", elem->minOccurs); 4225 if (elem->maxOccurs >= UNBOUNDED) 4226 fprintf(output, "max: unbounded\n"); 4227 else if (elem->maxOccurs != 1) 4228 fprintf(output, "max: %d\n", elem->maxOccurs); 4229 else 4230 fprintf(output, "\n"); 4231 } 4232 #endif 4233 /* 4234 * Misc other properties. 4235 */ 4236 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) || 4237 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) || 4238 (elem->flags & XML_SCHEMAS_ELEM_FIXED) || 4239 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) { 4240 fprintf(output, " props: "); 4241 if (elem->flags & XML_SCHEMAS_ELEM_FIXED) 4242 fprintf(output, "[fixed] "); 4243 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT) 4244 fprintf(output, "[default] "); 4245 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) 4246 fprintf(output, "[abstract] "); 4247 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE) 4248 fprintf(output, "[nillable] "); 4249 fprintf(output, "\n"); 4250 } 4251 /* 4252 * Default/fixed value. 4253 */ 4254 if (elem->value != NULL) 4255 fprintf(output, " value: '%s'\n", elem->value); 4256 /* 4257 * Type. 4258 */ 4259 if (elem->namedType != NULL) { 4260 fprintf(output, " type: '%s' ", elem->namedType); 4261 if (elem->namedTypeNs != NULL) 4262 fprintf(output, "ns '%s'\n", elem->namedTypeNs); 4263 else 4264 fprintf(output, "\n"); 4265 } else if (elem->subtypes != NULL) { 4266 /* 4267 * Dump local types. 4268 */ 4269 xmlSchemaTypeDump(elem->subtypes, output); 4270 } 4271 /* 4272 * Substitution group. 4273 */ 4274 if (elem->substGroup != NULL) { 4275 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup); 4276 if (elem->substGroupNs != NULL) 4277 fprintf(output, "ns '%s'\n", elem->substGroupNs); 4278 else 4279 fprintf(output, "\n"); 4280 } 4281 } 4282 4283 /** 4284 * xmlSchemaAnnotDump: 4285 * @output: the file output 4286 * @annot: a annotation 4287 * 4288 * Dump the annotation 4289 */ 4290 static void 4291 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot) 4292 { 4293 xmlChar *content; 4294 4295 if (annot == NULL) 4296 return; 4297 4298 content = xmlNodeGetContent(annot->content); 4299 if (content != NULL) { 4300 fprintf(output, " Annot: %s\n", content); 4301 xmlFree(content); 4302 } else 4303 fprintf(output, " Annot: empty\n"); 4304 } 4305 4306 /** 4307 * xmlSchemaContentModelDump: 4308 * @particle: the schema particle 4309 * @output: the file output 4310 * @depth: the depth used for intentation 4311 * 4312 * Dump a SchemaType structure 4313 */ 4314 static void 4315 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth) 4316 { 4317 xmlChar *str = NULL; 4318 xmlSchemaTreeItemPtr term; 4319 char shift[100]; 4320 int i; 4321 4322 if (particle == NULL) 4323 return; 4324 for (i = 0;((i < depth) && (i < 25));i++) 4325 shift[2 * i] = shift[2 * i + 1] = ' '; 4326 shift[2 * i] = shift[2 * i + 1] = 0; 4327 fprintf(output, "%s", shift); 4328 if (particle->children == NULL) { 4329 fprintf(output, "MISSING particle term\n"); 4330 return; 4331 } 4332 term = particle->children; 4333 if (term == NULL) { 4334 fprintf(output, "(NULL)"); 4335 } else { 4336 switch (term->type) { 4337 case XML_SCHEMA_TYPE_ELEMENT: 4338 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str, 4339 ((xmlSchemaElementPtr)term)->targetNamespace, 4340 ((xmlSchemaElementPtr)term)->name)); 4341 FREE_AND_NULL(str); 4342 break; 4343 case XML_SCHEMA_TYPE_SEQUENCE: 4344 fprintf(output, "SEQUENCE"); 4345 break; 4346 case XML_SCHEMA_TYPE_CHOICE: 4347 fprintf(output, "CHOICE"); 4348 break; 4349 case XML_SCHEMA_TYPE_ALL: 4350 fprintf(output, "ALL"); 4351 break; 4352 case XML_SCHEMA_TYPE_ANY: 4353 fprintf(output, "ANY"); 4354 break; 4355 default: 4356 fprintf(output, "UNKNOWN\n"); 4357 return; 4358 } 4359 } 4360 if (particle->minOccurs != 1) 4361 fprintf(output, " min: %d", particle->minOccurs); 4362 if (particle->maxOccurs >= UNBOUNDED) 4363 fprintf(output, " max: unbounded"); 4364 else if (particle->maxOccurs != 1) 4365 fprintf(output, " max: %d", particle->maxOccurs); 4366 fprintf(output, "\n"); 4367 if (term && 4368 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) || 4369 (term->type == XML_SCHEMA_TYPE_CHOICE) || 4370 (term->type == XML_SCHEMA_TYPE_ALL)) && 4371 (term->children != NULL)) { 4372 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children, 4373 output, depth +1); 4374 } 4375 if (particle->next != NULL) 4376 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next, 4377 output, depth); 4378 } 4379 4380 /** 4381 * xmlSchemaAttrUsesDump: 4382 * @uses: attribute uses list 4383 * @output: the file output 4384 * 4385 * Dumps a list of attribute use components. 4386 */ 4387 static void 4388 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output) 4389 { 4390 xmlSchemaAttributeUsePtr use; 4391 xmlSchemaAttributeUseProhibPtr prohib; 4392 xmlSchemaQNameRefPtr ref; 4393 const xmlChar *name, *tns; 4394 xmlChar *str = NULL; 4395 int i; 4396 4397 if ((uses == NULL) || (uses->nbItems == 0)) 4398 return; 4399 4400 fprintf(output, " attributes:\n"); 4401 for (i = 0; i < uses->nbItems; i++) { 4402 use = uses->items[i]; 4403 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) { 4404 fprintf(output, " [prohibition] "); 4405 prohib = (xmlSchemaAttributeUseProhibPtr) use; 4406 name = prohib->name; 4407 tns = prohib->targetNamespace; 4408 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) { 4409 fprintf(output, " [reference] "); 4410 ref = (xmlSchemaQNameRefPtr) use; 4411 name = ref->name; 4412 tns = ref->targetNamespace; 4413 } else { 4414 fprintf(output, " [use] "); 4415 name = WXS_ATTRUSE_DECL_NAME(use); 4416 tns = WXS_ATTRUSE_DECL_TNS(use); 4417 } 4418 fprintf(output, "'%s'\n", 4419 (const char *) xmlSchemaFormatQName(&str, tns, name)); 4420 FREE_AND_NULL(str); 4421 } 4422 } 4423 4424 /** 4425 * xmlSchemaTypeDump: 4426 * @output: the file output 4427 * @type: a type structure 4428 * 4429 * Dump a SchemaType structure 4430 */ 4431 static void 4432 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) 4433 { 4434 if (type == NULL) { 4435 fprintf(output, "Type: NULL\n"); 4436 return; 4437 } 4438 fprintf(output, "Type: "); 4439 if (type->name != NULL) 4440 fprintf(output, "'%s' ", type->name); 4441 else 4442 fprintf(output, "(no name) "); 4443 if (type->targetNamespace != NULL) 4444 fprintf(output, "ns '%s' ", type->targetNamespace); 4445 switch (type->type) { 4446 case XML_SCHEMA_TYPE_BASIC: 4447 fprintf(output, "[basic] "); 4448 break; 4449 case XML_SCHEMA_TYPE_SIMPLE: 4450 fprintf(output, "[simple] "); 4451 break; 4452 case XML_SCHEMA_TYPE_COMPLEX: 4453 fprintf(output, "[complex] "); 4454 break; 4455 case XML_SCHEMA_TYPE_SEQUENCE: 4456 fprintf(output, "[sequence] "); 4457 break; 4458 case XML_SCHEMA_TYPE_CHOICE: 4459 fprintf(output, "[choice] "); 4460 break; 4461 case XML_SCHEMA_TYPE_ALL: 4462 fprintf(output, "[all] "); 4463 break; 4464 case XML_SCHEMA_TYPE_UR: 4465 fprintf(output, "[ur] "); 4466 break; 4467 case XML_SCHEMA_TYPE_RESTRICTION: 4468 fprintf(output, "[restriction] "); 4469 break; 4470 case XML_SCHEMA_TYPE_EXTENSION: 4471 fprintf(output, "[extension] "); 4472 break; 4473 default: 4474 fprintf(output, "[unknown type %d] ", type->type); 4475 break; 4476 } 4477 fprintf(output, "content: "); 4478 switch (type->contentType) { 4479 case XML_SCHEMA_CONTENT_UNKNOWN: 4480 fprintf(output, "[unknown] "); 4481 break; 4482 case XML_SCHEMA_CONTENT_EMPTY: 4483 fprintf(output, "[empty] "); 4484 break; 4485 case XML_SCHEMA_CONTENT_ELEMENTS: 4486 fprintf(output, "[element] "); 4487 break; 4488 case XML_SCHEMA_CONTENT_MIXED: 4489 fprintf(output, "[mixed] "); 4490 break; 4491 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 4492 /* not used. */ 4493 break; 4494 case XML_SCHEMA_CONTENT_BASIC: 4495 fprintf(output, "[basic] "); 4496 break; 4497 case XML_SCHEMA_CONTENT_SIMPLE: 4498 fprintf(output, "[simple] "); 4499 break; 4500 case XML_SCHEMA_CONTENT_ANY: 4501 fprintf(output, "[any] "); 4502 break; 4503 } 4504 fprintf(output, "\n"); 4505 if (type->base != NULL) { 4506 fprintf(output, " base type: '%s'", type->base); 4507 if (type->baseNs != NULL) 4508 fprintf(output, " ns '%s'\n", type->baseNs); 4509 else 4510 fprintf(output, "\n"); 4511 } 4512 if (type->attrUses != NULL) 4513 xmlSchemaAttrUsesDump(type->attrUses, output); 4514 if (type->annot != NULL) 4515 xmlSchemaAnnotDump(output, type->annot); 4516 #ifdef DUMP_CONTENT_MODEL 4517 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) && 4518 (type->subtypes != NULL)) { 4519 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes, 4520 output, 1); 4521 } 4522 #endif 4523 } 4524 4525 static void 4526 xmlSchemaTypeDumpEntry(void *type, void *output, 4527 const xmlChar *name ATTRIBUTE_UNUSED) 4528 { 4529 xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output); 4530 } 4531 4532 /** 4533 * xmlSchemaDump: 4534 * @output: the file output 4535 * @schema: a schema structure 4536 * 4537 * Dump a Schema structure. 4538 */ 4539 void 4540 xmlSchemaDump(FILE * output, xmlSchemaPtr schema) 4541 { 4542 if (output == NULL) 4543 return; 4544 if (schema == NULL) { 4545 fprintf(output, "Schemas: NULL\n"); 4546 return; 4547 } 4548 fprintf(output, "Schemas: "); 4549 if (schema->name != NULL) 4550 fprintf(output, "%s, ", schema->name); 4551 else 4552 fprintf(output, "no name, "); 4553 if (schema->targetNamespace != NULL) 4554 fprintf(output, "%s", (const char *) schema->targetNamespace); 4555 else 4556 fprintf(output, "no target namespace"); 4557 fprintf(output, "\n"); 4558 if (schema->annot != NULL) 4559 xmlSchemaAnnotDump(output, schema->annot); 4560 xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output); 4561 xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output); 4562 } 4563 4564 #ifdef DEBUG_IDC_NODE_TABLE 4565 /** 4566 * xmlSchemaDebugDumpIDCTable: 4567 * @vctxt: the WXS validation context 4568 * 4569 * Displays the current IDC table for debug purposes. 4570 */ 4571 static void 4572 xmlSchemaDebugDumpIDCTable(FILE * output, 4573 const xmlChar *namespaceName, 4574 const xmlChar *localName, 4575 xmlSchemaPSVIIDCBindingPtr bind) 4576 { 4577 xmlChar *str = NULL; 4578 const xmlChar *value; 4579 xmlSchemaPSVIIDCNodePtr tab; 4580 xmlSchemaPSVIIDCKeyPtr key; 4581 int i, j, res; 4582 4583 fprintf(output, "IDC: TABLES on '%s'\n", 4584 xmlSchemaFormatQName(&str, namespaceName, localName)); 4585 FREE_AND_NULL(str) 4586 4587 if (bind == NULL) 4588 return; 4589 do { 4590 fprintf(output, "IDC: BINDING '%s' (%d)\n", 4591 xmlSchemaGetComponentQName(&str, 4592 bind->definition), bind->nbNodes); 4593 FREE_AND_NULL(str) 4594 for (i = 0; i < bind->nbNodes; i++) { 4595 tab = bind->nodeTable[i]; 4596 fprintf(output, " ( "); 4597 for (j = 0; j < bind->definition->nbFields; j++) { 4598 key = tab->keys[j]; 4599 if ((key != NULL) && (key->val != NULL)) { 4600 res = xmlSchemaGetCanonValue(key->val, &value); 4601 if (res >= 0) 4602 fprintf(output, "'%s' ", value); 4603 else 4604 fprintf(output, "CANON-VALUE-FAILED "); 4605 if (res == 0) 4606 FREE_AND_NULL(value) 4607 } else if (key != NULL) 4608 fprintf(output, "(no val), "); 4609 else 4610 fprintf(output, "(key missing), "); 4611 } 4612 fprintf(output, ")\n"); 4613 } 4614 if (bind->dupls && bind->dupls->nbItems) { 4615 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems); 4616 for (i = 0; i < bind->dupls->nbItems; i++) { 4617 tab = bind->dupls->items[i]; 4618 fprintf(output, " ( "); 4619 for (j = 0; j < bind->definition->nbFields; j++) { 4620 key = tab->keys[j]; 4621 if ((key != NULL) && (key->val != NULL)) { 4622 res = xmlSchemaGetCanonValue(key->val, &value); 4623 if (res >= 0) 4624 fprintf(output, "'%s' ", value); 4625 else 4626 fprintf(output, "CANON-VALUE-FAILED "); 4627 if (res == 0) 4628 FREE_AND_NULL(value) 4629 } else if (key != NULL) 4630 fprintf(output, "(no val), "); 4631 else 4632 fprintf(output, "(key missing), "); 4633 } 4634 fprintf(output, ")\n"); 4635 } 4636 } 4637 bind = bind->next; 4638 } while (bind != NULL); 4639 } 4640 #endif /* DEBUG_IDC */ 4641 #endif /* LIBXML_OUTPUT_ENABLED */ 4642 4643 /************************************************************************ 4644 * * 4645 * Utilities * 4646 * * 4647 ************************************************************************/ 4648 4649 /** 4650 * xmlSchemaGetPropNode: 4651 * @node: the element node 4652 * @name: the name of the attribute 4653 * 4654 * Seeks an attribute with a name of @name in 4655 * no namespace. 4656 * 4657 * Returns the attribute or NULL if not present. 4658 */ 4659 static xmlAttrPtr 4660 xmlSchemaGetPropNode(xmlNodePtr node, const char *name) 4661 { 4662 xmlAttrPtr prop; 4663 4664 if ((node == NULL) || (name == NULL)) 4665 return(NULL); 4666 prop = node->properties; 4667 while (prop != NULL) { 4668 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name)) 4669 return(prop); 4670 prop = prop->next; 4671 } 4672 return (NULL); 4673 } 4674 4675 /** 4676 * xmlSchemaGetPropNodeNs: 4677 * @node: the element node 4678 * @uri: the uri 4679 * @name: the name of the attribute 4680 * 4681 * Seeks an attribute with a local name of @name and 4682 * a namespace URI of @uri. 4683 * 4684 * Returns the attribute or NULL if not present. 4685 */ 4686 static xmlAttrPtr 4687 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name) 4688 { 4689 xmlAttrPtr prop; 4690 4691 if ((node == NULL) || (name == NULL)) 4692 return(NULL); 4693 prop = node->properties; 4694 while (prop != NULL) { 4695 if ((prop->ns != NULL) && 4696 xmlStrEqual(prop->name, BAD_CAST name) && 4697 xmlStrEqual(prop->ns->href, BAD_CAST uri)) 4698 return(prop); 4699 prop = prop->next; 4700 } 4701 return (NULL); 4702 } 4703 4704 static const xmlChar * 4705 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) 4706 { 4707 xmlChar *val; 4708 const xmlChar *ret; 4709 4710 val = xmlNodeGetContent(node); 4711 if (val == NULL) 4712 val = xmlStrdup((xmlChar *)""); 4713 ret = xmlDictLookup(ctxt->dict, val, -1); 4714 xmlFree(val); 4715 return(ret); 4716 } 4717 4718 static const xmlChar * 4719 xmlSchemaGetNodeContentNoDict(xmlNodePtr node) 4720 { 4721 return((const xmlChar*) xmlNodeGetContent(node)); 4722 } 4723 4724 /** 4725 * xmlSchemaGetProp: 4726 * @ctxt: the parser context 4727 * @node: the node 4728 * @name: the property name 4729 * 4730 * Read a attribute value and internalize the string 4731 * 4732 * Returns the string or NULL if not present. 4733 */ 4734 static const xmlChar * 4735 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 4736 const char *name) 4737 { 4738 xmlChar *val; 4739 const xmlChar *ret; 4740 4741 val = xmlGetNoNsProp(node, BAD_CAST name); 4742 if (val == NULL) 4743 return(NULL); 4744 ret = xmlDictLookup(ctxt->dict, val, -1); 4745 xmlFree(val); 4746 return(ret); 4747 } 4748 4749 /************************************************************************ 4750 * * 4751 * Parsing functions * 4752 * * 4753 ************************************************************************/ 4754 4755 #define WXS_FIND_GLOBAL_ITEM(slot) \ 4756 if (xmlStrEqual(nsName, schema->targetNamespace)) { \ 4757 ret = xmlHashLookup(schema->slot, name); \ 4758 if (ret != NULL) goto exit; \ 4759 } \ 4760 if (xmlHashSize(schema->schemasImports) > 1) { \ 4761 xmlSchemaImportPtr import; \ 4762 if (nsName == NULL) \ 4763 import = xmlHashLookup(schema->schemasImports, \ 4764 XML_SCHEMAS_NO_NAMESPACE); \ 4765 else \ 4766 import = xmlHashLookup(schema->schemasImports, nsName); \ 4767 if (import == NULL) \ 4768 goto exit; \ 4769 ret = xmlHashLookup(import->schema->slot, name); \ 4770 } 4771 4772 /** 4773 * xmlSchemaGetElem: 4774 * @schema: the schema context 4775 * @name: the element name 4776 * @ns: the element namespace 4777 * 4778 * Lookup a global element declaration in the schema. 4779 * 4780 * Returns the element declaration or NULL if not found. 4781 */ 4782 static xmlSchemaElementPtr 4783 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name, 4784 const xmlChar * nsName) 4785 { 4786 xmlSchemaElementPtr ret = NULL; 4787 4788 if ((name == NULL) || (schema == NULL)) 4789 return(NULL); 4790 if (schema != NULL) { 4791 WXS_FIND_GLOBAL_ITEM(elemDecl) 4792 } 4793 exit: 4794 #ifdef DEBUG 4795 if (ret == NULL) { 4796 if (nsName == NULL) 4797 fprintf(stderr, "Unable to lookup element decl. %s", name); 4798 else 4799 fprintf(stderr, "Unable to lookup element decl. %s:%s", name, 4800 nsName); 4801 } 4802 #endif 4803 return (ret); 4804 } 4805 4806 /** 4807 * xmlSchemaGetType: 4808 * @schema: the main schema 4809 * @name: the type's name 4810 * nsName: the type's namespace 4811 * 4812 * Lookup a type in the schemas or the predefined types 4813 * 4814 * Returns the group definition or NULL if not found. 4815 */ 4816 static xmlSchemaTypePtr 4817 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name, 4818 const xmlChar * nsName) 4819 { 4820 xmlSchemaTypePtr ret = NULL; 4821 4822 if (name == NULL) 4823 return (NULL); 4824 /* First try the built-in types. */ 4825 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) { 4826 ret = xmlSchemaGetPredefinedType(name, nsName); 4827 if (ret != NULL) 4828 goto exit; 4829 /* 4830 * Note that we try the parsed schemas as well here 4831 * since one might have parsed the S4S, which contain more 4832 * than the built-in types. 4833 * TODO: Can we optimize this? 4834 */ 4835 } 4836 if (schema != NULL) { 4837 WXS_FIND_GLOBAL_ITEM(typeDecl) 4838 } 4839 exit: 4840 4841 #ifdef DEBUG 4842 if (ret == NULL) { 4843 if (nsName == NULL) 4844 fprintf(stderr, "Unable to lookup type %s", name); 4845 else 4846 fprintf(stderr, "Unable to lookup type %s:%s", name, 4847 nsName); 4848 } 4849 #endif 4850 return (ret); 4851 } 4852 4853 /** 4854 * xmlSchemaGetAttributeDecl: 4855 * @schema: the context of the schema 4856 * @name: the name of the attribute 4857 * @ns: the target namespace of the attribute 4858 * 4859 * Lookup a an attribute in the schema or imported schemas 4860 * 4861 * Returns the attribute declaration or NULL if not found. 4862 */ 4863 static xmlSchemaAttributePtr 4864 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name, 4865 const xmlChar * nsName) 4866 { 4867 xmlSchemaAttributePtr ret = NULL; 4868 4869 if ((name == NULL) || (schema == NULL)) 4870 return (NULL); 4871 if (schema != NULL) { 4872 WXS_FIND_GLOBAL_ITEM(attrDecl) 4873 } 4874 exit: 4875 #ifdef DEBUG 4876 if (ret == NULL) { 4877 if (nsName == NULL) 4878 fprintf(stderr, "Unable to lookup attribute %s", name); 4879 else 4880 fprintf(stderr, "Unable to lookup attribute %s:%s", name, 4881 nsName); 4882 } 4883 #endif 4884 return (ret); 4885 } 4886 4887 /** 4888 * xmlSchemaGetAttributeGroup: 4889 * @schema: the context of the schema 4890 * @name: the name of the attribute group 4891 * @ns: the target namespace of the attribute group 4892 * 4893 * Lookup a an attribute group in the schema or imported schemas 4894 * 4895 * Returns the attribute group definition or NULL if not found. 4896 */ 4897 static xmlSchemaAttributeGroupPtr 4898 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name, 4899 const xmlChar * nsName) 4900 { 4901 xmlSchemaAttributeGroupPtr ret = NULL; 4902 4903 if ((name == NULL) || (schema == NULL)) 4904 return (NULL); 4905 if (schema != NULL) { 4906 WXS_FIND_GLOBAL_ITEM(attrgrpDecl) 4907 } 4908 exit: 4909 /* TODO: 4910 if ((ret != NULL) && (ret->redef != NULL)) { 4911 * Return the last redefinition. * 4912 ret = ret->redef; 4913 } 4914 */ 4915 #ifdef DEBUG 4916 if (ret == NULL) { 4917 if (nsName == NULL) 4918 fprintf(stderr, "Unable to lookup attribute group %s", name); 4919 else 4920 fprintf(stderr, "Unable to lookup attribute group %s:%s", name, 4921 nsName); 4922 } 4923 #endif 4924 return (ret); 4925 } 4926 4927 /** 4928 * xmlSchemaGetGroup: 4929 * @schema: the context of the schema 4930 * @name: the name of the group 4931 * @ns: the target namespace of the group 4932 * 4933 * Lookup a group in the schema or imported schemas 4934 * 4935 * Returns the group definition or NULL if not found. 4936 */ 4937 static xmlSchemaModelGroupDefPtr 4938 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name, 4939 const xmlChar * nsName) 4940 { 4941 xmlSchemaModelGroupDefPtr ret = NULL; 4942 4943 if ((name == NULL) || (schema == NULL)) 4944 return (NULL); 4945 if (schema != NULL) { 4946 WXS_FIND_GLOBAL_ITEM(groupDecl) 4947 } 4948 exit: 4949 4950 #ifdef DEBUG 4951 if (ret == NULL) { 4952 if (nsName == NULL) 4953 fprintf(stderr, "Unable to lookup group %s", name); 4954 else 4955 fprintf(stderr, "Unable to lookup group %s:%s", name, 4956 nsName); 4957 } 4958 #endif 4959 return (ret); 4960 } 4961 4962 static xmlSchemaNotationPtr 4963 xmlSchemaGetNotation(xmlSchemaPtr schema, 4964 const xmlChar *name, 4965 const xmlChar *nsName) 4966 { 4967 xmlSchemaNotationPtr ret = NULL; 4968 4969 if ((name == NULL) || (schema == NULL)) 4970 return (NULL); 4971 if (schema != NULL) { 4972 WXS_FIND_GLOBAL_ITEM(notaDecl) 4973 } 4974 exit: 4975 return (ret); 4976 } 4977 4978 static xmlSchemaIDCPtr 4979 xmlSchemaGetIDC(xmlSchemaPtr schema, 4980 const xmlChar *name, 4981 const xmlChar *nsName) 4982 { 4983 xmlSchemaIDCPtr ret = NULL; 4984 4985 if ((name == NULL) || (schema == NULL)) 4986 return (NULL); 4987 if (schema != NULL) { 4988 WXS_FIND_GLOBAL_ITEM(idcDef) 4989 } 4990 exit: 4991 return (ret); 4992 } 4993 4994 /** 4995 * xmlSchemaGetNamedComponent: 4996 * @schema: the schema 4997 * @name: the name of the group 4998 * @ns: the target namespace of the group 4999 * 5000 * Lookup a group in the schema or imported schemas 5001 * 5002 * Returns the group definition or NULL if not found. 5003 */ 5004 static xmlSchemaBasicItemPtr 5005 xmlSchemaGetNamedComponent(xmlSchemaPtr schema, 5006 xmlSchemaTypeType itemType, 5007 const xmlChar *name, 5008 const xmlChar *targetNs) 5009 { 5010 switch (itemType) { 5011 case XML_SCHEMA_TYPE_GROUP: 5012 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema, 5013 name, targetNs)); 5014 case XML_SCHEMA_TYPE_ELEMENT: 5015 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema, 5016 name, targetNs)); 5017 default: 5018 TODO 5019 return (NULL); 5020 } 5021 } 5022 5023 /************************************************************************ 5024 * * 5025 * Parsing functions * 5026 * * 5027 ************************************************************************/ 5028 5029 #define IS_BLANK_NODE(n) \ 5030 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1))) 5031 5032 /** 5033 * xmlSchemaIsBlank: 5034 * @str: a string 5035 * @len: the length of the string or -1 5036 * 5037 * Check if a string is ignorable 5038 * 5039 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise 5040 */ 5041 static int 5042 xmlSchemaIsBlank(xmlChar * str, int len) 5043 { 5044 if (str == NULL) 5045 return (1); 5046 if (len < 0) { 5047 while (*str != 0) { 5048 if (!(IS_BLANK_CH(*str))) 5049 return (0); 5050 str++; 5051 } 5052 } else while ((*str != 0) && (len != 0)) { 5053 if (!(IS_BLANK_CH(*str))) 5054 return (0); 5055 str++; 5056 len--; 5057 } 5058 5059 return (1); 5060 } 5061 5062 #define WXS_COMP_NAME(c, t) ((t) (c))->name 5063 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace 5064 /* 5065 * xmlSchemaFindRedefCompInGraph: 5066 * ATTENTION TODO: This uses pointer comp. for strings. 5067 */ 5068 static xmlSchemaBasicItemPtr 5069 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket, 5070 xmlSchemaTypeType type, 5071 const xmlChar *name, 5072 const xmlChar *nsName) 5073 { 5074 xmlSchemaBasicItemPtr ret; 5075 int i; 5076 5077 if ((bucket == NULL) || (name == NULL)) 5078 return(NULL); 5079 if ((bucket->globals == NULL) || 5080 (bucket->globals->nbItems == 0)) 5081 goto subschemas; 5082 /* 5083 * Search in global components. 5084 */ 5085 for (i = 0; i < bucket->globals->nbItems; i++) { 5086 ret = bucket->globals->items[i]; 5087 if (ret->type == type) { 5088 switch (type) { 5089 case XML_SCHEMA_TYPE_COMPLEX: 5090 case XML_SCHEMA_TYPE_SIMPLE: 5091 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) && 5092 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) == 5093 nsName)) 5094 { 5095 return(ret); 5096 } 5097 break; 5098 case XML_SCHEMA_TYPE_GROUP: 5099 if ((WXS_COMP_NAME(ret, 5100 xmlSchemaModelGroupDefPtr) == name) && 5101 (WXS_COMP_TNS(ret, 5102 xmlSchemaModelGroupDefPtr) == nsName)) 5103 { 5104 return(ret); 5105 } 5106 break; 5107 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: 5108 if ((WXS_COMP_NAME(ret, 5109 xmlSchemaAttributeGroupPtr) == name) && 5110 (WXS_COMP_TNS(ret, 5111 xmlSchemaAttributeGroupPtr) == nsName)) 5112 { 5113 return(ret); 5114 } 5115 break; 5116 default: 5117 /* Should not be hit. */ 5118 return(NULL); 5119 } 5120 } 5121 } 5122 subschemas: 5123 /* 5124 * Process imported/included schemas. 5125 */ 5126 if (bucket->relations != NULL) { 5127 xmlSchemaSchemaRelationPtr rel = bucket->relations; 5128 5129 /* 5130 * TODO: Marking the bucket will not avoid multiple searches 5131 * in the same schema, but avoids at least circularity. 5132 */ 5133 bucket->flags |= XML_SCHEMA_BUCKET_MARKED; 5134 do { 5135 if ((rel->bucket != NULL) && 5136 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) { 5137 ret = xmlSchemaFindRedefCompInGraph(rel->bucket, 5138 type, name, nsName); 5139 if (ret != NULL) 5140 return(ret); 5141 } 5142 rel = rel->next; 5143 } while (rel != NULL); 5144 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED; 5145 } 5146 return(NULL); 5147 } 5148 5149 /** 5150 * xmlSchemaAddNotation: 5151 * @ctxt: a schema parser context 5152 * @schema: the schema being built 5153 * @name: the item name 5154 * 5155 * Add an XML schema annotation declaration 5156 * *WARNING* this interface is highly subject to change 5157 * 5158 * Returns the new struture or NULL in case of error 5159 */ 5160 static xmlSchemaNotationPtr 5161 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5162 const xmlChar *name, const xmlChar *nsName, 5163 xmlNodePtr node ATTRIBUTE_UNUSED) 5164 { 5165 xmlSchemaNotationPtr ret = NULL; 5166 5167 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5168 return (NULL); 5169 5170 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation)); 5171 if (ret == NULL) { 5172 xmlSchemaPErrMemory(ctxt, "add annotation", NULL); 5173 return (NULL); 5174 } 5175 memset(ret, 0, sizeof(xmlSchemaNotation)); 5176 ret->type = XML_SCHEMA_TYPE_NOTATION; 5177 ret->name = name; 5178 ret->targetNamespace = nsName; 5179 /* TODO: do we need the node to be set? 5180 * ret->node = node;*/ 5181 WXS_ADD_GLOBAL(ctxt, ret); 5182 return (ret); 5183 } 5184 5185 /** 5186 * xmlSchemaAddAttribute: 5187 * @ctxt: a schema parser context 5188 * @schema: the schema being built 5189 * @name: the item name 5190 * @namespace: the namespace 5191 * 5192 * Add an XML schema Attrribute declaration 5193 * *WARNING* this interface is highly subject to change 5194 * 5195 * Returns the new struture or NULL in case of error 5196 */ 5197 static xmlSchemaAttributePtr 5198 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5199 const xmlChar * name, const xmlChar * nsName, 5200 xmlNodePtr node, int topLevel) 5201 { 5202 xmlSchemaAttributePtr ret = NULL; 5203 5204 if ((ctxt == NULL) || (schema == NULL)) 5205 return (NULL); 5206 5207 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute)); 5208 if (ret == NULL) { 5209 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL); 5210 return (NULL); 5211 } 5212 memset(ret, 0, sizeof(xmlSchemaAttribute)); 5213 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE; 5214 ret->node = node; 5215 ret->name = name; 5216 ret->targetNamespace = nsName; 5217 5218 if (topLevel) 5219 WXS_ADD_GLOBAL(ctxt, ret); 5220 else 5221 WXS_ADD_LOCAL(ctxt, ret); 5222 WXS_ADD_PENDING(ctxt, ret); 5223 return (ret); 5224 } 5225 5226 /** 5227 * xmlSchemaAddAttributeUse: 5228 * @ctxt: a schema parser context 5229 * @schema: the schema being built 5230 * @name: the item name 5231 * @namespace: the namespace 5232 * 5233 * Add an XML schema Attrribute declaration 5234 * *WARNING* this interface is highly subject to change 5235 * 5236 * Returns the new struture or NULL in case of error 5237 */ 5238 static xmlSchemaAttributeUsePtr 5239 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt, 5240 xmlNodePtr node) 5241 { 5242 xmlSchemaAttributeUsePtr ret = NULL; 5243 5244 if (pctxt == NULL) 5245 return (NULL); 5246 5247 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse)); 5248 if (ret == NULL) { 5249 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL); 5250 return (NULL); 5251 } 5252 memset(ret, 0, sizeof(xmlSchemaAttributeUse)); 5253 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE; 5254 ret->node = node; 5255 5256 WXS_ADD_LOCAL(pctxt, ret); 5257 return (ret); 5258 } 5259 5260 /* 5261 * xmlSchemaAddRedef: 5262 * 5263 * Adds a redefinition information. This is used at a later stage to: 5264 * resolve references to the redefined components and to check constraints. 5265 */ 5266 static xmlSchemaRedefPtr 5267 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt, 5268 xmlSchemaBucketPtr targetBucket, 5269 void *item, 5270 const xmlChar *refName, 5271 const xmlChar *refTargetNs) 5272 { 5273 xmlSchemaRedefPtr ret; 5274 5275 ret = (xmlSchemaRedefPtr) 5276 xmlMalloc(sizeof(xmlSchemaRedef)); 5277 if (ret == NULL) { 5278 xmlSchemaPErrMemory(pctxt, 5279 "allocating redefinition info", NULL); 5280 return (NULL); 5281 } 5282 memset(ret, 0, sizeof(xmlSchemaRedef)); 5283 ret->item = item; 5284 ret->targetBucket = targetBucket; 5285 ret->refName = refName; 5286 ret->refTargetNs = refTargetNs; 5287 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL) 5288 WXS_CONSTRUCTOR(pctxt)->redefs = ret; 5289 else 5290 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret; 5291 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret; 5292 5293 return (ret); 5294 } 5295 5296 /** 5297 * xmlSchemaAddAttributeGroupDefinition: 5298 * @ctxt: a schema parser context 5299 * @schema: the schema being built 5300 * @name: the item name 5301 * @nsName: the target namespace 5302 * @node: the corresponding node 5303 * 5304 * Add an XML schema Attrribute Group definition. 5305 * 5306 * Returns the new struture or NULL in case of error 5307 */ 5308 static xmlSchemaAttributeGroupPtr 5309 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 5310 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 5311 const xmlChar *name, 5312 const xmlChar *nsName, 5313 xmlNodePtr node) 5314 { 5315 xmlSchemaAttributeGroupPtr ret = NULL; 5316 5317 if ((pctxt == NULL) || (name == NULL)) 5318 return (NULL); 5319 5320 ret = (xmlSchemaAttributeGroupPtr) 5321 xmlMalloc(sizeof(xmlSchemaAttributeGroup)); 5322 if (ret == NULL) { 5323 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL); 5324 return (NULL); 5325 } 5326 memset(ret, 0, sizeof(xmlSchemaAttributeGroup)); 5327 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP; 5328 ret->name = name; 5329 ret->targetNamespace = nsName; 5330 ret->node = node; 5331 5332 /* TODO: Remove the flag. */ 5333 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL; 5334 if (pctxt->isRedefine) { 5335 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined, 5336 ret, name, nsName); 5337 if (pctxt->redef == NULL) { 5338 xmlFree(ret); 5339 return(NULL); 5340 } 5341 pctxt->redefCounter = 0; 5342 } 5343 WXS_ADD_GLOBAL(pctxt, ret); 5344 WXS_ADD_PENDING(pctxt, ret); 5345 return (ret); 5346 } 5347 5348 /** 5349 * xmlSchemaAddElement: 5350 * @ctxt: a schema parser context 5351 * @schema: the schema being built 5352 * @name: the type name 5353 * @namespace: the type namespace 5354 * 5355 * Add an XML schema Element declaration 5356 * *WARNING* this interface is highly subject to change 5357 * 5358 * Returns the new struture or NULL in case of error 5359 */ 5360 static xmlSchemaElementPtr 5361 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, 5362 const xmlChar * name, const xmlChar * nsName, 5363 xmlNodePtr node, int topLevel) 5364 { 5365 xmlSchemaElementPtr ret = NULL; 5366 5367 if ((ctxt == NULL) || (name == NULL)) 5368 return (NULL); 5369 5370 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement)); 5371 if (ret == NULL) { 5372 xmlSchemaPErrMemory(ctxt, "allocating element", NULL); 5373 return (NULL); 5374 } 5375 memset(ret, 0, sizeof(xmlSchemaElement)); 5376 ret->type = XML_SCHEMA_TYPE_ELEMENT; 5377 ret->name = name; 5378 ret->targetNamespace = nsName; 5379 ret->node = node; 5380 5381 if (topLevel) 5382 WXS_ADD_GLOBAL(ctxt, ret); 5383 else 5384 WXS_ADD_LOCAL(ctxt, ret); 5385 WXS_ADD_PENDING(ctxt, ret); 5386 return (ret); 5387 } 5388 5389 /** 5390 * xmlSchemaAddType: 5391 * @ctxt: a schema parser context 5392 * @schema: the schema being built 5393 * @name: the item name 5394 * @namespace: the namespace 5395 * 5396 * Add an XML schema item 5397 * *WARNING* this interface is highly subject to change 5398 * 5399 * Returns the new struture or NULL in case of error 5400 */ 5401 static xmlSchemaTypePtr 5402 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5403 xmlSchemaTypeType type, 5404 const xmlChar * name, const xmlChar * nsName, 5405 xmlNodePtr node, int topLevel) 5406 { 5407 xmlSchemaTypePtr ret = NULL; 5408 5409 if ((ctxt == NULL) || (schema == NULL)) 5410 return (NULL); 5411 5412 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 5413 if (ret == NULL) { 5414 xmlSchemaPErrMemory(ctxt, "allocating type", NULL); 5415 return (NULL); 5416 } 5417 memset(ret, 0, sizeof(xmlSchemaType)); 5418 ret->type = type; 5419 ret->name = name; 5420 ret->targetNamespace = nsName; 5421 ret->node = node; 5422 if (topLevel) { 5423 if (ctxt->isRedefine) { 5424 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5425 ret, name, nsName); 5426 if (ctxt->redef == NULL) { 5427 xmlFree(ret); 5428 return(NULL); 5429 } 5430 ctxt->redefCounter = 0; 5431 } 5432 WXS_ADD_GLOBAL(ctxt, ret); 5433 } else 5434 WXS_ADD_LOCAL(ctxt, ret); 5435 WXS_ADD_PENDING(ctxt, ret); 5436 return (ret); 5437 } 5438 5439 static xmlSchemaQNameRefPtr 5440 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt, 5441 xmlSchemaTypeType refType, 5442 const xmlChar *refName, 5443 const xmlChar *refNs) 5444 { 5445 xmlSchemaQNameRefPtr ret; 5446 5447 ret = (xmlSchemaQNameRefPtr) 5448 xmlMalloc(sizeof(xmlSchemaQNameRef)); 5449 if (ret == NULL) { 5450 xmlSchemaPErrMemory(pctxt, 5451 "allocating QName reference item", NULL); 5452 return (NULL); 5453 } 5454 ret->node = NULL; 5455 ret->type = XML_SCHEMA_EXTRA_QNAMEREF; 5456 ret->name = refName; 5457 ret->targetNamespace = refNs; 5458 ret->item = NULL; 5459 ret->itemType = refType; 5460 /* 5461 * Store the reference item in the schema. 5462 */ 5463 WXS_ADD_LOCAL(pctxt, ret); 5464 return (ret); 5465 } 5466 5467 static xmlSchemaAttributeUseProhibPtr 5468 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt) 5469 { 5470 xmlSchemaAttributeUseProhibPtr ret; 5471 5472 ret = (xmlSchemaAttributeUseProhibPtr) 5473 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib)); 5474 if (ret == NULL) { 5475 xmlSchemaPErrMemory(pctxt, 5476 "allocating attribute use prohibition", NULL); 5477 return (NULL); 5478 } 5479 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib)); 5480 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB; 5481 WXS_ADD_LOCAL(pctxt, ret); 5482 return (ret); 5483 } 5484 5485 5486 /** 5487 * xmlSchemaAddModelGroup: 5488 * @ctxt: a schema parser context 5489 * @schema: the schema being built 5490 * @type: the "compositor" type of the model group 5491 * @node: the node in the schema doc 5492 * 5493 * Adds a schema model group 5494 * *WARNING* this interface is highly subject to change 5495 * 5496 * Returns the new struture or NULL in case of error 5497 */ 5498 static xmlSchemaModelGroupPtr 5499 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt, 5500 xmlSchemaPtr schema, 5501 xmlSchemaTypeType type, 5502 xmlNodePtr node) 5503 { 5504 xmlSchemaModelGroupPtr ret = NULL; 5505 5506 if ((ctxt == NULL) || (schema == NULL)) 5507 return (NULL); 5508 5509 ret = (xmlSchemaModelGroupPtr) 5510 xmlMalloc(sizeof(xmlSchemaModelGroup)); 5511 if (ret == NULL) { 5512 xmlSchemaPErrMemory(ctxt, "allocating model group component", 5513 NULL); 5514 return (NULL); 5515 } 5516 memset(ret, 0, sizeof(xmlSchemaModelGroup)); 5517 ret->type = type; 5518 ret->node = node; 5519 WXS_ADD_LOCAL(ctxt, ret); 5520 if ((type == XML_SCHEMA_TYPE_SEQUENCE) || 5521 (type == XML_SCHEMA_TYPE_CHOICE)) 5522 WXS_ADD_PENDING(ctxt, ret); 5523 return (ret); 5524 } 5525 5526 5527 /** 5528 * xmlSchemaAddParticle: 5529 * @ctxt: a schema parser context 5530 * @schema: the schema being built 5531 * @node: the corresponding node in the schema doc 5532 * @min: the minOccurs 5533 * @max: the maxOccurs 5534 * 5535 * Adds an XML schema particle component. 5536 * *WARNING* this interface is highly subject to change 5537 * 5538 * Returns the new struture or NULL in case of error 5539 */ 5540 static xmlSchemaParticlePtr 5541 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt, 5542 xmlNodePtr node, int min, int max) 5543 { 5544 xmlSchemaParticlePtr ret = NULL; 5545 if (ctxt == NULL) 5546 return (NULL); 5547 5548 #ifdef DEBUG 5549 fprintf(stderr, "Adding particle component\n"); 5550 #endif 5551 ret = (xmlSchemaParticlePtr) 5552 xmlMalloc(sizeof(xmlSchemaParticle)); 5553 if (ret == NULL) { 5554 xmlSchemaPErrMemory(ctxt, "allocating particle component", 5555 NULL); 5556 return (NULL); 5557 } 5558 ret->type = XML_SCHEMA_TYPE_PARTICLE; 5559 ret->annot = NULL; 5560 ret->node = node; 5561 ret->minOccurs = min; 5562 ret->maxOccurs = max; 5563 ret->next = NULL; 5564 ret->children = NULL; 5565 5566 WXS_ADD_LOCAL(ctxt, ret); 5567 /* 5568 * Note that addition to pending components will be done locally 5569 * to the specific parsing function, since the most particles 5570 * need not to be fixed up (i.e. the reference to be resolved). 5571 * REMOVED: WXS_ADD_PENDING(ctxt, ret); 5572 */ 5573 return (ret); 5574 } 5575 5576 /** 5577 * xmlSchemaAddModelGroupDefinition: 5578 * @ctxt: a schema validation context 5579 * @schema: the schema being built 5580 * @name: the group name 5581 * 5582 * Add an XML schema Group definition 5583 * 5584 * Returns the new struture or NULL in case of error 5585 */ 5586 static xmlSchemaModelGroupDefPtr 5587 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 5588 xmlSchemaPtr schema, 5589 const xmlChar *name, 5590 const xmlChar *nsName, 5591 xmlNodePtr node) 5592 { 5593 xmlSchemaModelGroupDefPtr ret = NULL; 5594 5595 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5596 return (NULL); 5597 5598 ret = (xmlSchemaModelGroupDefPtr) 5599 xmlMalloc(sizeof(xmlSchemaModelGroupDef)); 5600 if (ret == NULL) { 5601 xmlSchemaPErrMemory(ctxt, "adding group", NULL); 5602 return (NULL); 5603 } 5604 memset(ret, 0, sizeof(xmlSchemaModelGroupDef)); 5605 ret->name = name; 5606 ret->type = XML_SCHEMA_TYPE_GROUP; 5607 ret->node = node; 5608 ret->targetNamespace = nsName; 5609 5610 if (ctxt->isRedefine) { 5611 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined, 5612 ret, name, nsName); 5613 if (ctxt->redef == NULL) { 5614 xmlFree(ret); 5615 return(NULL); 5616 } 5617 ctxt->redefCounter = 0; 5618 } 5619 WXS_ADD_GLOBAL(ctxt, ret); 5620 WXS_ADD_PENDING(ctxt, ret); 5621 return (ret); 5622 } 5623 5624 /** 5625 * xmlSchemaNewWildcardNs: 5626 * @ctxt: a schema validation context 5627 * 5628 * Creates a new wildcard namespace constraint. 5629 * 5630 * Returns the new struture or NULL in case of error 5631 */ 5632 static xmlSchemaWildcardNsPtr 5633 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt) 5634 { 5635 xmlSchemaWildcardNsPtr ret; 5636 5637 ret = (xmlSchemaWildcardNsPtr) 5638 xmlMalloc(sizeof(xmlSchemaWildcardNs)); 5639 if (ret == NULL) { 5640 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL); 5641 return (NULL); 5642 } 5643 ret->value = NULL; 5644 ret->next = NULL; 5645 return (ret); 5646 } 5647 5648 static xmlSchemaIDCPtr 5649 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5650 const xmlChar *name, const xmlChar *nsName, 5651 int category, xmlNodePtr node) 5652 { 5653 xmlSchemaIDCPtr ret = NULL; 5654 5655 if ((ctxt == NULL) || (schema == NULL) || (name == NULL)) 5656 return (NULL); 5657 5658 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC)); 5659 if (ret == NULL) { 5660 xmlSchemaPErrMemory(ctxt, 5661 "allocating an identity-constraint definition", NULL); 5662 return (NULL); 5663 } 5664 memset(ret, 0, sizeof(xmlSchemaIDC)); 5665 /* The target namespace of the parent element declaration. */ 5666 ret->targetNamespace = nsName; 5667 ret->name = name; 5668 ret->type = category; 5669 ret->node = node; 5670 5671 WXS_ADD_GLOBAL(ctxt, ret); 5672 /* 5673 * Only keyrefs need to be fixup up. 5674 */ 5675 if (category == XML_SCHEMA_TYPE_IDC_KEYREF) 5676 WXS_ADD_PENDING(ctxt, ret); 5677 return (ret); 5678 } 5679 5680 /** 5681 * xmlSchemaAddWildcard: 5682 * @ctxt: a schema validation context 5683 * @schema: a schema 5684 * 5685 * Adds a wildcard. 5686 * It corresponds to a xsd:anyAttribute and xsd:any. 5687 * 5688 * Returns the new struture or NULL in case of error 5689 */ 5690 static xmlSchemaWildcardPtr 5691 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 5692 xmlSchemaTypeType type, xmlNodePtr node) 5693 { 5694 xmlSchemaWildcardPtr ret = NULL; 5695 5696 if ((ctxt == NULL) || (schema == NULL)) 5697 return (NULL); 5698 5699 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard)); 5700 if (ret == NULL) { 5701 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL); 5702 return (NULL); 5703 } 5704 memset(ret, 0, sizeof(xmlSchemaWildcard)); 5705 ret->type = type; 5706 ret->node = node; 5707 WXS_ADD_LOCAL(ctxt, ret); 5708 return (ret); 5709 } 5710 5711 static void 5712 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) 5713 { 5714 if (group == NULL) 5715 return; 5716 if (group->members != NULL) 5717 xmlSchemaItemListFree(group->members); 5718 xmlFree(group); 5719 } 5720 5721 static void 5722 xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED) 5723 { 5724 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group); 5725 } 5726 5727 static xmlSchemaSubstGroupPtr 5728 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, 5729 xmlSchemaElementPtr head) 5730 { 5731 xmlSchemaSubstGroupPtr ret; 5732 5733 /* Init subst group hash. */ 5734 if (WXS_SUBST_GROUPS(pctxt) == NULL) { 5735 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict); 5736 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5737 return(NULL); 5738 } 5739 /* Create a new substitution group. */ 5740 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup)); 5741 if (ret == NULL) { 5742 xmlSchemaPErrMemory(NULL, 5743 "allocating a substitution group container", NULL); 5744 return(NULL); 5745 } 5746 memset(ret, 0, sizeof(xmlSchemaSubstGroup)); 5747 ret->head = head; 5748 /* Create list of members. */ 5749 ret->members = xmlSchemaItemListCreate(); 5750 if (ret->members == NULL) { 5751 xmlSchemaSubstGroupFree(ret); 5752 return(NULL); 5753 } 5754 /* Add subst group to hash. */ 5755 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt), 5756 head->name, head->targetNamespace, ret) != 0) { 5757 PERROR_INT("xmlSchemaSubstGroupAdd", 5758 "failed to add a new substitution container"); 5759 xmlSchemaSubstGroupFree(ret); 5760 return(NULL); 5761 } 5762 return(ret); 5763 } 5764 5765 static xmlSchemaSubstGroupPtr 5766 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt, 5767 xmlSchemaElementPtr head) 5768 { 5769 if (WXS_SUBST_GROUPS(pctxt) == NULL) 5770 return(NULL); 5771 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt), 5772 head->name, head->targetNamespace)); 5773 5774 } 5775 5776 /** 5777 * xmlSchemaAddElementSubstitutionMember: 5778 * @pctxt: a schema parser context 5779 * @head: the head of the substitution group 5780 * @member: the new member of the substitution group 5781 * 5782 * Allocate a new annotation structure. 5783 * 5784 * Returns the newly allocated structure or NULL in case or error 5785 */ 5786 static int 5787 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt, 5788 xmlSchemaElementPtr head, 5789 xmlSchemaElementPtr member) 5790 { 5791 xmlSchemaSubstGroupPtr substGroup = NULL; 5792 5793 if ((pctxt == NULL) || (head == NULL) || (member == NULL)) 5794 return (-1); 5795 5796 substGroup = xmlSchemaSubstGroupGet(pctxt, head); 5797 if (substGroup == NULL) 5798 substGroup = xmlSchemaSubstGroupAdd(pctxt, head); 5799 if (substGroup == NULL) 5800 return(-1); 5801 if (xmlSchemaItemListAdd(substGroup->members, member) == -1) 5802 return(-1); 5803 return(0); 5804 } 5805 5806 /************************************************************************ 5807 * * 5808 * Utilities for parsing * 5809 * * 5810 ************************************************************************/ 5811 5812 /** 5813 * xmlSchemaPValAttrNodeQNameValue: 5814 * @ctxt: a schema parser context 5815 * @schema: the schema context 5816 * @ownerDes: the designation of the parent element 5817 * @ownerItem: the parent as a schema object 5818 * @value: the QName value 5819 * @local: the resulting local part if found, the attribute value otherwise 5820 * @uri: the resulting namespace URI if found 5821 * 5822 * Extracts the local name and the URI of a QName value and validates it. 5823 * This one is intended to be used on attribute values that 5824 * should resolve to schema components. 5825 * 5826 * Returns 0, in case the QName is valid, a positive error code 5827 * if not valid and -1 if an internal error occurs. 5828 */ 5829 static int 5830 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt, 5831 xmlSchemaPtr schema, 5832 xmlSchemaBasicItemPtr ownerItem, 5833 xmlAttrPtr attr, 5834 const xmlChar *value, 5835 const xmlChar **uri, 5836 const xmlChar **local) 5837 { 5838 const xmlChar *pref; 5839 xmlNsPtr ns; 5840 int len, ret; 5841 5842 *uri = NULL; 5843 *local = NULL; 5844 ret = xmlValidateQName(value, 1); 5845 if (ret > 0) { 5846 xmlSchemaPSimpleTypeErr(ctxt, 5847 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5848 ownerItem, (xmlNodePtr) attr, 5849 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 5850 NULL, value, NULL, NULL, NULL); 5851 *local = value; 5852 return (ctxt->err); 5853 } else if (ret < 0) 5854 return (-1); 5855 5856 if (!strchr((char *) value, ':')) { 5857 ns = xmlSearchNs(attr->doc, attr->parent, NULL); 5858 if (ns) 5859 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5860 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { 5861 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the 5862 * parser context. */ 5863 /* 5864 * This one takes care of included schemas with no 5865 * target namespace. 5866 */ 5867 *uri = ctxt->targetNamespace; 5868 } 5869 *local = xmlDictLookup(ctxt->dict, value, -1); 5870 return (0); 5871 } 5872 /* 5873 * At this point xmlSplitQName3 has to return a local name. 5874 */ 5875 *local = xmlSplitQName3(value, &len); 5876 *local = xmlDictLookup(ctxt->dict, *local, -1); 5877 pref = xmlDictLookup(ctxt->dict, value, len); 5878 ns = xmlSearchNs(attr->doc, attr->parent, pref); 5879 if (ns == NULL) { 5880 xmlSchemaPSimpleTypeErr(ctxt, 5881 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 5882 ownerItem, (xmlNodePtr) attr, 5883 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value, 5884 "The value '%s' of simple type 'xs:QName' has no " 5885 "corresponding namespace declaration in scope", value, NULL); 5886 return (ctxt->err); 5887 } else { 5888 *uri = xmlDictLookup(ctxt->dict, ns->href, -1); 5889 } 5890 return (0); 5891 } 5892 5893 /** 5894 * xmlSchemaPValAttrNodeQName: 5895 * @ctxt: a schema parser context 5896 * @schema: the schema context 5897 * @ownerDes: the designation of the owner element 5898 * @ownerItem: the owner as a schema object 5899 * @attr: the attribute node 5900 * @local: the resulting local part if found, the attribute value otherwise 5901 * @uri: the resulting namespace URI if found 5902 * 5903 * Extracts and validates the QName of an attribute value. 5904 * This one is intended to be used on attribute values that 5905 * should resolve to schema components. 5906 * 5907 * Returns 0, in case the QName is valid, a positive error code 5908 * if not valid and -1 if an internal error occurs. 5909 */ 5910 static int 5911 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt, 5912 xmlSchemaPtr schema, 5913 xmlSchemaBasicItemPtr ownerItem, 5914 xmlAttrPtr attr, 5915 const xmlChar **uri, 5916 const xmlChar **local) 5917 { 5918 const xmlChar *value; 5919 5920 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 5921 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 5922 ownerItem, attr, value, uri, local)); 5923 } 5924 5925 /** 5926 * xmlSchemaPValAttrQName: 5927 * @ctxt: a schema parser context 5928 * @schema: the schema context 5929 * @ownerDes: the designation of the parent element 5930 * @ownerItem: the owner as a schema object 5931 * @ownerElem: the parent node of the attribute 5932 * @name: the name of the attribute 5933 * @local: the resulting local part if found, the attribute value otherwise 5934 * @uri: the resulting namespace URI if found 5935 * 5936 * Extracts and validates the QName of an attribute value. 5937 * 5938 * Returns 0, in case the QName is valid, a positive error code 5939 * if not valid and -1 if an internal error occurs. 5940 */ 5941 static int 5942 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt, 5943 xmlSchemaPtr schema, 5944 xmlSchemaBasicItemPtr ownerItem, 5945 xmlNodePtr ownerElem, 5946 const char *name, 5947 const xmlChar **uri, 5948 const xmlChar **local) 5949 { 5950 xmlAttrPtr attr; 5951 5952 attr = xmlSchemaGetPropNode(ownerElem, name); 5953 if (attr == NULL) { 5954 *local = NULL; 5955 *uri = NULL; 5956 return (0); 5957 } 5958 return (xmlSchemaPValAttrNodeQName(ctxt, schema, 5959 ownerItem, attr, uri, local)); 5960 } 5961 5962 /** 5963 * xmlSchemaPValAttrID: 5964 * @ctxt: a schema parser context 5965 * @schema: the schema context 5966 * @ownerDes: the designation of the parent element 5967 * @ownerItem: the owner as a schema object 5968 * @ownerElem: the parent node of the attribute 5969 * @name: the name of the attribute 5970 * 5971 * Extracts and validates the ID of an attribute value. 5972 * 5973 * Returns 0, in case the ID is valid, a positive error code 5974 * if not valid and -1 if an internal error occurs. 5975 */ 5976 static int 5977 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr) 5978 { 5979 int ret; 5980 const xmlChar *value; 5981 5982 if (attr == NULL) 5983 return(0); 5984 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr); 5985 ret = xmlValidateNCName(value, 1); 5986 if (ret == 0) { 5987 /* 5988 * NOTE: the IDness might have already be declared in the DTD 5989 */ 5990 if (attr->atype != XML_ATTRIBUTE_ID) { 5991 xmlIDPtr res; 5992 xmlChar *strip; 5993 5994 /* 5995 * TODO: Use xmlSchemaStrip here; it's not exported at this 5996 * moment. 5997 */ 5998 strip = xmlSchemaCollapseString(value); 5999 if (strip != NULL) { 6000 xmlFree((xmlChar *) value); 6001 value = strip; 6002 } 6003 res = xmlAddID(NULL, attr->doc, value, attr); 6004 if (res == NULL) { 6005 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6006 xmlSchemaPSimpleTypeErr(ctxt, 6007 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6008 NULL, (xmlNodePtr) attr, 6009 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 6010 NULL, NULL, "Duplicate value '%s' of simple " 6011 "type 'xs:ID'", value, NULL); 6012 } else 6013 attr->atype = XML_ATTRIBUTE_ID; 6014 } 6015 } else if (ret > 0) { 6016 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6017 xmlSchemaPSimpleTypeErr(ctxt, 6018 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6019 NULL, (xmlNodePtr) attr, 6020 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID), 6021 NULL, NULL, "The value '%s' of simple type 'xs:ID' is " 6022 "not a valid 'xs:NCName'", 6023 value, NULL); 6024 } 6025 if (value != NULL) 6026 xmlFree((xmlChar *)value); 6027 6028 return (ret); 6029 } 6030 6031 static int 6032 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt, 6033 xmlNodePtr ownerElem, 6034 const xmlChar *name) 6035 { 6036 xmlAttrPtr attr; 6037 6038 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name); 6039 if (attr == NULL) 6040 return(0); 6041 return(xmlSchemaPValAttrNodeID(ctxt, attr)); 6042 6043 } 6044 6045 /** 6046 * xmlGetMaxOccurs: 6047 * @ctxt: a schema validation context 6048 * @node: a subtree containing XML Schema informations 6049 * 6050 * Get the maxOccurs property 6051 * 6052 * Returns the default if not found, or the value 6053 */ 6054 static int 6055 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6056 int min, int max, int def, const char *expected) 6057 { 6058 const xmlChar *val, *cur; 6059 int ret = 0; 6060 xmlAttrPtr attr; 6061 6062 attr = xmlSchemaGetPropNode(node, "maxOccurs"); 6063 if (attr == NULL) 6064 return (def); 6065 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6066 6067 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) { 6068 if (max != UNBOUNDED) { 6069 xmlSchemaPSimpleTypeErr(ctxt, 6070 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6071 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6072 NULL, (xmlNodePtr) attr, NULL, expected, 6073 val, NULL, NULL, NULL); 6074 return (def); 6075 } else 6076 return (UNBOUNDED); /* encoding it with -1 might be another option */ 6077 } 6078 6079 cur = val; 6080 while (IS_BLANK_CH(*cur)) 6081 cur++; 6082 if (*cur == 0) { 6083 xmlSchemaPSimpleTypeErr(ctxt, 6084 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6085 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6086 NULL, (xmlNodePtr) attr, NULL, expected, 6087 val, NULL, NULL, NULL); 6088 return (def); 6089 } 6090 while ((*cur >= '0') && (*cur <= '9')) { 6091 ret = ret * 10 + (*cur - '0'); 6092 cur++; 6093 } 6094 while (IS_BLANK_CH(*cur)) 6095 cur++; 6096 /* 6097 * TODO: Restrict the maximal value to Integer. 6098 */ 6099 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6100 xmlSchemaPSimpleTypeErr(ctxt, 6101 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6102 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6103 NULL, (xmlNodePtr) attr, NULL, expected, 6104 val, NULL, NULL, NULL); 6105 return (def); 6106 } 6107 return (ret); 6108 } 6109 6110 /** 6111 * xmlGetMinOccurs: 6112 * @ctxt: a schema validation context 6113 * @node: a subtree containing XML Schema informations 6114 * 6115 * Get the minOccurs property 6116 * 6117 * Returns the default if not found, or the value 6118 */ 6119 static int 6120 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, 6121 int min, int max, int def, const char *expected) 6122 { 6123 const xmlChar *val, *cur; 6124 int ret = 0; 6125 xmlAttrPtr attr; 6126 6127 attr = xmlSchemaGetPropNode(node, "minOccurs"); 6128 if (attr == NULL) 6129 return (def); 6130 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6131 cur = val; 6132 while (IS_BLANK_CH(*cur)) 6133 cur++; 6134 if (*cur == 0) { 6135 xmlSchemaPSimpleTypeErr(ctxt, 6136 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6137 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6138 NULL, (xmlNodePtr) attr, NULL, expected, 6139 val, NULL, NULL, NULL); 6140 return (def); 6141 } 6142 while ((*cur >= '0') && (*cur <= '9')) { 6143 ret = ret * 10 + (*cur - '0'); 6144 cur++; 6145 } 6146 while (IS_BLANK_CH(*cur)) 6147 cur++; 6148 /* 6149 * TODO: Restrict the maximal value to Integer. 6150 */ 6151 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) { 6152 xmlSchemaPSimpleTypeErr(ctxt, 6153 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6154 /* XML_SCHEMAP_INVALID_MINOCCURS, */ 6155 NULL, (xmlNodePtr) attr, NULL, expected, 6156 val, NULL, NULL, NULL); 6157 return (def); 6158 } 6159 return (ret); 6160 } 6161 6162 /** 6163 * xmlSchemaPGetBoolNodeValue: 6164 * @ctxt: a schema validation context 6165 * @ownerDes: owner designation 6166 * @ownerItem: the owner as a schema item 6167 * @node: the node holding the value 6168 * 6169 * Converts a boolean string value into 1 or 0. 6170 * 6171 * Returns 0 or 1. 6172 */ 6173 static int 6174 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt, 6175 xmlSchemaBasicItemPtr ownerItem, 6176 xmlNodePtr node) 6177 { 6178 xmlChar *value = NULL; 6179 int res = 0; 6180 6181 value = xmlNodeGetContent(node); 6182 /* 6183 * 3.2.2.1 Lexical representation 6184 * An instance of a datatype that is defined as `boolean` 6185 * can have the following legal literals {true, false, 1, 0}. 6186 */ 6187 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true")) 6188 res = 1; 6189 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false")) 6190 res = 0; 6191 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1")) 6192 res = 1; 6193 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0")) 6194 res = 0; 6195 else { 6196 xmlSchemaPSimpleTypeErr(ctxt, 6197 XML_SCHEMAP_INVALID_BOOLEAN, 6198 ownerItem, node, 6199 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6200 NULL, BAD_CAST value, 6201 NULL, NULL, NULL); 6202 } 6203 if (value != NULL) 6204 xmlFree(value); 6205 return (res); 6206 } 6207 6208 /** 6209 * xmlGetBooleanProp: 6210 * @ctxt: a schema validation context 6211 * @node: a subtree containing XML Schema informations 6212 * @name: the attribute name 6213 * @def: the default value 6214 * 6215 * Evaluate if a boolean property is set 6216 * 6217 * Returns the default if not found, 0 if found to be false, 6218 * 1 if found to be true 6219 */ 6220 static int 6221 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, 6222 xmlNodePtr node, 6223 const char *name, int def) 6224 { 6225 const xmlChar *val; 6226 6227 val = xmlSchemaGetProp(ctxt, node, name); 6228 if (val == NULL) 6229 return (def); 6230 /* 6231 * 3.2.2.1 Lexical representation 6232 * An instance of a datatype that is defined as `boolean` 6233 * can have the following legal literals {true, false, 1, 0}. 6234 */ 6235 if (xmlStrEqual(val, BAD_CAST "true")) 6236 def = 1; 6237 else if (xmlStrEqual(val, BAD_CAST "false")) 6238 def = 0; 6239 else if (xmlStrEqual(val, BAD_CAST "1")) 6240 def = 1; 6241 else if (xmlStrEqual(val, BAD_CAST "0")) 6242 def = 0; 6243 else { 6244 xmlSchemaPSimpleTypeErr(ctxt, 6245 XML_SCHEMAP_INVALID_BOOLEAN, 6246 NULL, 6247 (xmlNodePtr) xmlSchemaGetPropNode(node, name), 6248 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN), 6249 NULL, val, NULL, NULL, NULL); 6250 } 6251 return (def); 6252 } 6253 6254 /************************************************************************ 6255 * * 6256 * Shema extraction from an Infoset * 6257 * * 6258 ************************************************************************/ 6259 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr 6260 ctxt, xmlSchemaPtr schema, 6261 xmlNodePtr node, 6262 int topLevel); 6263 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr 6264 ctxt, 6265 xmlSchemaPtr schema, 6266 xmlNodePtr node, 6267 int topLevel); 6268 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr 6269 ctxt, 6270 xmlSchemaPtr schema, 6271 xmlNodePtr node, 6272 xmlSchemaTypeType parentType); 6273 static xmlSchemaBasicItemPtr 6274 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 6275 xmlSchemaPtr schema, 6276 xmlNodePtr node, 6277 xmlSchemaItemListPtr uses, 6278 int parentType); 6279 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, 6280 xmlSchemaPtr schema, 6281 xmlNodePtr node); 6282 static xmlSchemaWildcardPtr 6283 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 6284 xmlSchemaPtr schema, xmlNodePtr node); 6285 6286 /** 6287 * xmlSchemaPValAttrNodeValue: 6288 * 6289 * @ctxt: a schema parser context 6290 * @ownerDes: the designation of the parent element 6291 * @ownerItem: the schema object owner if existent 6292 * @attr: the schema attribute node being validated 6293 * @value: the value 6294 * @type: the built-in type to be validated against 6295 * 6296 * Validates a value against the given built-in type. 6297 * This one is intended to be used internally for validation 6298 * of schema attribute values during parsing of the schema. 6299 * 6300 * Returns 0 if the value is valid, a positive error code 6301 * number otherwise and -1 in case of an internal or API error. 6302 */ 6303 static int 6304 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt, 6305 xmlSchemaBasicItemPtr ownerItem, 6306 xmlAttrPtr attr, 6307 const xmlChar *value, 6308 xmlSchemaTypePtr type) 6309 { 6310 6311 int ret = 0; 6312 6313 /* 6314 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this 6315 * one is really meant to be used internally, so better not. 6316 */ 6317 if ((pctxt == NULL) || (type == NULL) || (attr == NULL)) 6318 return (-1); 6319 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6320 PERROR_INT("xmlSchemaPValAttrNodeValue", 6321 "the given type is not a built-in type"); 6322 return (-1); 6323 } 6324 switch (type->builtInType) { 6325 case XML_SCHEMAS_NCNAME: 6326 case XML_SCHEMAS_QNAME: 6327 case XML_SCHEMAS_ANYURI: 6328 case XML_SCHEMAS_TOKEN: 6329 case XML_SCHEMAS_LANGUAGE: 6330 ret = xmlSchemaValPredefTypeNode(type, value, NULL, 6331 (xmlNodePtr) attr); 6332 break; 6333 default: { 6334 PERROR_INT("xmlSchemaPValAttrNodeValue", 6335 "validation using the given type is not supported while " 6336 "parsing a schema"); 6337 return (-1); 6338 } 6339 } 6340 /* 6341 * TODO: Should we use the S4S error codes instead? 6342 */ 6343 if (ret < 0) { 6344 PERROR_INT("xmlSchemaPValAttrNodeValue", 6345 "failed to validate a schema attribute value"); 6346 return (-1); 6347 } else if (ret > 0) { 6348 if (WXS_IS_LIST(type)) 6349 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2; 6350 else 6351 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1; 6352 xmlSchemaPSimpleTypeErr(pctxt, 6353 ret, ownerItem, (xmlNodePtr) attr, 6354 type, NULL, value, NULL, NULL, NULL); 6355 } 6356 return (ret); 6357 } 6358 6359 /** 6360 * xmlSchemaPValAttrNode: 6361 * 6362 * @ctxt: a schema parser context 6363 * @ownerDes: the designation of the parent element 6364 * @ownerItem: the schema object owner if existent 6365 * @attr: the schema attribute node being validated 6366 * @type: the built-in type to be validated against 6367 * @value: the resulting value if any 6368 * 6369 * Extracts and validates a value against the given built-in type. 6370 * This one is intended to be used internally for validation 6371 * of schema attribute values during parsing of the schema. 6372 * 6373 * Returns 0 if the value is valid, a positive error code 6374 * number otherwise and -1 in case of an internal or API error. 6375 */ 6376 static int 6377 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt, 6378 xmlSchemaBasicItemPtr ownerItem, 6379 xmlAttrPtr attr, 6380 xmlSchemaTypePtr type, 6381 const xmlChar **value) 6382 { 6383 const xmlChar *val; 6384 6385 if ((ctxt == NULL) || (type == NULL) || (attr == NULL)) 6386 return (-1); 6387 6388 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6389 if (value != NULL) 6390 *value = val; 6391 6392 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr, 6393 val, type)); 6394 } 6395 6396 /** 6397 * xmlSchemaPValAttr: 6398 * 6399 * @ctxt: a schema parser context 6400 * @node: the element node of the attribute 6401 * @ownerDes: the designation of the parent element 6402 * @ownerItem: the schema object owner if existent 6403 * @ownerElem: the owner element node 6404 * @name: the name of the schema attribute node 6405 * @type: the built-in type to be validated against 6406 * @value: the resulting value if any 6407 * 6408 * Extracts and validates a value against the given built-in type. 6409 * This one is intended to be used internally for validation 6410 * of schema attribute values during parsing of the schema. 6411 * 6412 * Returns 0 if the value is valid, a positive error code 6413 * number otherwise and -1 in case of an internal or API error. 6414 */ 6415 static int 6416 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt, 6417 xmlSchemaBasicItemPtr ownerItem, 6418 xmlNodePtr ownerElem, 6419 const char *name, 6420 xmlSchemaTypePtr type, 6421 const xmlChar **value) 6422 { 6423 xmlAttrPtr attr; 6424 6425 if ((ctxt == NULL) || (type == NULL)) { 6426 if (value != NULL) 6427 *value = NULL; 6428 return (-1); 6429 } 6430 if (type->type != XML_SCHEMA_TYPE_BASIC) { 6431 if (value != NULL) 6432 *value = NULL; 6433 xmlSchemaPErr(ctxt, ownerElem, 6434 XML_SCHEMAP_INTERNAL, 6435 "Internal error: xmlSchemaPValAttr, the given " 6436 "type '%s' is not a built-in type.\n", 6437 type->name, NULL); 6438 return (-1); 6439 } 6440 attr = xmlSchemaGetPropNode(ownerElem, name); 6441 if (attr == NULL) { 6442 if (value != NULL) 6443 *value = NULL; 6444 return (0); 6445 } 6446 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr, 6447 type, value)); 6448 } 6449 6450 static int 6451 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt, 6452 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6453 xmlNodePtr node, 6454 xmlAttrPtr attr, 6455 const xmlChar *namespaceName) 6456 { 6457 /* TODO: Pointer comparison instead? */ 6458 if (xmlStrEqual(pctxt->targetNamespace, namespaceName)) 6459 return (0); 6460 if (xmlStrEqual(xmlSchemaNs, namespaceName)) 6461 return (0); 6462 /* 6463 * Check if the referenced namespace was <import>ed. 6464 */ 6465 if (WXS_BUCKET(pctxt)->relations != NULL) { 6466 xmlSchemaSchemaRelationPtr rel; 6467 6468 rel = WXS_BUCKET(pctxt)->relations; 6469 do { 6470 if (WXS_IS_BUCKET_IMPMAIN(rel->type) && 6471 xmlStrEqual(namespaceName, rel->importNamespace)) 6472 return (0); 6473 rel = rel->next; 6474 } while (rel != NULL); 6475 } 6476 /* 6477 * No matching <import>ed namespace found. 6478 */ 6479 { 6480 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node; 6481 6482 if (namespaceName == NULL) 6483 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6484 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6485 "References from this schema to components in no " 6486 "namespace are not allowed, since not indicated by an " 6487 "import statement", NULL, NULL); 6488 else 6489 xmlSchemaCustomErr(ACTXT_CAST pctxt, 6490 XML_SCHEMAP_SRC_RESOLVE, n, NULL, 6491 "References from this schema to components in the " 6492 "namespace '%s' are not allowed, since not indicated by an " 6493 "import statement", namespaceName, NULL); 6494 } 6495 return (XML_SCHEMAP_SRC_RESOLVE); 6496 } 6497 6498 /** 6499 * xmlSchemaParseLocalAttributes: 6500 * @ctxt: a schema validation context 6501 * @schema: the schema being built 6502 * @node: a subtree containing XML Schema informations 6503 * @type: the hosting type where the attributes will be anchored 6504 * 6505 * Parses attribute uses and attribute declarations and 6506 * attribute group references. 6507 */ 6508 static int 6509 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6510 xmlNodePtr *child, xmlSchemaItemListPtr *list, 6511 int parentType, int *hasRefs) 6512 { 6513 void *item; 6514 6515 while ((IS_SCHEMA((*child), "attribute")) || 6516 (IS_SCHEMA((*child), "attributeGroup"))) { 6517 if (IS_SCHEMA((*child), "attribute")) { 6518 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child, 6519 *list, parentType); 6520 } else { 6521 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child); 6522 if ((item != NULL) && (hasRefs != NULL)) 6523 *hasRefs = 1; 6524 } 6525 if (item != NULL) { 6526 if (*list == NULL) { 6527 /* TODO: Customize grow factor. */ 6528 *list = xmlSchemaItemListCreate(); 6529 if (*list == NULL) 6530 return(-1); 6531 } 6532 if (xmlSchemaItemListAddSize(*list, 2, item) == -1) 6533 return(-1); 6534 } 6535 *child = (*child)->next; 6536 } 6537 return (0); 6538 } 6539 6540 /** 6541 * xmlSchemaParseAnnotation: 6542 * @ctxt: a schema validation context 6543 * @schema: the schema being built 6544 * @node: a subtree containing XML Schema informations 6545 * 6546 * parse a XML schema Attrribute declaration 6547 * *WARNING* this interface is highly subject to change 6548 * 6549 * Returns -1 in case of error, 0 if the declaration is improper and 6550 * 1 in case of success. 6551 */ 6552 static xmlSchemaAnnotPtr 6553 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed) 6554 { 6555 xmlSchemaAnnotPtr ret; 6556 xmlNodePtr child = NULL; 6557 xmlAttrPtr attr; 6558 int barked = 0; 6559 6560 /* 6561 * INFO: S4S completed. 6562 */ 6563 /* 6564 * id = ID 6565 * {any attributes with non-schema namespace . . .}> 6566 * Content: (appinfo | documentation)* 6567 */ 6568 if ((ctxt == NULL) || (node == NULL)) 6569 return (NULL); 6570 if (needed) 6571 ret = xmlSchemaNewAnnot(ctxt, node); 6572 else 6573 ret = NULL; 6574 attr = node->properties; 6575 while (attr != NULL) { 6576 if (((attr->ns == NULL) && 6577 (!xmlStrEqual(attr->name, BAD_CAST "id"))) || 6578 ((attr->ns != NULL) && 6579 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6580 6581 xmlSchemaPIllegalAttrErr(ctxt, 6582 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6583 } 6584 attr = attr->next; 6585 } 6586 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6587 /* 6588 * And now for the children... 6589 */ 6590 child = node->children; 6591 while (child != NULL) { 6592 if (IS_SCHEMA(child, "appinfo")) { 6593 /* TODO: make available the content of "appinfo". */ 6594 /* 6595 * source = anyURI 6596 * {any attributes with non-schema namespace . . .}> 6597 * Content: ({any})* 6598 */ 6599 attr = child->properties; 6600 while (attr != NULL) { 6601 if (((attr->ns == NULL) && 6602 (!xmlStrEqual(attr->name, BAD_CAST "source"))) || 6603 ((attr->ns != NULL) && 6604 xmlStrEqual(attr->ns->href, xmlSchemaNs))) { 6605 6606 xmlSchemaPIllegalAttrErr(ctxt, 6607 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6608 } 6609 attr = attr->next; 6610 } 6611 xmlSchemaPValAttr(ctxt, NULL, child, "source", 6612 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 6613 child = child->next; 6614 } else if (IS_SCHEMA(child, "documentation")) { 6615 /* TODO: make available the content of "documentation". */ 6616 /* 6617 * source = anyURI 6618 * {any attributes with non-schema namespace . . .}> 6619 * Content: ({any})* 6620 */ 6621 attr = child->properties; 6622 while (attr != NULL) { 6623 if (attr->ns == NULL) { 6624 if (!xmlStrEqual(attr->name, BAD_CAST "source")) { 6625 xmlSchemaPIllegalAttrErr(ctxt, 6626 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6627 } 6628 } else { 6629 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) || 6630 (xmlStrEqual(attr->name, BAD_CAST "lang") && 6631 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) { 6632 6633 xmlSchemaPIllegalAttrErr(ctxt, 6634 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6635 } 6636 } 6637 attr = attr->next; 6638 } 6639 /* 6640 * Attribute "xml:lang". 6641 */ 6642 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang"); 6643 if (attr != NULL) 6644 xmlSchemaPValAttrNode(ctxt, NULL, attr, 6645 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL); 6646 child = child->next; 6647 } else { 6648 if (!barked) 6649 xmlSchemaPContentErr(ctxt, 6650 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6651 NULL, node, child, NULL, "(appinfo | documentation)*"); 6652 barked = 1; 6653 child = child->next; 6654 } 6655 } 6656 6657 return (ret); 6658 } 6659 6660 /** 6661 * xmlSchemaParseFacet: 6662 * @ctxt: a schema validation context 6663 * @schema: the schema being built 6664 * @node: a subtree containing XML Schema informations 6665 * 6666 * parse a XML schema Facet declaration 6667 * *WARNING* this interface is highly subject to change 6668 * 6669 * Returns the new type structure or NULL in case of error 6670 */ 6671 static xmlSchemaFacetPtr 6672 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6673 xmlNodePtr node) 6674 { 6675 xmlSchemaFacetPtr facet; 6676 xmlNodePtr child = NULL; 6677 const xmlChar *value; 6678 6679 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6680 return (NULL); 6681 6682 facet = xmlSchemaNewFacet(); 6683 if (facet == NULL) { 6684 xmlSchemaPErrMemory(ctxt, "allocating facet", node); 6685 return (NULL); 6686 } 6687 facet->node = node; 6688 value = xmlSchemaGetProp(ctxt, node, "value"); 6689 if (value == NULL) { 6690 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE, 6691 "Facet %s has no value\n", node->name, NULL); 6692 xmlSchemaFreeFacet(facet); 6693 return (NULL); 6694 } 6695 if (IS_SCHEMA(node, "minInclusive")) { 6696 facet->type = XML_SCHEMA_FACET_MININCLUSIVE; 6697 } else if (IS_SCHEMA(node, "minExclusive")) { 6698 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; 6699 } else if (IS_SCHEMA(node, "maxInclusive")) { 6700 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; 6701 } else if (IS_SCHEMA(node, "maxExclusive")) { 6702 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; 6703 } else if (IS_SCHEMA(node, "totalDigits")) { 6704 facet->type = XML_SCHEMA_FACET_TOTALDIGITS; 6705 } else if (IS_SCHEMA(node, "fractionDigits")) { 6706 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; 6707 } else if (IS_SCHEMA(node, "pattern")) { 6708 facet->type = XML_SCHEMA_FACET_PATTERN; 6709 } else if (IS_SCHEMA(node, "enumeration")) { 6710 facet->type = XML_SCHEMA_FACET_ENUMERATION; 6711 } else if (IS_SCHEMA(node, "whiteSpace")) { 6712 facet->type = XML_SCHEMA_FACET_WHITESPACE; 6713 } else if (IS_SCHEMA(node, "length")) { 6714 facet->type = XML_SCHEMA_FACET_LENGTH; 6715 } else if (IS_SCHEMA(node, "maxLength")) { 6716 facet->type = XML_SCHEMA_FACET_MAXLENGTH; 6717 } else if (IS_SCHEMA(node, "minLength")) { 6718 facet->type = XML_SCHEMA_FACET_MINLENGTH; 6719 } else { 6720 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE, 6721 "Unknown facet type %s\n", node->name, NULL); 6722 xmlSchemaFreeFacet(facet); 6723 return (NULL); 6724 } 6725 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6726 facet->value = value; 6727 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 6728 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 6729 const xmlChar *fixed; 6730 6731 fixed = xmlSchemaGetProp(ctxt, node, "fixed"); 6732 if (fixed != NULL) { 6733 if (xmlStrEqual(fixed, BAD_CAST "true")) 6734 facet->fixed = 1; 6735 } 6736 } 6737 child = node->children; 6738 6739 if (IS_SCHEMA(child, "annotation")) { 6740 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6741 child = child->next; 6742 } 6743 if (child != NULL) { 6744 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD, 6745 "Facet %s has unexpected child content\n", 6746 node->name, NULL); 6747 } 6748 return (facet); 6749 } 6750 6751 /** 6752 * xmlSchemaParseWildcardNs: 6753 * @ctxt: a schema parser context 6754 * @wildc: the wildcard, already created 6755 * @node: a subtree containing XML Schema informations 6756 * 6757 * Parses the attribute "processContents" and "namespace" 6758 * of a xsd:anyAttribute and xsd:any. 6759 * *WARNING* this interface is highly subject to change 6760 * 6761 * Returns 0 if everything goes fine, a positive error code 6762 * if something is not valid and -1 if an internal error occurs. 6763 */ 6764 static int 6765 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt, 6766 xmlSchemaPtr schema ATTRIBUTE_UNUSED, 6767 xmlSchemaWildcardPtr wildc, 6768 xmlNodePtr node) 6769 { 6770 const xmlChar *pc, *ns, *dictnsItem; 6771 int ret = 0; 6772 xmlChar *nsItem; 6773 xmlSchemaWildcardNsPtr tmp, lastNs = NULL; 6774 xmlAttrPtr attr; 6775 6776 pc = xmlSchemaGetProp(ctxt, node, "processContents"); 6777 if ((pc == NULL) 6778 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) { 6779 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6780 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) { 6781 wildc->processContents = XML_SCHEMAS_ANY_SKIP; 6782 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) { 6783 wildc->processContents = XML_SCHEMAS_ANY_LAX; 6784 } else { 6785 xmlSchemaPSimpleTypeErr(ctxt, 6786 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 6787 NULL, node, 6788 NULL, "(strict | skip | lax)", pc, 6789 NULL, NULL, NULL); 6790 wildc->processContents = XML_SCHEMAS_ANY_STRICT; 6791 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 6792 } 6793 /* 6794 * Build the namespace constraints. 6795 */ 6796 attr = xmlSchemaGetPropNode(node, "namespace"); 6797 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 6798 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any"))) 6799 wildc->any = 1; 6800 else if (xmlStrEqual(ns, BAD_CAST "##other")) { 6801 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 6802 if (wildc->negNsSet == NULL) { 6803 return (-1); 6804 } 6805 wildc->negNsSet->value = ctxt->targetNamespace; 6806 } else { 6807 const xmlChar *end, *cur; 6808 6809 cur = ns; 6810 do { 6811 while (IS_BLANK_CH(*cur)) 6812 cur++; 6813 end = cur; 6814 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 6815 end++; 6816 if (end == cur) 6817 break; 6818 nsItem = xmlStrndup(cur, end - cur); 6819 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) || 6820 (xmlStrEqual(nsItem, BAD_CAST "##any"))) { 6821 xmlSchemaPSimpleTypeErr(ctxt, 6822 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, 6823 NULL, (xmlNodePtr) attr, 6824 NULL, 6825 "((##any | ##other) | List of (xs:anyURI | " 6826 "(##targetNamespace | ##local)))", 6827 nsItem, NULL, NULL, NULL); 6828 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER; 6829 } else { 6830 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) { 6831 dictnsItem = ctxt->targetNamespace; 6832 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) { 6833 dictnsItem = NULL; 6834 } else { 6835 /* 6836 * Validate the item (anyURI). 6837 */ 6838 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr, 6839 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI)); 6840 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1); 6841 } 6842 /* 6843 * Avoid dublicate namespaces. 6844 */ 6845 tmp = wildc->nsSet; 6846 while (tmp != NULL) { 6847 if (dictnsItem == tmp->value) 6848 break; 6849 tmp = tmp->next; 6850 } 6851 if (tmp == NULL) { 6852 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 6853 if (tmp == NULL) { 6854 xmlFree(nsItem); 6855 return (-1); 6856 } 6857 tmp->value = dictnsItem; 6858 tmp->next = NULL; 6859 if (wildc->nsSet == NULL) 6860 wildc->nsSet = tmp; 6861 else if (lastNs != NULL) 6862 lastNs->next = tmp; 6863 lastNs = tmp; 6864 } 6865 6866 } 6867 xmlFree(nsItem); 6868 cur = end; 6869 } while (*cur != 0); 6870 } 6871 return (ret); 6872 } 6873 6874 static int 6875 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt, 6876 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED, 6877 xmlNodePtr node, 6878 int minOccurs, 6879 int maxOccurs) { 6880 6881 if ((maxOccurs == 0) && ( minOccurs == 0)) 6882 return (0); 6883 if (maxOccurs != UNBOUNDED) { 6884 /* 6885 * TODO: Maybe we should better not create the particle, 6886 * if min/max is invalid, since it could confuse the build of the 6887 * content model. 6888 */ 6889 /* 6890 * 3.9.6 Schema Component Constraint: Particle Correct 6891 * 6892 */ 6893 if (maxOccurs < 1) { 6894 /* 6895 * 2.2 {max occurs} must be greater than or equal to 1. 6896 */ 6897 xmlSchemaPCustomAttrErr(ctxt, 6898 XML_SCHEMAP_P_PROPS_CORRECT_2_2, 6899 NULL, NULL, 6900 xmlSchemaGetPropNode(node, "maxOccurs"), 6901 "The value must be greater than or equal to 1"); 6902 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2); 6903 } else if (minOccurs > maxOccurs) { 6904 /* 6905 * 2.1 {min occurs} must not be greater than {max occurs}. 6906 */ 6907 xmlSchemaPCustomAttrErr(ctxt, 6908 XML_SCHEMAP_P_PROPS_CORRECT_2_1, 6909 NULL, NULL, 6910 xmlSchemaGetPropNode(node, "minOccurs"), 6911 "The value must not be greater than the value of 'maxOccurs'"); 6912 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1); 6913 } 6914 } 6915 return (0); 6916 } 6917 6918 /** 6919 * xmlSchemaParseAny: 6920 * @ctxt: a schema validation context 6921 * @schema: the schema being built 6922 * @node: a subtree containing XML Schema informations 6923 * 6924 * Parsea a XML schema <any> element. A particle and wildcard 6925 * will be created (except if minOccurs==maxOccurs==0, in this case 6926 * nothing will be created). 6927 * *WARNING* this interface is highly subject to change 6928 * 6929 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0 6930 */ 6931 static xmlSchemaParticlePtr 6932 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 6933 xmlNodePtr node) 6934 { 6935 xmlSchemaParticlePtr particle; 6936 xmlNodePtr child = NULL; 6937 xmlSchemaWildcardPtr wild; 6938 int min, max; 6939 xmlAttrPtr attr; 6940 xmlSchemaAnnotPtr annot = NULL; 6941 6942 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 6943 return (NULL); 6944 /* 6945 * Check for illegal attributes. 6946 */ 6947 attr = node->properties; 6948 while (attr != NULL) { 6949 if (attr->ns == NULL) { 6950 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 6951 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 6952 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 6953 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 6954 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 6955 xmlSchemaPIllegalAttrErr(ctxt, 6956 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6957 } 6958 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 6959 xmlSchemaPIllegalAttrErr(ctxt, 6960 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 6961 } 6962 attr = attr->next; 6963 } 6964 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 6965 /* 6966 * minOccurs/maxOccurs. 6967 */ 6968 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 6969 "(xs:nonNegativeInteger | unbounded)"); 6970 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, 6971 "xs:nonNegativeInteger"); 6972 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 6973 /* 6974 * Create & parse the wildcard. 6975 */ 6976 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node); 6977 if (wild == NULL) 6978 return (NULL); 6979 xmlSchemaParseWildcardNs(ctxt, schema, wild, node); 6980 /* 6981 * And now for the children... 6982 */ 6983 child = node->children; 6984 if (IS_SCHEMA(child, "annotation")) { 6985 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 6986 child = child->next; 6987 } 6988 if (child != NULL) { 6989 xmlSchemaPContentErr(ctxt, 6990 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 6991 NULL, node, child, 6992 NULL, "(annotation?)"); 6993 } 6994 /* 6995 * No component if minOccurs==maxOccurs==0. 6996 */ 6997 if ((min == 0) && (max == 0)) { 6998 /* Don't free the wildcard, since it's already on the list. */ 6999 return (NULL); 7000 } 7001 /* 7002 * Create the particle. 7003 */ 7004 particle = xmlSchemaAddParticle(ctxt, node, min, max); 7005 if (particle == NULL) 7006 return (NULL); 7007 particle->annot = annot; 7008 particle->children = (xmlSchemaTreeItemPtr) wild; 7009 7010 return (particle); 7011 } 7012 7013 /** 7014 * xmlSchemaParseNotation: 7015 * @ctxt: a schema validation context 7016 * @schema: the schema being built 7017 * @node: a subtree containing XML Schema informations 7018 * 7019 * parse a XML schema Notation declaration 7020 * 7021 * Returns the new structure or NULL in case of error 7022 */ 7023 static xmlSchemaNotationPtr 7024 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 7025 xmlNodePtr node) 7026 { 7027 const xmlChar *name; 7028 xmlSchemaNotationPtr ret; 7029 xmlNodePtr child = NULL; 7030 7031 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7032 return (NULL); 7033 name = xmlSchemaGetProp(ctxt, node, "name"); 7034 if (name == NULL) { 7035 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME, 7036 "Notation has no name\n", NULL, NULL); 7037 return (NULL); 7038 } 7039 ret = xmlSchemaAddNotation(ctxt, schema, name, 7040 ctxt->targetNamespace, node); 7041 if (ret == NULL) 7042 return (NULL); 7043 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7044 7045 child = node->children; 7046 if (IS_SCHEMA(child, "annotation")) { 7047 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7048 child = child->next; 7049 } 7050 if (child != NULL) { 7051 xmlSchemaPContentErr(ctxt, 7052 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7053 NULL, node, child, 7054 NULL, "(annotation?)"); 7055 } 7056 7057 return (ret); 7058 } 7059 7060 /** 7061 * xmlSchemaParseAnyAttribute: 7062 * @ctxt: a schema validation context 7063 * @schema: the schema being built 7064 * @node: a subtree containing XML Schema informations 7065 * 7066 * parse a XML schema AnyAttrribute declaration 7067 * *WARNING* this interface is highly subject to change 7068 * 7069 * Returns a wildcard or NULL. 7070 */ 7071 static xmlSchemaWildcardPtr 7072 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, 7073 xmlSchemaPtr schema, xmlNodePtr node) 7074 { 7075 xmlSchemaWildcardPtr ret; 7076 xmlNodePtr child = NULL; 7077 xmlAttrPtr attr; 7078 7079 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 7080 return (NULL); 7081 7082 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE, 7083 node); 7084 if (ret == NULL) { 7085 return (NULL); 7086 } 7087 /* 7088 * Check for illegal attributes. 7089 */ 7090 attr = node->properties; 7091 while (attr != NULL) { 7092 if (attr->ns == NULL) { 7093 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7094 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 7095 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) { 7096 xmlSchemaPIllegalAttrErr(ctxt, 7097 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7098 } 7099 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7100 xmlSchemaPIllegalAttrErr(ctxt, 7101 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7102 } 7103 attr = attr->next; 7104 } 7105 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 7106 /* 7107 * Parse the namespace list. 7108 */ 7109 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0) 7110 return (NULL); 7111 /* 7112 * And now for the children... 7113 */ 7114 child = node->children; 7115 if (IS_SCHEMA(child, "annotation")) { 7116 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 7117 child = child->next; 7118 } 7119 if (child != NULL) { 7120 xmlSchemaPContentErr(ctxt, 7121 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7122 NULL, node, child, 7123 NULL, "(annotation?)"); 7124 } 7125 7126 return (ret); 7127 } 7128 7129 7130 /** 7131 * xmlSchemaParseAttribute: 7132 * @ctxt: a schema validation context 7133 * @schema: the schema being built 7134 * @node: a subtree containing XML Schema informations 7135 * 7136 * parse a XML schema Attrribute declaration 7137 * *WARNING* this interface is highly subject to change 7138 * 7139 * Returns the attribute declaration. 7140 */ 7141 static xmlSchemaBasicItemPtr 7142 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt, 7143 xmlSchemaPtr schema, 7144 xmlNodePtr node, 7145 xmlSchemaItemListPtr uses, 7146 int parentType) 7147 { 7148 const xmlChar *attrValue, *name = NULL, *ns = NULL; 7149 xmlSchemaAttributeUsePtr use = NULL; 7150 xmlNodePtr child = NULL; 7151 xmlAttrPtr attr; 7152 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL; 7153 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7154 int nberrors, hasForm = 0, defValueType = 0; 7155 7156 #define WXS_ATTR_DEF_VAL_DEFAULT 1 7157 #define WXS_ATTR_DEF_VAL_FIXED 2 7158 7159 /* 7160 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7161 */ 7162 7163 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7164 return (NULL); 7165 attr = xmlSchemaGetPropNode(node, "ref"); 7166 if (attr != NULL) { 7167 if (xmlSchemaPValAttrNodeQName(pctxt, schema, 7168 NULL, attr, &tmpNs, &tmpName) != 0) { 7169 return (NULL); 7170 } 7171 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0) 7172 return(NULL); 7173 isRef = 1; 7174 } 7175 nberrors = pctxt->nberrors; 7176 /* 7177 * Check for illegal attributes. 7178 */ 7179 attr = node->properties; 7180 while (attr != NULL) { 7181 if (attr->ns == NULL) { 7182 if (isRef) { 7183 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7184 xmlSchemaPValAttrNodeID(pctxt, attr); 7185 goto attr_next; 7186 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) { 7187 goto attr_next; 7188 } 7189 } else { 7190 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 7191 goto attr_next; 7192 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) { 7193 xmlSchemaPValAttrNodeID(pctxt, attr); 7194 goto attr_next; 7195 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) { 7196 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL, 7197 attr, &tmpNs, &tmpName); 7198 goto attr_next; 7199 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) { 7200 /* 7201 * Evaluate the target namespace 7202 */ 7203 hasForm = 1; 7204 attrValue = xmlSchemaGetNodeContent(pctxt, 7205 (xmlNodePtr) attr); 7206 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 7207 ns = pctxt->targetNamespace; 7208 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) 7209 { 7210 xmlSchemaPSimpleTypeErr(pctxt, 7211 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 7212 NULL, (xmlNodePtr) attr, 7213 NULL, "(qualified | unqualified)", 7214 attrValue, NULL, NULL, NULL); 7215 } 7216 goto attr_next; 7217 } 7218 } 7219 if (xmlStrEqual(attr->name, BAD_CAST "use")) { 7220 7221 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7222 /* TODO: Maybe we need to normalize the value beforehand. */ 7223 if (xmlStrEqual(attrValue, BAD_CAST "optional")) 7224 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL; 7225 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited")) 7226 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED; 7227 else if (xmlStrEqual(attrValue, BAD_CAST "required")) 7228 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED; 7229 else { 7230 xmlSchemaPSimpleTypeErr(pctxt, 7231 XML_SCHEMAP_INVALID_ATTR_USE, 7232 NULL, (xmlNodePtr) attr, 7233 NULL, "(optional | prohibited | required)", 7234 attrValue, NULL, NULL, NULL); 7235 } 7236 goto attr_next; 7237 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) { 7238 /* 7239 * 3.2.3 : 1 7240 * default and fixed must not both be present. 7241 */ 7242 if (defValue) { 7243 xmlSchemaPMutualExclAttrErr(pctxt, 7244 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7245 NULL, attr, "default", "fixed"); 7246 } else { 7247 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7248 defValueType = WXS_ATTR_DEF_VAL_DEFAULT; 7249 } 7250 goto attr_next; 7251 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) { 7252 /* 7253 * 3.2.3 : 1 7254 * default and fixed must not both be present. 7255 */ 7256 if (defValue) { 7257 xmlSchemaPMutualExclAttrErr(pctxt, 7258 XML_SCHEMAP_SRC_ATTRIBUTE_1, 7259 NULL, attr, "default", "fixed"); 7260 } else { 7261 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7262 defValueType = WXS_ATTR_DEF_VAL_FIXED; 7263 } 7264 goto attr_next; 7265 } 7266 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs)) 7267 goto attr_next; 7268 7269 xmlSchemaPIllegalAttrErr(pctxt, 7270 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7271 7272 attr_next: 7273 attr = attr->next; 7274 } 7275 /* 7276 * 3.2.3 : 2 7277 * If default and use are both present, use must have 7278 * the actual value optional. 7279 */ 7280 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) && 7281 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) { 7282 xmlSchemaPSimpleTypeErr(pctxt, 7283 XML_SCHEMAP_SRC_ATTRIBUTE_2, 7284 NULL, node, NULL, 7285 "(optional | prohibited | required)", NULL, 7286 "The value of the attribute 'use' must be 'optional' " 7287 "if the attribute 'default' is present", 7288 NULL, NULL); 7289 } 7290 /* 7291 * We want correct attributes. 7292 */ 7293 if (nberrors != pctxt->nberrors) 7294 return(NULL); 7295 if (! isRef) { 7296 xmlSchemaAttributePtr attrDecl; 7297 7298 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */ 7299 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR)) 7300 ns = pctxt->targetNamespace; 7301 /* 7302 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7303 * TODO: Move this to the component layer. 7304 */ 7305 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) { 7306 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7307 XML_SCHEMAP_NO_XSI, 7308 node, NULL, 7309 "The target namespace must not match '%s'", 7310 xmlSchemaInstanceNs, NULL); 7311 } 7312 attr = xmlSchemaGetPropNode(node, "name"); 7313 if (attr == NULL) { 7314 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7315 NULL, node, "name", NULL); 7316 return (NULL); 7317 } 7318 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7319 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7320 return (NULL); 7321 } 7322 /* 7323 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7324 * TODO: Move this to the component layer. 7325 */ 7326 if (xmlStrEqual(name, BAD_CAST "xmlns")) { 7327 xmlSchemaPSimpleTypeErr(pctxt, 7328 XML_SCHEMAP_NO_XMLNS, 7329 NULL, (xmlNodePtr) attr, 7330 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7331 "The value of the attribute must not match 'xmlns'", 7332 NULL, NULL); 7333 return (NULL); 7334 } 7335 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) 7336 goto check_children; 7337 /* 7338 * Create the attribute use component. 7339 */ 7340 use = xmlSchemaAddAttributeUse(pctxt, node); 7341 if (use == NULL) 7342 return(NULL); 7343 use->occurs = occurs; 7344 /* 7345 * Create the attribute declaration. 7346 */ 7347 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0); 7348 if (attrDecl == NULL) 7349 return (NULL); 7350 if (tmpName != NULL) { 7351 attrDecl->typeName = tmpName; 7352 attrDecl->typeNs = tmpNs; 7353 } 7354 use->attrDecl = attrDecl; 7355 /* 7356 * Value constraint. 7357 */ 7358 if (defValue != NULL) { 7359 attrDecl->defValue = defValue; 7360 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7361 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED; 7362 } 7363 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7364 xmlSchemaQNameRefPtr ref; 7365 7366 /* 7367 * Create the attribute use component. 7368 */ 7369 use = xmlSchemaAddAttributeUse(pctxt, node); 7370 if (use == NULL) 7371 return(NULL); 7372 /* 7373 * We need to resolve the reference at later stage. 7374 */ 7375 WXS_ADD_PENDING(pctxt, use); 7376 use->occurs = occurs; 7377 /* 7378 * Create a QName reference to the attribute declaration. 7379 */ 7380 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE, 7381 tmpName, tmpNs); 7382 if (ref == NULL) 7383 return(NULL); 7384 /* 7385 * Assign the reference. This will be substituted for the 7386 * referenced attribute declaration when the QName is resolved. 7387 */ 7388 use->attrDecl = WXS_ATTR_CAST ref; 7389 /* 7390 * Value constraint. 7391 */ 7392 if (defValue != NULL) 7393 use->defValue = defValue; 7394 if (defValueType == WXS_ATTR_DEF_VAL_FIXED) 7395 use->flags |= XML_SCHEMA_ATTR_USE_FIXED; 7396 } 7397 7398 check_children: 7399 /* 7400 * And now for the children... 7401 */ 7402 child = node->children; 7403 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) { 7404 xmlSchemaAttributeUseProhibPtr prohib; 7405 7406 if (IS_SCHEMA(child, "annotation")) { 7407 xmlSchemaParseAnnotation(pctxt, child, 0); 7408 child = child->next; 7409 } 7410 if (child != NULL) { 7411 xmlSchemaPContentErr(pctxt, 7412 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7413 NULL, node, child, NULL, 7414 "(annotation?)"); 7415 } 7416 /* 7417 * Check for pointlessness of attribute prohibitions. 7418 */ 7419 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { 7420 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7421 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7422 node, NULL, 7423 "Skipping attribute use prohibition, since it is " 7424 "pointless inside an <attributeGroup>", 7425 NULL, NULL, NULL); 7426 return(NULL); 7427 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) { 7428 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7429 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7430 node, NULL, 7431 "Skipping attribute use prohibition, since it is " 7432 "pointless when extending a type", 7433 NULL, NULL, NULL); 7434 return(NULL); 7435 } 7436 if (! isRef) { 7437 tmpName = name; 7438 tmpNs = ns; 7439 } 7440 /* 7441 * Check for duplicate attribute prohibitions. 7442 */ 7443 if (uses) { 7444 int i; 7445 7446 for (i = 0; i < uses->nbItems; i++) { 7447 use = uses->items[i]; 7448 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) && 7449 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) && 7450 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace)) 7451 { 7452 xmlChar *str = NULL; 7453 7454 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 7455 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, 7456 node, NULL, 7457 "Skipping duplicate attribute use prohibition '%s'", 7458 xmlSchemaFormatQName(&str, tmpNs, tmpName), 7459 NULL, NULL); 7460 FREE_AND_NULL(str) 7461 return(NULL); 7462 } 7463 } 7464 } 7465 /* 7466 * Create the attribute prohibition helper component. 7467 */ 7468 prohib = xmlSchemaAddAttributeUseProhib(pctxt); 7469 if (prohib == NULL) 7470 return(NULL); 7471 prohib->node = node; 7472 prohib->name = tmpName; 7473 prohib->targetNamespace = tmpNs; 7474 if (isRef) { 7475 /* 7476 * We need at least to resolve to the attribute declaration. 7477 */ 7478 WXS_ADD_PENDING(pctxt, prohib); 7479 } 7480 return(WXS_BASIC_CAST prohib); 7481 } else { 7482 if (IS_SCHEMA(child, "annotation")) { 7483 /* 7484 * TODO: Should this go into the attr decl? 7485 */ 7486 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7487 child = child->next; 7488 } 7489 if (isRef) { 7490 if (child != NULL) { 7491 if (IS_SCHEMA(child, "simpleType")) 7492 /* 7493 * 3.2.3 : 3.2 7494 * If ref is present, then all of <simpleType>, 7495 * form and type must be absent. 7496 */ 7497 xmlSchemaPContentErr(pctxt, 7498 XML_SCHEMAP_SRC_ATTRIBUTE_3_2, 7499 NULL, node, child, NULL, 7500 "(annotation?)"); 7501 else 7502 xmlSchemaPContentErr(pctxt, 7503 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7504 NULL, node, child, NULL, 7505 "(annotation?)"); 7506 } 7507 } else { 7508 if (IS_SCHEMA(child, "simpleType")) { 7509 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) { 7510 /* 7511 * 3.2.3 : 4 7512 * type and <simpleType> must not both be present. 7513 */ 7514 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7515 NULL, node, child, 7516 "The attribute 'type' and the <simpleType> child " 7517 "are mutually exclusive", NULL); 7518 } else 7519 WXS_ATTRUSE_TYPEDEF(use) = 7520 xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7521 child = child->next; 7522 } 7523 if (child != NULL) 7524 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7525 NULL, node, child, NULL, 7526 "(annotation?, simpleType?)"); 7527 } 7528 } 7529 return (WXS_BASIC_CAST use); 7530 } 7531 7532 7533 static xmlSchemaAttributePtr 7534 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt, 7535 xmlSchemaPtr schema, 7536 xmlNodePtr node) 7537 { 7538 const xmlChar *attrValue; 7539 xmlSchemaAttributePtr ret; 7540 xmlNodePtr child = NULL; 7541 xmlAttrPtr attr; 7542 7543 /* 7544 * Note that the w3c spec assumes the schema to be validated with schema 7545 * for schemas beforehand. 7546 * 7547 * 3.2.3 Constraints on XML Representations of Attribute Declarations 7548 */ 7549 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7550 return (NULL); 7551 /* 7552 * 3.2.3 : 3.1 7553 * One of ref or name must be present, but not both 7554 */ 7555 attr = xmlSchemaGetPropNode(node, "name"); 7556 if (attr == NULL) { 7557 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING, 7558 NULL, node, "name", NULL); 7559 return (NULL); 7560 } 7561 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 7562 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) { 7563 return (NULL); 7564 } 7565 /* 7566 * 3.2.6 Schema Component Constraint: xmlns Not Allowed 7567 * TODO: Move this to the component layer. 7568 */ 7569 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) { 7570 xmlSchemaPSimpleTypeErr(pctxt, 7571 XML_SCHEMAP_NO_XMLNS, 7572 NULL, (xmlNodePtr) attr, 7573 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL, 7574 "The value of the attribute must not match 'xmlns'", 7575 NULL, NULL); 7576 return (NULL); 7577 } 7578 /* 7579 * 3.2.6 Schema Component Constraint: xsi: Not Allowed 7580 * TODO: Move this to the component layer. 7581 * Or better leave it here and add it to the component layer 7582 * if we have a schema construction API. 7583 */ 7584 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) { 7585 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7586 XML_SCHEMAP_NO_XSI, node, NULL, 7587 "The target namespace must not match '%s'", 7588 xmlSchemaInstanceNs, NULL); 7589 } 7590 7591 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue, 7592 pctxt->targetNamespace, node, 1); 7593 if (ret == NULL) 7594 return (NULL); 7595 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL; 7596 7597 /* 7598 * Check for illegal attributes. 7599 */ 7600 attr = node->properties; 7601 while (attr != NULL) { 7602 if (attr->ns == NULL) { 7603 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 7604 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 7605 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 7606 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 7607 (!xmlStrEqual(attr->name, BAD_CAST "type"))) 7608 { 7609 xmlSchemaPIllegalAttrErr(pctxt, 7610 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7611 } 7612 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7613 xmlSchemaPIllegalAttrErr(pctxt, 7614 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7615 } 7616 attr = attr->next; 7617 } 7618 xmlSchemaPValAttrQName(pctxt, schema, NULL, 7619 node, "type", &ret->typeNs, &ret->typeName); 7620 7621 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7622 /* 7623 * Attribute "fixed". 7624 */ 7625 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed"); 7626 if (ret->defValue != NULL) 7627 ret->flags |= XML_SCHEMAS_ATTR_FIXED; 7628 /* 7629 * Attribute "default". 7630 */ 7631 attr = xmlSchemaGetPropNode(node, "default"); 7632 if (attr != NULL) { 7633 /* 7634 * 3.2.3 : 1 7635 * default and fixed must not both be present. 7636 */ 7637 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) { 7638 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1, 7639 WXS_BASIC_CAST ret, attr, "default", "fixed"); 7640 } else 7641 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr); 7642 } 7643 /* 7644 * And now for the children... 7645 */ 7646 child = node->children; 7647 if (IS_SCHEMA(child, "annotation")) { 7648 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7649 child = child->next; 7650 } 7651 if (IS_SCHEMA(child, "simpleType")) { 7652 if (ret->typeName != NULL) { 7653 /* 7654 * 3.2.3 : 4 7655 * type and <simpleType> must not both be present. 7656 */ 7657 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4, 7658 NULL, node, child, 7659 "The attribute 'type' and the <simpleType> child " 7660 "are mutually exclusive", NULL); 7661 } else 7662 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0); 7663 child = child->next; 7664 } 7665 if (child != NULL) 7666 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7667 NULL, node, child, NULL, 7668 "(annotation?, simpleType?)"); 7669 7670 return (ret); 7671 } 7672 7673 /** 7674 * xmlSchemaParseAttributeGroupRef: 7675 * @ctxt: a schema validation context 7676 * @schema: the schema being built 7677 * @node: a subtree containing XML Schema informations 7678 * 7679 * Parse an attribute group definition reference. 7680 * Note that a reference to an attribute group does not 7681 * correspond to any component at all. 7682 * *WARNING* this interface is highly subject to change 7683 * 7684 * Returns the attribute group or NULL in case of error. 7685 */ 7686 static xmlSchemaQNameRefPtr 7687 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt, 7688 xmlSchemaPtr schema, 7689 xmlNodePtr node) 7690 { 7691 xmlSchemaQNameRefPtr ret; 7692 xmlNodePtr child = NULL; 7693 xmlAttrPtr attr; 7694 const xmlChar *refNs = NULL, *ref = NULL; 7695 7696 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7697 return (NULL); 7698 7699 attr = xmlSchemaGetPropNode(node, "ref"); 7700 if (attr == NULL) { 7701 xmlSchemaPMissingAttrErr(pctxt, 7702 XML_SCHEMAP_S4S_ATTR_MISSING, 7703 NULL, node, "ref", NULL); 7704 return (NULL); 7705 } 7706 xmlSchemaPValAttrNodeQName(pctxt, schema, 7707 NULL, attr, &refNs, &ref); 7708 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0) 7709 return(NULL); 7710 7711 /* 7712 * Check for illegal attributes. 7713 */ 7714 attr = node->properties; 7715 while (attr != NULL) { 7716 if (attr->ns == NULL) { 7717 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 7718 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7719 { 7720 xmlSchemaPIllegalAttrErr(pctxt, 7721 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7722 } 7723 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7724 xmlSchemaPIllegalAttrErr(pctxt, 7725 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7726 } 7727 attr = attr->next; 7728 } 7729 /* Attribute ID */ 7730 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7731 7732 /* 7733 * And now for the children... 7734 */ 7735 child = node->children; 7736 if (IS_SCHEMA(child, "annotation")) { 7737 /* 7738 * TODO: We do not have a place to store the annotation, do we? 7739 */ 7740 xmlSchemaParseAnnotation(pctxt, child, 0); 7741 child = child->next; 7742 } 7743 if (child != NULL) { 7744 xmlSchemaPContentErr(pctxt, 7745 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7746 NULL, node, child, NULL, 7747 "(annotation?)"); 7748 } 7749 7750 /* 7751 * Handle attribute group redefinitions. 7752 */ 7753 if (pctxt->isRedefine && pctxt->redef && 7754 (pctxt->redef->item->type == 7755 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) && 7756 (ref == pctxt->redef->refName) && 7757 (refNs == pctxt->redef->refTargetNs)) 7758 { 7759 /* 7760 * SPEC src-redefine: 7761 * (7.1) "If it has an <attributeGroup> among its contents 7762 * the `actual value` of whose ref [attribute] is the same 7763 * as the `actual value` of its own name attribute plus 7764 * target namespace, then it must have exactly one such group." 7765 */ 7766 if (pctxt->redefCounter != 0) { 7767 xmlChar *str = NULL; 7768 7769 xmlSchemaCustomErr(ACTXT_CAST pctxt, 7770 XML_SCHEMAP_SRC_REDEFINE, node, NULL, 7771 "The redefining attribute group definition " 7772 "'%s' must not contain more than one " 7773 "reference to the redefined definition", 7774 xmlSchemaFormatQName(&str, refNs, ref), NULL); 7775 FREE_AND_NULL(str); 7776 return(NULL); 7777 } 7778 pctxt->redefCounter++; 7779 /* 7780 * URGENT TODO: How to ensure that the reference will not be 7781 * handled by the normal component resolution mechanism? 7782 */ 7783 ret = xmlSchemaNewQNameRef(pctxt, 7784 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7785 if (ret == NULL) 7786 return(NULL); 7787 ret->node = node; 7788 pctxt->redef->reference = WXS_BASIC_CAST ret; 7789 } else { 7790 /* 7791 * Create a QName-reference helper component. We will substitute this 7792 * component for the attribute uses of the referenced attribute group 7793 * definition. 7794 */ 7795 ret = xmlSchemaNewQNameRef(pctxt, 7796 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs); 7797 if (ret == NULL) 7798 return(NULL); 7799 ret->node = node; 7800 /* Add to pending items, to be able to resolve the reference. */ 7801 WXS_ADD_PENDING(pctxt, ret); 7802 } 7803 return (ret); 7804 } 7805 7806 /** 7807 * xmlSchemaParseAttributeGroupDefinition: 7808 * @pctxt: a schema validation context 7809 * @schema: the schema being built 7810 * @node: a subtree containing XML Schema informations 7811 * 7812 * parse a XML schema Attribute Group declaration 7813 * *WARNING* this interface is highly subject to change 7814 * 7815 * Returns the attribute group definition or NULL in case of error. 7816 */ 7817 static xmlSchemaAttributeGroupPtr 7818 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt, 7819 xmlSchemaPtr schema, 7820 xmlNodePtr node) 7821 { 7822 const xmlChar *name; 7823 xmlSchemaAttributeGroupPtr ret; 7824 xmlNodePtr child = NULL; 7825 xmlAttrPtr attr; 7826 int hasRefs = 0; 7827 7828 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 7829 return (NULL); 7830 7831 attr = xmlSchemaGetPropNode(node, "name"); 7832 if (attr == NULL) { 7833 xmlSchemaPMissingAttrErr(pctxt, 7834 XML_SCHEMAP_S4S_ATTR_MISSING, 7835 NULL, node, "name", NULL); 7836 return (NULL); 7837 } 7838 /* 7839 * The name is crucial, exit if invalid. 7840 */ 7841 if (xmlSchemaPValAttrNode(pctxt, 7842 NULL, attr, 7843 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 7844 return (NULL); 7845 } 7846 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema, 7847 name, pctxt->targetNamespace, node); 7848 if (ret == NULL) 7849 return (NULL); 7850 /* 7851 * Check for illegal attributes. 7852 */ 7853 attr = node->properties; 7854 while (attr != NULL) { 7855 if (attr->ns == NULL) { 7856 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 7857 (!xmlStrEqual(attr->name, BAD_CAST "id"))) 7858 { 7859 xmlSchemaPIllegalAttrErr(pctxt, 7860 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7861 } 7862 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 7863 xmlSchemaPIllegalAttrErr(pctxt, 7864 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 7865 } 7866 attr = attr->next; 7867 } 7868 /* Attribute ID */ 7869 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 7870 /* 7871 * And now for the children... 7872 */ 7873 child = node->children; 7874 if (IS_SCHEMA(child, "annotation")) { 7875 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1); 7876 child = child->next; 7877 } 7878 /* 7879 * Parse contained attribute decls/refs. 7880 */ 7881 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child, 7882 (xmlSchemaItemListPtr *) &(ret->attrUses), 7883 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1) 7884 return(NULL); 7885 if (hasRefs) 7886 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS; 7887 /* 7888 * Parse the attribute wildcard. 7889 */ 7890 if (IS_SCHEMA(child, "anyAttribute")) { 7891 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt, 7892 schema, child); 7893 child = child->next; 7894 } 7895 if (child != NULL) { 7896 xmlSchemaPContentErr(pctxt, 7897 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 7898 NULL, node, child, NULL, 7899 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))"); 7900 } 7901 return (ret); 7902 } 7903 7904 /** 7905 * xmlSchemaPValAttrFormDefault: 7906 * @value: the value 7907 * @flags: the flags to be modified 7908 * @flagQualified: the specific flag for "qualified" 7909 * 7910 * Returns 0 if the value is valid, 1 otherwise. 7911 */ 7912 static int 7913 xmlSchemaPValAttrFormDefault(const xmlChar *value, 7914 int *flags, 7915 int flagQualified) 7916 { 7917 if (xmlStrEqual(value, BAD_CAST "qualified")) { 7918 if ((*flags & flagQualified) == 0) 7919 *flags |= flagQualified; 7920 } else if (!xmlStrEqual(value, BAD_CAST "unqualified")) 7921 return (1); 7922 7923 return (0); 7924 } 7925 7926 /** 7927 * xmlSchemaPValAttrBlockFinal: 7928 * @value: the value 7929 * @flags: the flags to be modified 7930 * @flagAll: the specific flag for "#all" 7931 * @flagExtension: the specific flag for "extension" 7932 * @flagRestriction: the specific flag for "restriction" 7933 * @flagSubstitution: the specific flag for "substitution" 7934 * @flagList: the specific flag for "list" 7935 * @flagUnion: the specific flag for "union" 7936 * 7937 * Validates the value of the attribute "final" and "block". The value 7938 * is converted into the specified flag values and returned in @flags. 7939 * 7940 * Returns 0 if the value is valid, 1 otherwise. 7941 */ 7942 7943 static int 7944 xmlSchemaPValAttrBlockFinal(const xmlChar *value, 7945 int *flags, 7946 int flagAll, 7947 int flagExtension, 7948 int flagRestriction, 7949 int flagSubstitution, 7950 int flagList, 7951 int flagUnion) 7952 { 7953 int ret = 0; 7954 7955 /* 7956 * TODO: This does not check for dublicate entries. 7957 */ 7958 if ((flags == NULL) || (value == NULL)) 7959 return (-1); 7960 if (value[0] == 0) 7961 return (0); 7962 if (xmlStrEqual(value, BAD_CAST "#all")) { 7963 if (flagAll != -1) 7964 *flags |= flagAll; 7965 else { 7966 if (flagExtension != -1) 7967 *flags |= flagExtension; 7968 if (flagRestriction != -1) 7969 *flags |= flagRestriction; 7970 if (flagSubstitution != -1) 7971 *flags |= flagSubstitution; 7972 if (flagList != -1) 7973 *flags |= flagList; 7974 if (flagUnion != -1) 7975 *flags |= flagUnion; 7976 } 7977 } else { 7978 const xmlChar *end, *cur = value; 7979 xmlChar *item; 7980 7981 do { 7982 while (IS_BLANK_CH(*cur)) 7983 cur++; 7984 end = cur; 7985 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 7986 end++; 7987 if (end == cur) 7988 break; 7989 item = xmlStrndup(cur, end - cur); 7990 if (xmlStrEqual(item, BAD_CAST "extension")) { 7991 if (flagExtension != -1) { 7992 if ((*flags & flagExtension) == 0) 7993 *flags |= flagExtension; 7994 } else 7995 ret = 1; 7996 } else if (xmlStrEqual(item, BAD_CAST "restriction")) { 7997 if (flagRestriction != -1) { 7998 if ((*flags & flagRestriction) == 0) 7999 *flags |= flagRestriction; 8000 } else 8001 ret = 1; 8002 } else if (xmlStrEqual(item, BAD_CAST "substitution")) { 8003 if (flagSubstitution != -1) { 8004 if ((*flags & flagSubstitution) == 0) 8005 *flags |= flagSubstitution; 8006 } else 8007 ret = 1; 8008 } else if (xmlStrEqual(item, BAD_CAST "list")) { 8009 if (flagList != -1) { 8010 if ((*flags & flagList) == 0) 8011 *flags |= flagList; 8012 } else 8013 ret = 1; 8014 } else if (xmlStrEqual(item, BAD_CAST "union")) { 8015 if (flagUnion != -1) { 8016 if ((*flags & flagUnion) == 0) 8017 *flags |= flagUnion; 8018 } else 8019 ret = 1; 8020 } else 8021 ret = 1; 8022 if (item != NULL) 8023 xmlFree(item); 8024 cur = end; 8025 } while ((ret == 0) && (*cur != 0)); 8026 } 8027 8028 return (ret); 8029 } 8030 8031 static int 8032 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, 8033 xmlSchemaIDCPtr idc, 8034 xmlSchemaIDCSelectPtr selector, 8035 xmlAttrPtr attr, 8036 int isField) 8037 { 8038 xmlNodePtr node; 8039 8040 /* 8041 * c-selector-xpath: 8042 * Schema Component Constraint: Selector Value OK 8043 * 8044 * TODO: 1 The {selector} must be a valid XPath expression, as defined 8045 * in [XPath]. 8046 */ 8047 if (selector == NULL) { 8048 xmlSchemaPErr(ctxt, idc->node, 8049 XML_SCHEMAP_INTERNAL, 8050 "Internal error: xmlSchemaCheckCSelectorXPath, " 8051 "the selector is not specified.\n", NULL, NULL); 8052 return (-1); 8053 } 8054 if (attr == NULL) 8055 node = idc->node; 8056 else 8057 node = (xmlNodePtr) attr; 8058 if (selector->xpath == NULL) { 8059 xmlSchemaPCustomErr(ctxt, 8060 /* TODO: Adjust error code. */ 8061 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8062 NULL, node, 8063 "The XPath expression of the selector is not valid", NULL); 8064 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8065 } else { 8066 const xmlChar **nsArray = NULL; 8067 xmlNsPtr *nsList = NULL; 8068 /* 8069 * Compile the XPath expression. 8070 */ 8071 /* 8072 * TODO: We need the array of in-scope namespaces for compilation. 8073 * TODO: Call xmlPatterncompile with different options for selector/ 8074 * field. 8075 */ 8076 if (attr == NULL) 8077 nsList = NULL; 8078 else 8079 nsList = xmlGetNsList(attr->doc, attr->parent); 8080 /* 8081 * Build an array of prefixes and namespaces. 8082 */ 8083 if (nsList != NULL) { 8084 int i, count = 0; 8085 8086 for (i = 0; nsList[i] != NULL; i++) 8087 count++; 8088 8089 nsArray = (const xmlChar **) xmlMalloc( 8090 (count * 2 + 1) * sizeof(const xmlChar *)); 8091 if (nsArray == NULL) { 8092 xmlSchemaPErrMemory(ctxt, "allocating a namespace array", 8093 NULL); 8094 xmlFree(nsList); 8095 return (-1); 8096 } 8097 for (i = 0; i < count; i++) { 8098 nsArray[2 * i] = nsList[i]->href; 8099 nsArray[2 * i + 1] = nsList[i]->prefix; 8100 } 8101 nsArray[count * 2] = NULL; 8102 xmlFree(nsList); 8103 } 8104 /* 8105 * TODO: Differentiate between "selector" and "field". 8106 */ 8107 if (isField) 8108 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8109 NULL, XML_PATTERN_XSFIELD, nsArray); 8110 else 8111 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, 8112 NULL, XML_PATTERN_XSSEL, nsArray); 8113 if (nsArray != NULL) 8114 xmlFree((xmlChar **) nsArray); 8115 8116 if (selector->xpathComp == NULL) { 8117 xmlSchemaPCustomErr(ctxt, 8118 /* TODO: Adjust error code? */ 8119 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8120 NULL, node, 8121 "The XPath expression '%s' could not be " 8122 "compiled", selector->xpath); 8123 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE); 8124 } 8125 } 8126 return (0); 8127 } 8128 8129 #define ADD_ANNOTATION(annot) \ 8130 xmlSchemaAnnotPtr cur = item->annot; \ 8131 if (item->annot == NULL) { \ 8132 item->annot = annot; \ 8133 return (annot); \ 8134 } \ 8135 cur = item->annot; \ 8136 if (cur->next != NULL) { \ 8137 cur = cur->next; \ 8138 } \ 8139 cur->next = annot; 8140 8141 /** 8142 * xmlSchemaAssignAnnotation: 8143 * @item: the schema component 8144 * @annot: the annotation 8145 * 8146 * Adds the annotation to the given schema component. 8147 * 8148 * Returns the given annotaion. 8149 */ 8150 static xmlSchemaAnnotPtr 8151 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem, 8152 xmlSchemaAnnotPtr annot) 8153 { 8154 if ((annItem == NULL) || (annot == NULL)) 8155 return (NULL); 8156 switch (annItem->type) { 8157 case XML_SCHEMA_TYPE_ELEMENT: { 8158 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem; 8159 ADD_ANNOTATION(annot) 8160 } 8161 break; 8162 case XML_SCHEMA_TYPE_ATTRIBUTE: { 8163 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem; 8164 ADD_ANNOTATION(annot) 8165 } 8166 break; 8167 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE: 8168 case XML_SCHEMA_TYPE_ANY: { 8169 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem; 8170 ADD_ANNOTATION(annot) 8171 } 8172 break; 8173 case XML_SCHEMA_TYPE_PARTICLE: 8174 case XML_SCHEMA_TYPE_IDC_KEY: 8175 case XML_SCHEMA_TYPE_IDC_KEYREF: 8176 case XML_SCHEMA_TYPE_IDC_UNIQUE: { 8177 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem; 8178 ADD_ANNOTATION(annot) 8179 } 8180 break; 8181 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: { 8182 xmlSchemaAttributeGroupPtr item = 8183 (xmlSchemaAttributeGroupPtr) annItem; 8184 ADD_ANNOTATION(annot) 8185 } 8186 break; 8187 case XML_SCHEMA_TYPE_NOTATION: { 8188 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem; 8189 ADD_ANNOTATION(annot) 8190 } 8191 break; 8192 case XML_SCHEMA_FACET_MININCLUSIVE: 8193 case XML_SCHEMA_FACET_MINEXCLUSIVE: 8194 case XML_SCHEMA_FACET_MAXINCLUSIVE: 8195 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 8196 case XML_SCHEMA_FACET_TOTALDIGITS: 8197 case XML_SCHEMA_FACET_FRACTIONDIGITS: 8198 case XML_SCHEMA_FACET_PATTERN: 8199 case XML_SCHEMA_FACET_ENUMERATION: 8200 case XML_SCHEMA_FACET_WHITESPACE: 8201 case XML_SCHEMA_FACET_LENGTH: 8202 case XML_SCHEMA_FACET_MAXLENGTH: 8203 case XML_SCHEMA_FACET_MINLENGTH: { 8204 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem; 8205 ADD_ANNOTATION(annot) 8206 } 8207 break; 8208 case XML_SCHEMA_TYPE_SIMPLE: 8209 case XML_SCHEMA_TYPE_COMPLEX: { 8210 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem; 8211 ADD_ANNOTATION(annot) 8212 } 8213 break; 8214 case XML_SCHEMA_TYPE_GROUP: { 8215 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem; 8216 ADD_ANNOTATION(annot) 8217 } 8218 break; 8219 case XML_SCHEMA_TYPE_SEQUENCE: 8220 case XML_SCHEMA_TYPE_CHOICE: 8221 case XML_SCHEMA_TYPE_ALL: { 8222 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem; 8223 ADD_ANNOTATION(annot) 8224 } 8225 break; 8226 default: 8227 xmlSchemaPCustomErr(NULL, 8228 XML_SCHEMAP_INTERNAL, 8229 NULL, NULL, 8230 "Internal error: xmlSchemaAddAnnotation, " 8231 "The item is not a annotated schema component", NULL); 8232 break; 8233 } 8234 return (annot); 8235 } 8236 8237 /** 8238 * xmlSchemaParseIDCSelectorAndField: 8239 * @ctxt: a schema validation context 8240 * @schema: the schema being built 8241 * @node: a subtree containing XML Schema informations 8242 * 8243 * Parses a XML Schema identity-contraint definition's 8244 * <selector> and <field> elements. 8245 * 8246 * Returns the parsed identity-constraint definition. 8247 */ 8248 static xmlSchemaIDCSelectPtr 8249 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt, 8250 xmlSchemaIDCPtr idc, 8251 xmlNodePtr node, 8252 int isField) 8253 { 8254 xmlSchemaIDCSelectPtr item; 8255 xmlNodePtr child = NULL; 8256 xmlAttrPtr attr; 8257 8258 /* 8259 * Check for illegal attributes. 8260 */ 8261 attr = node->properties; 8262 while (attr != NULL) { 8263 if (attr->ns == NULL) { 8264 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8265 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) { 8266 xmlSchemaPIllegalAttrErr(ctxt, 8267 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8268 } 8269 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8270 xmlSchemaPIllegalAttrErr(ctxt, 8271 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8272 } 8273 attr = attr->next; 8274 } 8275 /* 8276 * Create the item. 8277 */ 8278 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect)); 8279 if (item == NULL) { 8280 xmlSchemaPErrMemory(ctxt, 8281 "allocating a 'selector' of an identity-constraint definition", 8282 NULL); 8283 return (NULL); 8284 } 8285 memset(item, 0, sizeof(xmlSchemaIDCSelect)); 8286 /* 8287 * Attribute "xpath" (mandatory). 8288 */ 8289 attr = xmlSchemaGetPropNode(node, "xpath"); 8290 if (attr == NULL) { 8291 xmlSchemaPMissingAttrErr(ctxt, 8292 XML_SCHEMAP_S4S_ATTR_MISSING, 8293 NULL, node, 8294 "name", NULL); 8295 } else { 8296 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8297 /* 8298 * URGENT TODO: "field"s have an other syntax than "selector"s. 8299 */ 8300 8301 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr, 8302 isField) == -1) { 8303 xmlSchemaPErr(ctxt, 8304 (xmlNodePtr) attr, 8305 XML_SCHEMAP_INTERNAL, 8306 "Internal error: xmlSchemaParseIDCSelectorAndField, " 8307 "validating the XPath expression of a IDC selector.\n", 8308 NULL, NULL); 8309 } 8310 8311 } 8312 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8313 /* 8314 * And now for the children... 8315 */ 8316 child = node->children; 8317 if (IS_SCHEMA(child, "annotation")) { 8318 /* 8319 * Add the annotation to the parent IDC. 8320 */ 8321 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc, 8322 xmlSchemaParseAnnotation(ctxt, child, 1)); 8323 child = child->next; 8324 } 8325 if (child != NULL) { 8326 xmlSchemaPContentErr(ctxt, 8327 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8328 NULL, node, child, 8329 NULL, "(annotation?)"); 8330 } 8331 8332 return (item); 8333 } 8334 8335 /** 8336 * xmlSchemaParseIDC: 8337 * @ctxt: a schema validation context 8338 * @schema: the schema being built 8339 * @node: a subtree containing XML Schema informations 8340 * 8341 * Parses a XML Schema identity-contraint definition. 8342 * 8343 * Returns the parsed identity-constraint definition. 8344 */ 8345 static xmlSchemaIDCPtr 8346 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt, 8347 xmlSchemaPtr schema, 8348 xmlNodePtr node, 8349 xmlSchemaTypeType idcCategory, 8350 const xmlChar *targetNamespace) 8351 { 8352 xmlSchemaIDCPtr item = NULL; 8353 xmlNodePtr child = NULL; 8354 xmlAttrPtr attr; 8355 const xmlChar *name = NULL; 8356 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL; 8357 8358 /* 8359 * Check for illegal attributes. 8360 */ 8361 attr = node->properties; 8362 while (attr != NULL) { 8363 if (attr->ns == NULL) { 8364 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8365 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 8366 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) || 8367 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) { 8368 xmlSchemaPIllegalAttrErr(ctxt, 8369 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8370 } 8371 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8372 xmlSchemaPIllegalAttrErr(ctxt, 8373 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8374 } 8375 attr = attr->next; 8376 } 8377 /* 8378 * Attribute "name" (mandatory). 8379 */ 8380 attr = xmlSchemaGetPropNode(node, "name"); 8381 if (attr == NULL) { 8382 xmlSchemaPMissingAttrErr(ctxt, 8383 XML_SCHEMAP_S4S_ATTR_MISSING, 8384 NULL, node, 8385 "name", NULL); 8386 return (NULL); 8387 } else if (xmlSchemaPValAttrNode(ctxt, 8388 NULL, attr, 8389 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 8390 return (NULL); 8391 } 8392 /* Create the component. */ 8393 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace, 8394 idcCategory, node); 8395 if (item == NULL) 8396 return(NULL); 8397 8398 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8399 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) { 8400 /* 8401 * Attribute "refer" (mandatory). 8402 */ 8403 attr = xmlSchemaGetPropNode(node, "refer"); 8404 if (attr == NULL) { 8405 xmlSchemaPMissingAttrErr(ctxt, 8406 XML_SCHEMAP_S4S_ATTR_MISSING, 8407 NULL, node, 8408 "refer", NULL); 8409 } else { 8410 /* 8411 * Create a reference item. 8412 */ 8413 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY, 8414 NULL, NULL); 8415 if (item->ref == NULL) 8416 return (NULL); 8417 xmlSchemaPValAttrNodeQName(ctxt, schema, 8418 NULL, attr, 8419 &(item->ref->targetNamespace), 8420 &(item->ref->name)); 8421 xmlSchemaCheckReference(ctxt, schema, node, attr, 8422 item->ref->targetNamespace); 8423 } 8424 } 8425 /* 8426 * And now for the children... 8427 */ 8428 child = node->children; 8429 if (IS_SCHEMA(child, "annotation")) { 8430 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8431 child = child->next; 8432 } 8433 if (child == NULL) { 8434 xmlSchemaPContentErr(ctxt, 8435 XML_SCHEMAP_S4S_ELEM_MISSING, 8436 NULL, node, child, 8437 "A child element is missing", 8438 "(annotation?, (selector, field+))"); 8439 } 8440 /* 8441 * Child element <selector>. 8442 */ 8443 if (IS_SCHEMA(child, "selector")) { 8444 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt, 8445 item, child, 0); 8446 child = child->next; 8447 /* 8448 * Child elements <field>. 8449 */ 8450 if (IS_SCHEMA(child, "field")) { 8451 do { 8452 field = xmlSchemaParseIDCSelectorAndField(ctxt, 8453 item, child, 1); 8454 if (field != NULL) { 8455 field->index = item->nbFields; 8456 item->nbFields++; 8457 if (lastField != NULL) 8458 lastField->next = field; 8459 else 8460 item->fields = field; 8461 lastField = field; 8462 } 8463 child = child->next; 8464 } while (IS_SCHEMA(child, "field")); 8465 } else { 8466 xmlSchemaPContentErr(ctxt, 8467 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8468 NULL, node, child, 8469 NULL, "(annotation?, (selector, field+))"); 8470 } 8471 } 8472 if (child != NULL) { 8473 xmlSchemaPContentErr(ctxt, 8474 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8475 NULL, node, child, 8476 NULL, "(annotation?, (selector, field+))"); 8477 } 8478 8479 return (item); 8480 } 8481 8482 /** 8483 * xmlSchemaParseElement: 8484 * @ctxt: a schema validation context 8485 * @schema: the schema being built 8486 * @node: a subtree containing XML Schema informations 8487 * @topLevel: indicates if this is global declaration 8488 * 8489 * Parses a XML schema element declaration. 8490 * *WARNING* this interface is highly subject to change 8491 * 8492 * Returns the element declaration or a particle; NULL in case 8493 * of an error or if the particle has minOccurs==maxOccurs==0. 8494 */ 8495 static xmlSchemaBasicItemPtr 8496 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8497 xmlNodePtr node, int *isElemRef, int topLevel) 8498 { 8499 xmlSchemaElementPtr decl = NULL; 8500 xmlSchemaParticlePtr particle = NULL; 8501 xmlSchemaAnnotPtr annot = NULL; 8502 xmlNodePtr child = NULL; 8503 xmlAttrPtr attr, nameAttr; 8504 int min, max, isRef = 0; 8505 xmlChar *des = NULL; 8506 8507 /* 3.3.3 Constraints on XML Representations of Element Declarations */ 8508 /* TODO: Complete implementation of 3.3.6 */ 8509 8510 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8511 return (NULL); 8512 8513 if (isElemRef != NULL) 8514 *isElemRef = 0; 8515 /* 8516 * If we get a "ref" attribute on a local <element> we will assume it's 8517 * a reference - even if there's a "name" attribute; this seems to be more 8518 * robust. 8519 */ 8520 nameAttr = xmlSchemaGetPropNode(node, "name"); 8521 attr = xmlSchemaGetPropNode(node, "ref"); 8522 if ((topLevel) || (attr == NULL)) { 8523 if (nameAttr == NULL) { 8524 xmlSchemaPMissingAttrErr(ctxt, 8525 XML_SCHEMAP_S4S_ATTR_MISSING, 8526 NULL, node, "name", NULL); 8527 return (NULL); 8528 } 8529 } else 8530 isRef = 1; 8531 8532 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8533 child = node->children; 8534 if (IS_SCHEMA(child, "annotation")) { 8535 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 8536 child = child->next; 8537 } 8538 /* 8539 * Skip particle part if a global declaration. 8540 */ 8541 if (topLevel) 8542 goto declaration_part; 8543 /* 8544 * The particle part ================================================== 8545 */ 8546 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 8547 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)"); 8548 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 8549 particle = xmlSchemaAddParticle(ctxt, node, min, max); 8550 if (particle == NULL) 8551 goto return_null; 8552 8553 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */ 8554 8555 if (isRef) { 8556 const xmlChar *refNs = NULL, *ref = NULL; 8557 xmlSchemaQNameRefPtr refer = NULL; 8558 /* 8559 * The reference part ============================================= 8560 */ 8561 if (isElemRef != NULL) 8562 *isElemRef = 1; 8563 8564 xmlSchemaPValAttrNodeQName(ctxt, schema, 8565 NULL, attr, &refNs, &ref); 8566 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 8567 /* 8568 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both" 8569 */ 8570 if (nameAttr != NULL) { 8571 xmlSchemaPMutualExclAttrErr(ctxt, 8572 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name"); 8573 } 8574 /* 8575 * Check for illegal attributes. 8576 */ 8577 attr = node->properties; 8578 while (attr != NULL) { 8579 if (attr->ns == NULL) { 8580 if (xmlStrEqual(attr->name, BAD_CAST "ref") || 8581 xmlStrEqual(attr->name, BAD_CAST "name") || 8582 xmlStrEqual(attr->name, BAD_CAST "id") || 8583 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") || 8584 xmlStrEqual(attr->name, BAD_CAST "minOccurs")) 8585 { 8586 attr = attr->next; 8587 continue; 8588 } else { 8589 /* SPEC (3.3.3 : 2.2) */ 8590 xmlSchemaPCustomAttrErr(ctxt, 8591 XML_SCHEMAP_SRC_ELEMENT_2_2, 8592 NULL, NULL, attr, 8593 "Only the attributes 'minOccurs', 'maxOccurs' and " 8594 "'id' are allowed in addition to 'ref'"); 8595 break; 8596 } 8597 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8598 xmlSchemaPIllegalAttrErr(ctxt, 8599 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8600 } 8601 attr = attr->next; 8602 } 8603 /* 8604 * No children except <annotation> expected. 8605 */ 8606 if (child != NULL) { 8607 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8608 NULL, node, child, NULL, "(annotation?)"); 8609 } 8610 if ((min == 0) && (max == 0)) 8611 goto return_null; 8612 /* 8613 * Create the reference item and attach it to the particle. 8614 */ 8615 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT, 8616 ref, refNs); 8617 if (refer == NULL) 8618 goto return_null; 8619 particle->children = (xmlSchemaTreeItemPtr) refer; 8620 particle->annot = annot; 8621 /* 8622 * Add the particle to pending components, since the reference 8623 * need to be resolved. 8624 */ 8625 WXS_ADD_PENDING(ctxt, particle); 8626 return ((xmlSchemaBasicItemPtr) particle); 8627 } 8628 /* 8629 * The declaration part =============================================== 8630 */ 8631 declaration_part: 8632 { 8633 const xmlChar *ns = NULL, *fixed, *name, *attrValue; 8634 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL; 8635 8636 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr, 8637 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) 8638 goto return_null; 8639 /* 8640 * Evaluate the target namespace. 8641 */ 8642 if (topLevel) { 8643 ns = ctxt->targetNamespace; 8644 } else { 8645 attr = xmlSchemaGetPropNode(node, "form"); 8646 if (attr != NULL) { 8647 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8648 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) { 8649 ns = ctxt->targetNamespace; 8650 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) { 8651 xmlSchemaPSimpleTypeErr(ctxt, 8652 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8653 NULL, (xmlNodePtr) attr, 8654 NULL, "(qualified | unqualified)", 8655 attrValue, NULL, NULL, NULL); 8656 } 8657 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 8658 ns = ctxt->targetNamespace; 8659 } 8660 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel); 8661 if (decl == NULL) { 8662 goto return_null; 8663 } 8664 /* 8665 * Check for illegal attributes. 8666 */ 8667 attr = node->properties; 8668 while (attr != NULL) { 8669 if (attr->ns == NULL) { 8670 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 8671 (!xmlStrEqual(attr->name, BAD_CAST "type")) && 8672 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 8673 (!xmlStrEqual(attr->name, BAD_CAST "default")) && 8674 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) && 8675 (!xmlStrEqual(attr->name, BAD_CAST "block")) && 8676 (!xmlStrEqual(attr->name, BAD_CAST "nillable"))) 8677 { 8678 if (topLevel == 0) { 8679 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 8680 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 8681 (!xmlStrEqual(attr->name, BAD_CAST "form"))) 8682 { 8683 xmlSchemaPIllegalAttrErr(ctxt, 8684 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8685 } 8686 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) && 8687 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) && 8688 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) { 8689 8690 xmlSchemaPIllegalAttrErr(ctxt, 8691 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8692 } 8693 } 8694 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8695 8696 xmlSchemaPIllegalAttrErr(ctxt, 8697 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8698 } 8699 attr = attr->next; 8700 } 8701 /* 8702 * Extract/validate attributes. 8703 */ 8704 if (topLevel) { 8705 /* 8706 * Process top attributes of global element declarations here. 8707 */ 8708 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL; 8709 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL; 8710 xmlSchemaPValAttrQName(ctxt, schema, 8711 NULL, node, "substitutionGroup", 8712 &(decl->substGroupNs), &(decl->substGroup)); 8713 if (xmlGetBooleanProp(ctxt, node, "abstract", 0)) 8714 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT; 8715 /* 8716 * Attribute "final". 8717 */ 8718 attr = xmlSchemaGetPropNode(node, "final"); 8719 if (attr == NULL) { 8720 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 8721 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION; 8722 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 8723 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION; 8724 } else { 8725 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8726 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8727 -1, 8728 XML_SCHEMAS_ELEM_FINAL_EXTENSION, 8729 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) { 8730 xmlSchemaPSimpleTypeErr(ctxt, 8731 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8732 NULL, (xmlNodePtr) attr, 8733 NULL, "(#all | List of (extension | restriction))", 8734 attrValue, NULL, NULL, NULL); 8735 } 8736 } 8737 } 8738 /* 8739 * Attribute "block". 8740 */ 8741 attr = xmlSchemaGetPropNode(node, "block"); 8742 if (attr == NULL) { 8743 /* 8744 * Apply default "block" values. 8745 */ 8746 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 8747 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION; 8748 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 8749 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION; 8750 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 8751 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION; 8752 } else { 8753 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8754 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags), 8755 -1, 8756 XML_SCHEMAS_ELEM_BLOCK_EXTENSION, 8757 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION, 8758 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) { 8759 xmlSchemaPSimpleTypeErr(ctxt, 8760 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 8761 NULL, (xmlNodePtr) attr, 8762 NULL, "(#all | List of (extension | " 8763 "restriction | substitution))", attrValue, 8764 NULL, NULL, NULL); 8765 } 8766 } 8767 if (xmlGetBooleanProp(ctxt, node, "nillable", 0)) 8768 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE; 8769 8770 attr = xmlSchemaGetPropNode(node, "type"); 8771 if (attr != NULL) { 8772 xmlSchemaPValAttrNodeQName(ctxt, schema, 8773 NULL, attr, 8774 &(decl->namedTypeNs), &(decl->namedType)); 8775 xmlSchemaCheckReference(ctxt, schema, node, 8776 attr, decl->namedTypeNs); 8777 } 8778 decl->value = xmlSchemaGetProp(ctxt, node, "default"); 8779 attr = xmlSchemaGetPropNode(node, "fixed"); 8780 if (attr != NULL) { 8781 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8782 if (decl->value != NULL) { 8783 /* 8784 * 3.3.3 : 1 8785 * default and fixed must not both be present. 8786 */ 8787 xmlSchemaPMutualExclAttrErr(ctxt, 8788 XML_SCHEMAP_SRC_ELEMENT_1, 8789 NULL, attr, "default", "fixed"); 8790 } else { 8791 decl->flags |= XML_SCHEMAS_ELEM_FIXED; 8792 decl->value = fixed; 8793 } 8794 } 8795 /* 8796 * And now for the children... 8797 */ 8798 if (IS_SCHEMA(child, "complexType")) { 8799 /* 8800 * 3.3.3 : 3 8801 * "type" and either <simpleType> or <complexType> are mutually 8802 * exclusive 8803 */ 8804 if (decl->namedType != NULL) { 8805 xmlSchemaPContentErr(ctxt, 8806 XML_SCHEMAP_SRC_ELEMENT_3, 8807 NULL, node, child, 8808 "The attribute 'type' and the <complexType> child are " 8809 "mutually exclusive", NULL); 8810 } else 8811 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0); 8812 child = child->next; 8813 } else if (IS_SCHEMA(child, "simpleType")) { 8814 /* 8815 * 3.3.3 : 3 8816 * "type" and either <simpleType> or <complexType> are 8817 * mutually exclusive 8818 */ 8819 if (decl->namedType != NULL) { 8820 xmlSchemaPContentErr(ctxt, 8821 XML_SCHEMAP_SRC_ELEMENT_3, 8822 NULL, node, child, 8823 "The attribute 'type' and the <simpleType> child are " 8824 "mutually exclusive", NULL); 8825 } else 8826 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 8827 child = child->next; 8828 } 8829 while ((IS_SCHEMA(child, "unique")) || 8830 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) { 8831 if (IS_SCHEMA(child, "unique")) { 8832 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8833 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace); 8834 } else if (IS_SCHEMA(child, "key")) { 8835 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8836 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace); 8837 } else if (IS_SCHEMA(child, "keyref")) { 8838 curIDC = xmlSchemaParseIDC(ctxt, schema, child, 8839 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace); 8840 } 8841 if (lastIDC != NULL) 8842 lastIDC->next = curIDC; 8843 else 8844 decl->idcs = (void *) curIDC; 8845 lastIDC = curIDC; 8846 child = child->next; 8847 } 8848 if (child != NULL) { 8849 xmlSchemaPContentErr(ctxt, 8850 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 8851 NULL, node, child, 8852 NULL, "(annotation?, ((simpleType | complexType)?, " 8853 "(unique | key | keyref)*))"); 8854 } 8855 decl->annot = annot; 8856 } 8857 /* 8858 * NOTE: Element Declaration Representation OK 4. will be checked at a 8859 * different layer. 8860 */ 8861 FREE_AND_NULL(des) 8862 if (topLevel) 8863 return ((xmlSchemaBasicItemPtr) decl); 8864 else { 8865 particle->children = (xmlSchemaTreeItemPtr) decl; 8866 return ((xmlSchemaBasicItemPtr) particle); 8867 } 8868 8869 return_null: 8870 FREE_AND_NULL(des); 8871 if (annot != NULL) { 8872 if (particle != NULL) 8873 particle->annot = NULL; 8874 if (decl != NULL) 8875 decl->annot = NULL; 8876 xmlSchemaFreeAnnot(annot); 8877 } 8878 return (NULL); 8879 } 8880 8881 /** 8882 * xmlSchemaParseUnion: 8883 * @ctxt: a schema validation context 8884 * @schema: the schema being built 8885 * @node: a subtree containing XML Schema informations 8886 * 8887 * parse a XML schema Union definition 8888 * *WARNING* this interface is highly subject to change 8889 * 8890 * Returns -1 in case of internal error, 0 in case of success and a positive 8891 * error code otherwise. 8892 */ 8893 static int 8894 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 8895 xmlNodePtr node) 8896 { 8897 xmlSchemaTypePtr type; 8898 xmlNodePtr child = NULL; 8899 xmlAttrPtr attr; 8900 const xmlChar *cur = NULL; 8901 8902 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 8903 return (-1); 8904 /* Not a component, don't create it. */ 8905 type = ctxt->ctxtType; 8906 /* 8907 * Mark the simple type as being of variety "union". 8908 */ 8909 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 8910 /* 8911 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 8912 * then the `simple ur-type definition`." 8913 */ 8914 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 8915 /* 8916 * Check for illegal attributes. 8917 */ 8918 attr = node->properties; 8919 while (attr != NULL) { 8920 if (attr->ns == NULL) { 8921 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 8922 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) { 8923 xmlSchemaPIllegalAttrErr(ctxt, 8924 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8925 } 8926 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 8927 xmlSchemaPIllegalAttrErr(ctxt, 8928 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 8929 } 8930 attr = attr->next; 8931 } 8932 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 8933 /* 8934 * Attribute "memberTypes". This is a list of QNames. 8935 * TODO: Check the value to contain anything. 8936 */ 8937 attr = xmlSchemaGetPropNode(node, "memberTypes"); 8938 if (attr != NULL) { 8939 const xmlChar *end; 8940 xmlChar *tmp; 8941 const xmlChar *localName, *nsName; 8942 xmlSchemaTypeLinkPtr link, lastLink = NULL; 8943 xmlSchemaQNameRefPtr ref; 8944 8945 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 8946 type->base = cur; 8947 do { 8948 while (IS_BLANK_CH(*cur)) 8949 cur++; 8950 end = cur; 8951 while ((*end != 0) && (!(IS_BLANK_CH(*end)))) 8952 end++; 8953 if (end == cur) 8954 break; 8955 tmp = xmlStrndup(cur, end - cur); 8956 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema, 8957 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) { 8958 /* 8959 * Create the member type link. 8960 */ 8961 link = (xmlSchemaTypeLinkPtr) 8962 xmlMalloc(sizeof(xmlSchemaTypeLink)); 8963 if (link == NULL) { 8964 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, " 8965 "allocating a type link", NULL); 8966 return (-1); 8967 } 8968 link->type = NULL; 8969 link->next = NULL; 8970 if (lastLink == NULL) 8971 type->memberTypes = link; 8972 else 8973 lastLink->next = link; 8974 lastLink = link; 8975 /* 8976 * Create a reference item. 8977 */ 8978 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE, 8979 localName, nsName); 8980 if (ref == NULL) { 8981 FREE_AND_NULL(tmp) 8982 return (-1); 8983 } 8984 /* 8985 * Assign the reference to the link, it will be resolved 8986 * later during fixup of the union simple type. 8987 */ 8988 link->type = (xmlSchemaTypePtr) ref; 8989 } 8990 FREE_AND_NULL(tmp) 8991 cur = end; 8992 } while (*cur != 0); 8993 8994 } 8995 /* 8996 * And now for the children... 8997 */ 8998 child = node->children; 8999 if (IS_SCHEMA(child, "annotation")) { 9000 /* 9001 * Add the annotation to the simple type ancestor. 9002 */ 9003 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9004 xmlSchemaParseAnnotation(ctxt, child, 1)); 9005 child = child->next; 9006 } 9007 if (IS_SCHEMA(child, "simpleType")) { 9008 xmlSchemaTypePtr subtype, last = NULL; 9009 9010 /* 9011 * Anchor the member types in the "subtypes" field of the 9012 * simple type. 9013 */ 9014 while (IS_SCHEMA(child, "simpleType")) { 9015 subtype = (xmlSchemaTypePtr) 9016 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9017 if (subtype != NULL) { 9018 if (last == NULL) { 9019 type->subtypes = subtype; 9020 last = subtype; 9021 } else { 9022 last->next = subtype; 9023 last = subtype; 9024 } 9025 last->next = NULL; 9026 } 9027 child = child->next; 9028 } 9029 } 9030 if (child != NULL) { 9031 xmlSchemaPContentErr(ctxt, 9032 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9033 NULL, node, child, NULL, "(annotation?, simpleType*)"); 9034 } 9035 if ((attr == NULL) && (type->subtypes == NULL)) { 9036 /* 9037 * src-union-memberTypes-or-simpleTypes 9038 * Either the memberTypes [attribute] of the <union> element must 9039 * be non-empty or there must be at least one simpleType [child]. 9040 */ 9041 xmlSchemaPCustomErr(ctxt, 9042 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, 9043 NULL, node, 9044 "Either the attribute 'memberTypes' or " 9045 "at least one <simpleType> child must be present", NULL); 9046 } 9047 return (0); 9048 } 9049 9050 /** 9051 * xmlSchemaParseList: 9052 * @ctxt: a schema validation context 9053 * @schema: the schema being built 9054 * @node: a subtree containing XML Schema informations 9055 * 9056 * parse a XML schema List definition 9057 * *WARNING* this interface is highly subject to change 9058 * 9059 * Returns -1 in case of error, 0 if the declaration is improper and 9060 * 1 in case of success. 9061 */ 9062 static xmlSchemaTypePtr 9063 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9064 xmlNodePtr node) 9065 { 9066 xmlSchemaTypePtr type; 9067 xmlNodePtr child = NULL; 9068 xmlAttrPtr attr; 9069 9070 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9071 return (NULL); 9072 /* Not a component, don't create it. */ 9073 type = ctxt->ctxtType; 9074 /* 9075 * Mark the type as being of variety "list". 9076 */ 9077 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 9078 /* 9079 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen, 9080 * then the `simple ur-type definition`." 9081 */ 9082 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE); 9083 /* 9084 * Check for illegal attributes. 9085 */ 9086 attr = node->properties; 9087 while (attr != NULL) { 9088 if (attr->ns == NULL) { 9089 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9090 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) { 9091 xmlSchemaPIllegalAttrErr(ctxt, 9092 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9093 } 9094 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9095 xmlSchemaPIllegalAttrErr(ctxt, 9096 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9097 } 9098 attr = attr->next; 9099 } 9100 9101 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9102 9103 /* 9104 * Attribute "itemType". NOTE that we will use the "ref" and "refNs" 9105 * fields for holding the reference to the itemType. 9106 * 9107 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove 9108 * the "ref" fields. 9109 */ 9110 xmlSchemaPValAttrQName(ctxt, schema, NULL, 9111 node, "itemType", &(type->baseNs), &(type->base)); 9112 /* 9113 * And now for the children... 9114 */ 9115 child = node->children; 9116 if (IS_SCHEMA(child, "annotation")) { 9117 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 9118 xmlSchemaParseAnnotation(ctxt, child, 1)); 9119 child = child->next; 9120 } 9121 if (IS_SCHEMA(child, "simpleType")) { 9122 /* 9123 * src-list-itemType-or-simpleType 9124 * Either the itemType [attribute] or the <simpleType> [child] of 9125 * the <list> element must be present, but not both. 9126 */ 9127 if (type->base != NULL) { 9128 xmlSchemaPCustomErr(ctxt, 9129 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9130 NULL, node, 9131 "The attribute 'itemType' and the <simpleType> child " 9132 "are mutually exclusive", NULL); 9133 } else { 9134 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0); 9135 } 9136 child = child->next; 9137 } else if (type->base == NULL) { 9138 xmlSchemaPCustomErr(ctxt, 9139 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9140 NULL, node, 9141 "Either the attribute 'itemType' or the <simpleType> child " 9142 "must be present", NULL); 9143 } 9144 if (child != NULL) { 9145 xmlSchemaPContentErr(ctxt, 9146 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9147 NULL, node, child, NULL, "(annotation?, simpleType?)"); 9148 } 9149 if ((type->base == NULL) && 9150 (type->subtypes == NULL) && 9151 (xmlSchemaGetPropNode(node, "itemType") == NULL)) { 9152 xmlSchemaPCustomErr(ctxt, 9153 XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 9154 NULL, node, 9155 "Either the attribute 'itemType' or the <simpleType> child " 9156 "must be present", NULL); 9157 } 9158 return (NULL); 9159 } 9160 9161 /** 9162 * xmlSchemaParseSimpleType: 9163 * @ctxt: a schema validation context 9164 * @schema: the schema being built 9165 * @node: a subtree containing XML Schema informations 9166 * 9167 * parse a XML schema Simple Type definition 9168 * *WARNING* this interface is highly subject to change 9169 * 9170 * Returns -1 in case of error, 0 if the declaration is improper and 9171 * 1 in case of success. 9172 */ 9173 static xmlSchemaTypePtr 9174 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 9175 xmlNodePtr node, int topLevel) 9176 { 9177 xmlSchemaTypePtr type, oldCtxtType; 9178 xmlNodePtr child = NULL; 9179 const xmlChar *attrValue = NULL; 9180 xmlAttrPtr attr; 9181 int hasRestriction = 0; 9182 9183 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9184 return (NULL); 9185 9186 if (topLevel) { 9187 attr = xmlSchemaGetPropNode(node, "name"); 9188 if (attr == NULL) { 9189 xmlSchemaPMissingAttrErr(ctxt, 9190 XML_SCHEMAP_S4S_ATTR_MISSING, 9191 NULL, node, 9192 "name", NULL); 9193 return (NULL); 9194 } else { 9195 if (xmlSchemaPValAttrNode(ctxt, 9196 NULL, attr, 9197 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) 9198 return (NULL); 9199 /* 9200 * Skip built-in types. 9201 */ 9202 if (ctxt->isS4S) { 9203 xmlSchemaTypePtr biType; 9204 9205 if (ctxt->isRedefine) { 9206 /* 9207 * REDEFINE: Disallow redefinition of built-in-types. 9208 * TODO: It seems that the spec does not say anything 9209 * about this case. 9210 */ 9211 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9212 NULL, node, 9213 "Redefinition of built-in simple types is not " 9214 "supported", NULL); 9215 return(NULL); 9216 } 9217 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs); 9218 if (biType != NULL) 9219 return (biType); 9220 } 9221 } 9222 } 9223 /* 9224 * TargetNamespace: 9225 * SPEC "The `actual value` of the targetNamespace [attribute] 9226 * of the <schema> ancestor element information item if present, 9227 * otherwise `absent`. 9228 */ 9229 if (topLevel == 0) { 9230 #ifdef ENABLE_NAMED_LOCALS 9231 char buf[40]; 9232 #endif 9233 /* 9234 * Parse as local simple type definition. 9235 */ 9236 #ifdef ENABLE_NAMED_LOCALS 9237 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1); 9238 type = xmlSchemaAddType(ctxt, schema, 9239 XML_SCHEMA_TYPE_SIMPLE, 9240 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 9241 ctxt->targetNamespace, node, 0); 9242 #else 9243 type = xmlSchemaAddType(ctxt, schema, 9244 XML_SCHEMA_TYPE_SIMPLE, 9245 NULL, ctxt->targetNamespace, node, 0); 9246 #endif 9247 if (type == NULL) 9248 return (NULL); 9249 type->type = XML_SCHEMA_TYPE_SIMPLE; 9250 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9251 /* 9252 * Check for illegal attributes. 9253 */ 9254 attr = node->properties; 9255 while (attr != NULL) { 9256 if (attr->ns == NULL) { 9257 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 9258 xmlSchemaPIllegalAttrErr(ctxt, 9259 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9260 } 9261 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9262 xmlSchemaPIllegalAttrErr(ctxt, 9263 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9264 } 9265 attr = attr->next; 9266 } 9267 } else { 9268 /* 9269 * Parse as global simple type definition. 9270 * 9271 * Note that attrValue is the value of the attribute "name" here. 9272 */ 9273 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE, 9274 attrValue, ctxt->targetNamespace, node, 1); 9275 if (type == NULL) 9276 return (NULL); 9277 type->type = XML_SCHEMA_TYPE_SIMPLE; 9278 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 9279 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 9280 /* 9281 * Check for illegal attributes. 9282 */ 9283 attr = node->properties; 9284 while (attr != NULL) { 9285 if (attr->ns == NULL) { 9286 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 9287 (!xmlStrEqual(attr->name, BAD_CAST "name")) && 9288 (!xmlStrEqual(attr->name, BAD_CAST "final"))) { 9289 xmlSchemaPIllegalAttrErr(ctxt, 9290 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9291 } 9292 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9293 xmlSchemaPIllegalAttrErr(ctxt, 9294 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9295 } 9296 attr = attr->next; 9297 } 9298 /* 9299 * Attribute "final". 9300 */ 9301 attr = xmlSchemaGetPropNode(node, "final"); 9302 if (attr == NULL) { 9303 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9304 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 9305 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9306 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST; 9307 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9308 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION; 9309 } else { 9310 attrValue = xmlSchemaGetProp(ctxt, node, "final"); 9311 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 9312 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1, 9313 XML_SCHEMAS_TYPE_FINAL_LIST, 9314 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) { 9315 9316 xmlSchemaPSimpleTypeErr(ctxt, 9317 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9318 WXS_BASIC_CAST type, (xmlNodePtr) attr, 9319 NULL, "(#all | List of (list | union | restriction)", 9320 attrValue, NULL, NULL, NULL); 9321 } 9322 } 9323 } 9324 type->targetNamespace = ctxt->targetNamespace; 9325 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9326 /* 9327 * And now for the children... 9328 */ 9329 oldCtxtType = ctxt->ctxtType; 9330 9331 ctxt->ctxtType = type; 9332 9333 child = node->children; 9334 if (IS_SCHEMA(child, "annotation")) { 9335 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9336 child = child->next; 9337 } 9338 if (child == NULL) { 9339 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING, 9340 NULL, node, child, NULL, 9341 "(annotation?, (restriction | list | union))"); 9342 } else if (IS_SCHEMA(child, "restriction")) { 9343 xmlSchemaParseRestriction(ctxt, schema, child, 9344 XML_SCHEMA_TYPE_SIMPLE); 9345 hasRestriction = 1; 9346 child = child->next; 9347 } else if (IS_SCHEMA(child, "list")) { 9348 xmlSchemaParseList(ctxt, schema, child); 9349 child = child->next; 9350 } else if (IS_SCHEMA(child, "union")) { 9351 xmlSchemaParseUnion(ctxt, schema, child); 9352 child = child->next; 9353 } 9354 if (child != NULL) { 9355 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9356 NULL, node, child, NULL, 9357 "(annotation?, (restriction | list | union))"); 9358 } 9359 /* 9360 * REDEFINE: SPEC src-redefine (5) 9361 * "Within the [children], each <simpleType> must have a 9362 * <restriction> among its [children] ... the `actual value` of whose 9363 * base [attribute] must be the same as the `actual value` of its own 9364 * name attribute plus target namespace;" 9365 */ 9366 if (topLevel && ctxt->isRedefine && (! hasRestriction)) { 9367 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 9368 NULL, node, "This is a redefinition, thus the " 9369 "<simpleType> must have a <restriction> child", NULL); 9370 } 9371 9372 ctxt->ctxtType = oldCtxtType; 9373 return (type); 9374 } 9375 9376 /** 9377 * xmlSchemaParseModelGroupDefRef: 9378 * @ctxt: the parser context 9379 * @schema: the schema being built 9380 * @node: the node 9381 * 9382 * Parses a reference to a model group definition. 9383 * 9384 * We will return a particle component with a qname-component or 9385 * NULL in case of an error. 9386 */ 9387 static xmlSchemaTreeItemPtr 9388 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt, 9389 xmlSchemaPtr schema, 9390 xmlNodePtr node) 9391 { 9392 xmlSchemaParticlePtr item; 9393 xmlNodePtr child = NULL; 9394 xmlAttrPtr attr; 9395 const xmlChar *ref = NULL, *refNs = NULL; 9396 int min, max; 9397 9398 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9399 return (NULL); 9400 9401 attr = xmlSchemaGetPropNode(node, "ref"); 9402 if (attr == NULL) { 9403 xmlSchemaPMissingAttrErr(ctxt, 9404 XML_SCHEMAP_S4S_ATTR_MISSING, 9405 NULL, node, "ref", NULL); 9406 return (NULL); 9407 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL, 9408 attr, &refNs, &ref) != 0) { 9409 return (NULL); 9410 } 9411 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs); 9412 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 9413 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 9414 "(xs:nonNegativeInteger | unbounded)"); 9415 /* 9416 * Check for illegal attributes. 9417 */ 9418 attr = node->properties; 9419 while (attr != NULL) { 9420 if (attr->ns == NULL) { 9421 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) && 9422 (!xmlStrEqual(attr->name, BAD_CAST "id")) && 9423 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) && 9424 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) { 9425 xmlSchemaPIllegalAttrErr(ctxt, 9426 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9427 } 9428 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9429 xmlSchemaPIllegalAttrErr(ctxt, 9430 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9431 } 9432 attr = attr->next; 9433 } 9434 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9435 item = xmlSchemaAddParticle(ctxt, node, min, max); 9436 if (item == NULL) 9437 return (NULL); 9438 /* 9439 * Create a qname-reference and set as the term; it will be substituted 9440 * for the model group after the reference has been resolved. 9441 */ 9442 item->children = (xmlSchemaTreeItemPtr) 9443 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs); 9444 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max); 9445 /* 9446 * And now for the children... 9447 */ 9448 child = node->children; 9449 /* TODO: Is annotation even allowed for a model group reference? */ 9450 if (IS_SCHEMA(child, "annotation")) { 9451 /* 9452 * TODO: What to do exactly with the annotation? 9453 */ 9454 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9455 child = child->next; 9456 } 9457 if (child != NULL) { 9458 xmlSchemaPContentErr(ctxt, 9459 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9460 NULL, node, child, NULL, 9461 "(annotation?)"); 9462 } 9463 /* 9464 * Corresponds to no component at all if minOccurs==maxOccurs==0. 9465 */ 9466 if ((min == 0) && (max == 0)) 9467 return (NULL); 9468 9469 return ((xmlSchemaTreeItemPtr) item); 9470 } 9471 9472 /** 9473 * xmlSchemaParseModelGroupDefinition: 9474 * @ctxt: a schema validation context 9475 * @schema: the schema being built 9476 * @node: a subtree containing XML Schema informations 9477 * 9478 * Parses a XML schema model group definition. 9479 * 9480 * Note that the contraint src-redefine (6.2) can't be applied until 9481 * references have been resolved. So we will do this at the 9482 * component fixup level. 9483 * 9484 * *WARNING* this interface is highly subject to change 9485 * 9486 * Returns -1 in case of error, 0 if the declaration is improper and 9487 * 1 in case of success. 9488 */ 9489 static xmlSchemaModelGroupDefPtr 9490 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt, 9491 xmlSchemaPtr schema, 9492 xmlNodePtr node) 9493 { 9494 xmlSchemaModelGroupDefPtr item; 9495 xmlNodePtr child = NULL; 9496 xmlAttrPtr attr; 9497 const xmlChar *name; 9498 9499 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 9500 return (NULL); 9501 9502 attr = xmlSchemaGetPropNode(node, "name"); 9503 if (attr == NULL) { 9504 xmlSchemaPMissingAttrErr(ctxt, 9505 XML_SCHEMAP_S4S_ATTR_MISSING, 9506 NULL, node, 9507 "name", NULL); 9508 return (NULL); 9509 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 9510 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 9511 return (NULL); 9512 } 9513 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name, 9514 ctxt->targetNamespace, node); 9515 if (item == NULL) 9516 return (NULL); 9517 /* 9518 * Check for illegal attributes. 9519 */ 9520 attr = node->properties; 9521 while (attr != NULL) { 9522 if (attr->ns == NULL) { 9523 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) && 9524 (!xmlStrEqual(attr->name, BAD_CAST "id"))) { 9525 xmlSchemaPIllegalAttrErr(ctxt, 9526 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9527 } 9528 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 9529 xmlSchemaPIllegalAttrErr(ctxt, 9530 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 9531 } 9532 attr = attr->next; 9533 } 9534 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9535 /* 9536 * And now for the children... 9537 */ 9538 child = node->children; 9539 if (IS_SCHEMA(child, "annotation")) { 9540 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9541 child = child->next; 9542 } 9543 if (IS_SCHEMA(child, "all")) { 9544 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9545 XML_SCHEMA_TYPE_ALL, 0); 9546 child = child->next; 9547 } else if (IS_SCHEMA(child, "choice")) { 9548 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9549 XML_SCHEMA_TYPE_CHOICE, 0); 9550 child = child->next; 9551 } else if (IS_SCHEMA(child, "sequence")) { 9552 item->children = xmlSchemaParseModelGroup(ctxt, schema, child, 9553 XML_SCHEMA_TYPE_SEQUENCE, 0); 9554 child = child->next; 9555 } 9556 9557 9558 9559 if (child != NULL) { 9560 xmlSchemaPContentErr(ctxt, 9561 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9562 NULL, node, child, NULL, 9563 "(annotation?, (all | choice | sequence)?)"); 9564 } 9565 return (item); 9566 } 9567 9568 /** 9569 * xmlSchemaCleanupDoc: 9570 * @ctxt: a schema validation context 9571 * @node: the root of the document. 9572 * 9573 * removes unwanted nodes in a schemas document tree 9574 */ 9575 static void 9576 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root) 9577 { 9578 xmlNodePtr delete, cur; 9579 9580 if ((ctxt == NULL) || (root == NULL)) return; 9581 9582 /* 9583 * Remove all the blank text nodes 9584 */ 9585 delete = NULL; 9586 cur = root; 9587 while (cur != NULL) { 9588 if (delete != NULL) { 9589 xmlUnlinkNode(delete); 9590 xmlFreeNode(delete); 9591 delete = NULL; 9592 } 9593 if (cur->type == XML_TEXT_NODE) { 9594 if (IS_BLANK_NODE(cur)) { 9595 if (xmlNodeGetSpacePreserve(cur) != 1) { 9596 delete = cur; 9597 } 9598 } 9599 } else if ((cur->type != XML_ELEMENT_NODE) && 9600 (cur->type != XML_CDATA_SECTION_NODE)) { 9601 delete = cur; 9602 goto skip_children; 9603 } 9604 9605 /* 9606 * Skip to next node 9607 */ 9608 if (cur->children != NULL) { 9609 if ((cur->children->type != XML_ENTITY_DECL) && 9610 (cur->children->type != XML_ENTITY_REF_NODE) && 9611 (cur->children->type != XML_ENTITY_NODE)) { 9612 cur = cur->children; 9613 continue; 9614 } 9615 } 9616 skip_children: 9617 if (cur->next != NULL) { 9618 cur = cur->next; 9619 continue; 9620 } 9621 9622 do { 9623 cur = cur->parent; 9624 if (cur == NULL) 9625 break; 9626 if (cur == root) { 9627 cur = NULL; 9628 break; 9629 } 9630 if (cur->next != NULL) { 9631 cur = cur->next; 9632 break; 9633 } 9634 } while (cur != NULL); 9635 } 9636 if (delete != NULL) { 9637 xmlUnlinkNode(delete); 9638 xmlFreeNode(delete); 9639 delete = NULL; 9640 } 9641 } 9642 9643 9644 static void 9645 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema) 9646 { 9647 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM) 9648 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM; 9649 9650 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR) 9651 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR; 9652 9653 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 9654 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION; 9655 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 9656 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION; 9657 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST) 9658 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST; 9659 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION) 9660 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION; 9661 9662 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 9663 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION; 9664 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 9665 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION; 9666 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION) 9667 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION; 9668 } 9669 9670 static int 9671 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt, 9672 xmlSchemaPtr schema, 9673 xmlNodePtr node) 9674 { 9675 xmlAttrPtr attr; 9676 const xmlChar *val; 9677 int res = 0, oldErrs = ctxt->nberrors; 9678 9679 /* 9680 * Those flags should be moved to the parser context flags, 9681 * since they are not visible at the component level. I.e. 9682 * they are used if processing schema *documents* only. 9683 */ 9684 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 9685 HFAILURE; 9686 9687 /* 9688 * Since the version is of type xs:token, we won't bother to 9689 * check it. 9690 */ 9691 /* REMOVED: 9692 attr = xmlSchemaGetPropNode(node, "version"); 9693 if (attr != NULL) { 9694 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr, 9695 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val); 9696 HFAILURE; 9697 } 9698 */ 9699 attr = xmlSchemaGetPropNode(node, "targetNamespace"); 9700 if (attr != NULL) { 9701 res = xmlSchemaPValAttrNode(ctxt, NULL, attr, 9702 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL); 9703 HFAILURE; 9704 if (res != 0) { 9705 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE; 9706 goto exit; 9707 } 9708 } 9709 attr = xmlSchemaGetPropNode(node, "elementFormDefault"); 9710 if (attr != NULL) { 9711 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9712 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9713 XML_SCHEMAS_QUALIF_ELEM); 9714 HFAILURE; 9715 if (res != 0) { 9716 xmlSchemaPSimpleTypeErr(ctxt, 9717 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, 9718 NULL, (xmlNodePtr) attr, NULL, 9719 "(qualified | unqualified)", val, NULL, NULL, NULL); 9720 } 9721 } 9722 attr = xmlSchemaGetPropNode(node, "attributeFormDefault"); 9723 if (attr != NULL) { 9724 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9725 res = xmlSchemaPValAttrFormDefault(val, &schema->flags, 9726 XML_SCHEMAS_QUALIF_ATTR); 9727 HFAILURE; 9728 if (res != 0) { 9729 xmlSchemaPSimpleTypeErr(ctxt, 9730 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, 9731 NULL, (xmlNodePtr) attr, NULL, 9732 "(qualified | unqualified)", val, NULL, NULL, NULL); 9733 } 9734 } 9735 attr = xmlSchemaGetPropNode(node, "finalDefault"); 9736 if (attr != NULL) { 9737 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9738 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9739 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION, 9740 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION, 9741 -1, 9742 XML_SCHEMAS_FINAL_DEFAULT_LIST, 9743 XML_SCHEMAS_FINAL_DEFAULT_UNION); 9744 HFAILURE; 9745 if (res != 0) { 9746 xmlSchemaPSimpleTypeErr(ctxt, 9747 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9748 NULL, (xmlNodePtr) attr, NULL, 9749 "(#all | List of (extension | restriction | list | union))", 9750 val, NULL, NULL, NULL); 9751 } 9752 } 9753 attr = xmlSchemaGetPropNode(node, "blockDefault"); 9754 if (attr != NULL) { 9755 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr); 9756 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1, 9757 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION, 9758 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION, 9759 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1); 9760 HFAILURE; 9761 if (res != 0) { 9762 xmlSchemaPSimpleTypeErr(ctxt, 9763 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 9764 NULL, (xmlNodePtr) attr, NULL, 9765 "(#all | List of (extension | restriction | substitution))", 9766 val, NULL, NULL, NULL); 9767 } 9768 } 9769 9770 exit: 9771 if (oldErrs != ctxt->nberrors) 9772 res = ctxt->err; 9773 return(res); 9774 exit_failure: 9775 return(-1); 9776 } 9777 9778 /** 9779 * xmlSchemaParseSchemaTopLevel: 9780 * @ctxt: a schema validation context 9781 * @schema: the schemas 9782 * @nodes: the list of top level nodes 9783 * 9784 * Returns the internal XML Schema structure built from the resource or 9785 * NULL in case of error 9786 */ 9787 static int 9788 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt, 9789 xmlSchemaPtr schema, xmlNodePtr nodes) 9790 { 9791 xmlNodePtr child; 9792 xmlSchemaAnnotPtr annot; 9793 int res = 0, oldErrs, tmpOldErrs; 9794 9795 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL)) 9796 return(-1); 9797 9798 oldErrs = ctxt->nberrors; 9799 child = nodes; 9800 while ((IS_SCHEMA(child, "include")) || 9801 (IS_SCHEMA(child, "import")) || 9802 (IS_SCHEMA(child, "redefine")) || 9803 (IS_SCHEMA(child, "annotation"))) { 9804 if (IS_SCHEMA(child, "annotation")) { 9805 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9806 if (schema->annot == NULL) 9807 schema->annot = annot; 9808 else 9809 xmlSchemaFreeAnnot(annot); 9810 } else if (IS_SCHEMA(child, "import")) { 9811 tmpOldErrs = ctxt->nberrors; 9812 res = xmlSchemaParseImport(ctxt, schema, child); 9813 HFAILURE; 9814 HSTOP(ctxt); 9815 if (tmpOldErrs != ctxt->nberrors) 9816 goto exit; 9817 } else if (IS_SCHEMA(child, "include")) { 9818 tmpOldErrs = ctxt->nberrors; 9819 res = xmlSchemaParseInclude(ctxt, schema, child); 9820 HFAILURE; 9821 HSTOP(ctxt); 9822 if (tmpOldErrs != ctxt->nberrors) 9823 goto exit; 9824 } else if (IS_SCHEMA(child, "redefine")) { 9825 tmpOldErrs = ctxt->nberrors; 9826 res = xmlSchemaParseRedefine(ctxt, schema, child); 9827 HFAILURE; 9828 HSTOP(ctxt); 9829 if (tmpOldErrs != ctxt->nberrors) 9830 goto exit; 9831 } 9832 child = child->next; 9833 } 9834 /* 9835 * URGENT TODO: Change the functions to return int results. 9836 * We need especially to catch internal errors. 9837 */ 9838 while (child != NULL) { 9839 if (IS_SCHEMA(child, "complexType")) { 9840 xmlSchemaParseComplexType(ctxt, schema, child, 1); 9841 child = child->next; 9842 } else if (IS_SCHEMA(child, "simpleType")) { 9843 xmlSchemaParseSimpleType(ctxt, schema, child, 1); 9844 child = child->next; 9845 } else if (IS_SCHEMA(child, "element")) { 9846 xmlSchemaParseElement(ctxt, schema, child, NULL, 1); 9847 child = child->next; 9848 } else if (IS_SCHEMA(child, "attribute")) { 9849 xmlSchemaParseGlobalAttribute(ctxt, schema, child); 9850 child = child->next; 9851 } else if (IS_SCHEMA(child, "attributeGroup")) { 9852 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child); 9853 child = child->next; 9854 } else if (IS_SCHEMA(child, "group")) { 9855 xmlSchemaParseModelGroupDefinition(ctxt, schema, child); 9856 child = child->next; 9857 } else if (IS_SCHEMA(child, "notation")) { 9858 xmlSchemaParseNotation(ctxt, schema, child); 9859 child = child->next; 9860 } else { 9861 xmlSchemaPContentErr(ctxt, 9862 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 9863 NULL, child->parent, child, 9864 NULL, "((include | import | redefine | annotation)*, " 9865 "(((simpleType | complexType | group | attributeGroup) " 9866 "| element | attribute | notation), annotation*)*)"); 9867 child = child->next; 9868 } 9869 while (IS_SCHEMA(child, "annotation")) { 9870 /* 9871 * TODO: We should add all annotations. 9872 */ 9873 annot = xmlSchemaParseAnnotation(ctxt, child, 1); 9874 if (schema->annot == NULL) 9875 schema->annot = annot; 9876 else 9877 xmlSchemaFreeAnnot(annot); 9878 child = child->next; 9879 } 9880 } 9881 exit: 9882 ctxt->ctxtType = NULL; 9883 if (oldErrs != ctxt->nberrors) 9884 res = ctxt->err; 9885 return(res); 9886 exit_failure: 9887 return(-1); 9888 } 9889 9890 static xmlSchemaSchemaRelationPtr 9891 xmlSchemaSchemaRelationCreate(void) 9892 { 9893 xmlSchemaSchemaRelationPtr ret; 9894 9895 ret = (xmlSchemaSchemaRelationPtr) 9896 xmlMalloc(sizeof(xmlSchemaSchemaRelation)); 9897 if (ret == NULL) { 9898 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL); 9899 return(NULL); 9900 } 9901 memset(ret, 0, sizeof(xmlSchemaSchemaRelation)); 9902 return(ret); 9903 } 9904 9905 #if 0 9906 static void 9907 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel) 9908 { 9909 xmlFree(rel); 9910 } 9911 #endif 9912 9913 static void 9914 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef) 9915 { 9916 xmlSchemaRedefPtr prev; 9917 9918 while (redef != NULL) { 9919 prev = redef; 9920 redef = redef->next; 9921 xmlFree(prev); 9922 } 9923 } 9924 9925 static void 9926 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) 9927 { 9928 /* 9929 * After the construction context has been freed, there will be 9930 * no schema graph available any more. Only the schema buckets 9931 * will stay alive, which are put into the "schemasImports" and 9932 * "includes" slots of the xmlSchema. 9933 */ 9934 if (con->buckets != NULL) 9935 xmlSchemaItemListFree(con->buckets); 9936 if (con->pending != NULL) 9937 xmlSchemaItemListFree(con->pending); 9938 if (con->substGroups != NULL) 9939 xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); 9940 if (con->redefs != NULL) 9941 xmlSchemaRedefListFree(con->redefs); 9942 if (con->dict != NULL) 9943 xmlDictFree(con->dict); 9944 xmlFree(con); 9945 } 9946 9947 static xmlSchemaConstructionCtxtPtr 9948 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict) 9949 { 9950 xmlSchemaConstructionCtxtPtr ret; 9951 9952 ret = (xmlSchemaConstructionCtxtPtr) 9953 xmlMalloc(sizeof(xmlSchemaConstructionCtxt)); 9954 if (ret == NULL) { 9955 xmlSchemaPErrMemory(NULL, 9956 "allocating schema construction context", NULL); 9957 return (NULL); 9958 } 9959 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt)); 9960 9961 ret->buckets = xmlSchemaItemListCreate(); 9962 if (ret->buckets == NULL) { 9963 xmlSchemaPErrMemory(NULL, 9964 "allocating list of schema buckets", NULL); 9965 xmlFree(ret); 9966 return (NULL); 9967 } 9968 ret->pending = xmlSchemaItemListCreate(); 9969 if (ret->pending == NULL) { 9970 xmlSchemaPErrMemory(NULL, 9971 "allocating list of pending global components", NULL); 9972 xmlSchemaConstructionCtxtFree(ret); 9973 return (NULL); 9974 } 9975 ret->dict = dict; 9976 xmlDictReference(dict); 9977 return(ret); 9978 } 9979 9980 static xmlSchemaParserCtxtPtr 9981 xmlSchemaParserCtxtCreate(void) 9982 { 9983 xmlSchemaParserCtxtPtr ret; 9984 9985 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt)); 9986 if (ret == NULL) { 9987 xmlSchemaPErrMemory(NULL, "allocating schema parser context", 9988 NULL); 9989 return (NULL); 9990 } 9991 memset(ret, 0, sizeof(xmlSchemaParserCtxt)); 9992 ret->type = XML_SCHEMA_CTXT_PARSER; 9993 ret->attrProhibs = xmlSchemaItemListCreate(); 9994 if (ret->attrProhibs == NULL) { 9995 xmlFree(ret); 9996 return(NULL); 9997 } 9998 return(ret); 9999 } 10000 10001 /** 10002 * xmlSchemaNewParserCtxtUseDict: 10003 * @URL: the location of the schema 10004 * @dict: the dictionary to be used 10005 * 10006 * Create an XML Schemas parse context for that file/resource expected 10007 * to contain an XML Schemas file. 10008 * 10009 * Returns the parser context or NULL in case of error 10010 */ 10011 static xmlSchemaParserCtxtPtr 10012 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict) 10013 { 10014 xmlSchemaParserCtxtPtr ret; 10015 10016 ret = xmlSchemaParserCtxtCreate(); 10017 if (ret == NULL) 10018 return (NULL); 10019 ret->dict = dict; 10020 xmlDictReference(dict); 10021 if (URL != NULL) 10022 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1); 10023 return (ret); 10024 } 10025 10026 static int 10027 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt) 10028 { 10029 if (vctxt->pctxt == NULL) { 10030 if (vctxt->schema != NULL) 10031 vctxt->pctxt = 10032 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict); 10033 else 10034 vctxt->pctxt = xmlSchemaNewParserCtxt("*"); 10035 if (vctxt->pctxt == NULL) { 10036 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt", 10037 "failed to create a temp. parser context"); 10038 return (-1); 10039 } 10040 /* TODO: Pass user data. */ 10041 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error, 10042 vctxt->warning, vctxt->errCtxt); 10043 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror, 10044 vctxt->errCtxt); 10045 } 10046 return (0); 10047 } 10048 10049 /** 10050 * xmlSchemaGetSchemaBucket: 10051 * @pctxt: the schema parser context 10052 * @schemaLocation: the URI of the schema document 10053 * 10054 * Returns a schema bucket if it was already parsed. 10055 * 10056 * Returns a schema bucket if it was already parsed from 10057 * @schemaLocation, NULL otherwise. 10058 */ 10059 static xmlSchemaBucketPtr 10060 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10061 const xmlChar *schemaLocation) 10062 { 10063 xmlSchemaBucketPtr cur; 10064 xmlSchemaItemListPtr list; 10065 10066 list = pctxt->constructor->buckets; 10067 if (list->nbItems == 0) 10068 return(NULL); 10069 else { 10070 int i; 10071 for (i = 0; i < list->nbItems; i++) { 10072 cur = (xmlSchemaBucketPtr) list->items[i]; 10073 /* Pointer comparison! */ 10074 if (cur->schemaLocation == schemaLocation) 10075 return(cur); 10076 } 10077 } 10078 return(NULL); 10079 } 10080 10081 static xmlSchemaBucketPtr 10082 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt, 10083 const xmlChar *schemaLocation, 10084 const xmlChar *targetNamespace) 10085 { 10086 xmlSchemaBucketPtr cur; 10087 xmlSchemaItemListPtr list; 10088 10089 list = pctxt->constructor->buckets; 10090 if (list->nbItems == 0) 10091 return(NULL); 10092 else { 10093 int i; 10094 for (i = 0; i < list->nbItems; i++) { 10095 cur = (xmlSchemaBucketPtr) list->items[i]; 10096 /* Pointer comparison! */ 10097 if ((cur->origTargetNamespace == NULL) && 10098 (cur->schemaLocation == schemaLocation) && 10099 (cur->targetNamespace == targetNamespace)) 10100 return(cur); 10101 } 10102 } 10103 return(NULL); 10104 } 10105 10106 10107 #define IS_BAD_SCHEMA_DOC(b) \ 10108 (((b)->doc == NULL) && ((b)->schemaLocation != NULL)) 10109 10110 static xmlSchemaBucketPtr 10111 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt, 10112 const xmlChar *targetNamespace, 10113 int imported) 10114 { 10115 xmlSchemaBucketPtr cur; 10116 xmlSchemaItemListPtr list; 10117 10118 list = pctxt->constructor->buckets; 10119 if (list->nbItems == 0) 10120 return(NULL); 10121 else { 10122 int i; 10123 for (i = 0; i < list->nbItems; i++) { 10124 cur = (xmlSchemaBucketPtr) list->items[i]; 10125 if ((! IS_BAD_SCHEMA_DOC(cur)) && 10126 (cur->origTargetNamespace == targetNamespace) && 10127 ((imported && cur->imported) || 10128 ((!imported) && (!cur->imported)))) 10129 return(cur); 10130 } 10131 } 10132 return(NULL); 10133 } 10134 10135 static int 10136 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt, 10137 xmlSchemaPtr schema, 10138 xmlSchemaBucketPtr bucket) 10139 { 10140 int oldFlags; 10141 xmlDocPtr oldDoc; 10142 xmlNodePtr node; 10143 int ret, oldErrs; 10144 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket; 10145 10146 /* 10147 * Save old values; reset the *main* schema. 10148 * URGENT TODO: This is not good; move the per-document information 10149 * to the parser. Get rid of passing the main schema to the 10150 * parsing functions. 10151 */ 10152 oldFlags = schema->flags; 10153 oldDoc = schema->doc; 10154 if (schema->flags != 0) 10155 xmlSchemaClearSchemaDefaults(schema); 10156 schema->doc = bucket->doc; 10157 pctxt->schema = schema; 10158 /* 10159 * Keep the current target namespace on the parser *not* on the 10160 * main schema. 10161 */ 10162 pctxt->targetNamespace = bucket->targetNamespace; 10163 WXS_CONSTRUCTOR(pctxt)->bucket = bucket; 10164 10165 if ((bucket->targetNamespace != NULL) && 10166 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) { 10167 /* 10168 * We are parsing the schema for schemas! 10169 */ 10170 pctxt->isS4S = 1; 10171 } 10172 /* Mark it as parsed, even if parsing fails. */ 10173 bucket->parsed++; 10174 /* Compile the schema doc. */ 10175 node = xmlDocGetRootElement(bucket->doc); 10176 ret = xmlSchemaParseSchemaElement(pctxt, schema, node); 10177 if (ret != 0) 10178 goto exit; 10179 /* An empty schema; just get out. */ 10180 if (node->children == NULL) 10181 goto exit; 10182 oldErrs = pctxt->nberrors; 10183 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children); 10184 if (ret != 0) 10185 goto exit; 10186 /* 10187 * TODO: Not nice, but I'm not 100% sure we will get always an error 10188 * as a result of the obove functions; so better rely on pctxt->err 10189 * as well. 10190 */ 10191 if ((ret == 0) && (oldErrs != pctxt->nberrors)) { 10192 ret = pctxt->err; 10193 goto exit; 10194 } 10195 10196 exit: 10197 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket; 10198 /* Restore schema values. */ 10199 schema->doc = oldDoc; 10200 schema->flags = oldFlags; 10201 return(ret); 10202 } 10203 10204 static int 10205 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt, 10206 xmlSchemaPtr schema, 10207 xmlSchemaBucketPtr bucket) 10208 { 10209 xmlSchemaParserCtxtPtr newpctxt; 10210 int res = 0; 10211 10212 if (bucket == NULL) 10213 return(0); 10214 if (bucket->parsed) { 10215 PERROR_INT("xmlSchemaParseNewDoc", 10216 "reparsing a schema doc"); 10217 return(-1); 10218 } 10219 if (bucket->doc == NULL) { 10220 PERROR_INT("xmlSchemaParseNewDoc", 10221 "parsing a schema doc, but there's no doc"); 10222 return(-1); 10223 } 10224 if (pctxt->constructor == NULL) { 10225 PERROR_INT("xmlSchemaParseNewDoc", 10226 "no constructor"); 10227 return(-1); 10228 } 10229 /* Create and init the temporary parser context. */ 10230 newpctxt = xmlSchemaNewParserCtxtUseDict( 10231 (const char *) bucket->schemaLocation, pctxt->dict); 10232 if (newpctxt == NULL) 10233 return(-1); 10234 newpctxt->constructor = pctxt->constructor; 10235 /* 10236 * TODO: Can we avoid that the parser knows about the main schema? 10237 * It would be better if he knows about the current schema bucket 10238 * only. 10239 */ 10240 newpctxt->schema = schema; 10241 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning, 10242 pctxt->errCtxt); 10243 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror, 10244 pctxt->errCtxt); 10245 newpctxt->counter = pctxt->counter; 10246 10247 10248 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket); 10249 10250 /* Channel back errors and cleanup the temporary parser context. */ 10251 if (res != 0) 10252 pctxt->err = res; 10253 pctxt->nberrors += newpctxt->nberrors; 10254 pctxt->counter = newpctxt->counter; 10255 newpctxt->constructor = NULL; 10256 /* Free the parser context. */ 10257 xmlSchemaFreeParserCtxt(newpctxt); 10258 return(res); 10259 } 10260 10261 static void 10262 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket, 10263 xmlSchemaSchemaRelationPtr rel) 10264 { 10265 xmlSchemaSchemaRelationPtr cur = bucket->relations; 10266 10267 if (cur == NULL) { 10268 bucket->relations = rel; 10269 return; 10270 } 10271 while (cur->next != NULL) 10272 cur = cur->next; 10273 cur->next = rel; 10274 } 10275 10276 10277 static const xmlChar * 10278 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location, 10279 xmlNodePtr ctxtNode) 10280 { 10281 /* 10282 * Build an absolue location URI. 10283 */ 10284 if (location != NULL) { 10285 if (ctxtNode == NULL) 10286 return(location); 10287 else { 10288 xmlChar *base, *URI; 10289 const xmlChar *ret = NULL; 10290 10291 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode); 10292 if (base == NULL) { 10293 URI = xmlBuildURI(location, ctxtNode->doc->URL); 10294 } else { 10295 URI = xmlBuildURI(location, base); 10296 xmlFree(base); 10297 } 10298 if (URI != NULL) { 10299 ret = xmlDictLookup(dict, URI, -1); 10300 xmlFree(URI); 10301 return(ret); 10302 } 10303 } 10304 } 10305 return(NULL); 10306 } 10307 10308 10309 10310 /** 10311 * xmlSchemaAddSchemaDoc: 10312 * @pctxt: a schema validation context 10313 * @schema: the schema being built 10314 * @node: a subtree containing XML Schema informations 10315 * 10316 * Parse an included (and to-be-redefined) XML schema document. 10317 * 10318 * Returns 0 on success, a positive error code on errors and 10319 * -1 in case of an internal or API error. 10320 */ 10321 10322 static int 10323 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt, 10324 int type, /* import or include or redefine */ 10325 const xmlChar *schemaLocation, 10326 xmlDocPtr schemaDoc, 10327 const char *schemaBuffer, 10328 int schemaBufferLen, 10329 xmlNodePtr invokingNode, 10330 const xmlChar *sourceTargetNamespace, 10331 const xmlChar *importNamespace, 10332 xmlSchemaBucketPtr *bucket) 10333 { 10334 const xmlChar *targetNamespace = NULL; 10335 xmlSchemaSchemaRelationPtr relation = NULL; 10336 xmlDocPtr doc = NULL; 10337 int res = 0, err = 0, located = 0, preserveDoc = 0; 10338 xmlSchemaBucketPtr bkt = NULL; 10339 10340 if (bucket != NULL) 10341 *bucket = NULL; 10342 10343 switch (type) { 10344 case XML_SCHEMA_SCHEMA_IMPORT: 10345 case XML_SCHEMA_SCHEMA_MAIN: 10346 err = XML_SCHEMAP_SRC_IMPORT; 10347 break; 10348 case XML_SCHEMA_SCHEMA_INCLUDE: 10349 err = XML_SCHEMAP_SRC_INCLUDE; 10350 break; 10351 case XML_SCHEMA_SCHEMA_REDEFINE: 10352 err = XML_SCHEMAP_SRC_REDEFINE; 10353 break; 10354 } 10355 10356 10357 /* Special handling for the main schema: 10358 * skip the location and relation logic and just parse the doc. 10359 * We need just a bucket to be returned in this case. 10360 */ 10361 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt))) 10362 goto doc_load; 10363 10364 /* Note that we expect the location to be an absulute URI. */ 10365 if (schemaLocation != NULL) { 10366 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation); 10367 if ((bkt != NULL) && 10368 (pctxt->constructor->bucket == bkt)) { 10369 /* Report self-imports/inclusions/redefinitions. */ 10370 10371 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10372 invokingNode, NULL, 10373 "The schema must not import/include/redefine itself", 10374 NULL, NULL); 10375 goto exit; 10376 } 10377 } 10378 /* 10379 * Create a relation for the graph of schemas. 10380 */ 10381 relation = xmlSchemaSchemaRelationCreate(); 10382 if (relation == NULL) 10383 return(-1); 10384 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket, 10385 relation); 10386 relation->type = type; 10387 10388 /* 10389 * Save the namespace import information. 10390 */ 10391 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10392 relation->importNamespace = importNamespace; 10393 if (schemaLocation == NULL) { 10394 /* 10395 * No location; this is just an import of the namespace. 10396 * Note that we don't assign a bucket to the relation 10397 * in this case. 10398 */ 10399 goto exit; 10400 } 10401 targetNamespace = importNamespace; 10402 } 10403 10404 /* Did we already fetch the doc? */ 10405 if (bkt != NULL) { 10406 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) { 10407 /* 10408 * We included/redefined and then try to import a schema, 10409 * but the new location provided for import was different. 10410 */ 10411 if (schemaLocation == NULL) 10412 schemaLocation = BAD_CAST "in_memory_buffer"; 10413 if (!xmlStrEqual(schemaLocation, 10414 bkt->schemaLocation)) { 10415 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10416 invokingNode, NULL, 10417 "The schema document '%s' cannot be imported, since " 10418 "it was already included or redefined", 10419 schemaLocation, NULL); 10420 goto exit; 10421 } 10422 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) { 10423 /* 10424 * We imported and then try to include/redefine a schema, 10425 * but the new location provided for the include/redefine 10426 * was different. 10427 */ 10428 if (schemaLocation == NULL) 10429 schemaLocation = BAD_CAST "in_memory_buffer"; 10430 if (!xmlStrEqual(schemaLocation, 10431 bkt->schemaLocation)) { 10432 xmlSchemaCustomErr(ACTXT_CAST pctxt, err, 10433 invokingNode, NULL, 10434 "The schema document '%s' cannot be included or " 10435 "redefined, since it was already imported", 10436 schemaLocation, NULL); 10437 goto exit; 10438 } 10439 } 10440 } 10441 10442 if (WXS_IS_BUCKET_IMPMAIN(type)) { 10443 /* 10444 * Given that the schemaLocation [attribute] is only a hint, it is open 10445 * to applications to ignore all but the first <import> for a given 10446 * namespace, regardless of the `actual value` of schemaLocation, but 10447 * such a strategy risks missing useful information when new 10448 * schemaLocations are offered. 10449 * 10450 * We will use the first <import> that comes with a location. 10451 * Further <import>s *with* a location, will result in an error. 10452 * TODO: Better would be to just report a warning here, but 10453 * we'll try it this way until someone complains. 10454 * 10455 * Schema Document Location Strategy: 10456 * 3 Based on the namespace name, identify an existing schema document, 10457 * either as a resource which is an XML document or a <schema> element 10458 * information item, in some local schema repository; 10459 * 5 Attempt to resolve the namespace name to locate such a resource. 10460 * 10461 * NOTE: (3) and (5) are not supported. 10462 */ 10463 if (bkt != NULL) { 10464 relation->bucket = bkt; 10465 goto exit; 10466 } 10467 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt, 10468 importNamespace, 1); 10469 10470 if (bkt != NULL) { 10471 relation->bucket = bkt; 10472 if (bkt->schemaLocation == NULL) { 10473 /* First given location of the schema; load the doc. */ 10474 bkt->schemaLocation = schemaLocation; 10475 } else { 10476 if (!xmlStrEqual(schemaLocation, 10477 bkt->schemaLocation)) { 10478 /* 10479 * Additional location given; just skip it. 10480 * URGENT TODO: We should report a warning here. 10481 * res = XML_SCHEMAP_SRC_IMPORT; 10482 */ 10483 if (schemaLocation == NULL) 10484 schemaLocation = BAD_CAST "in_memory_buffer"; 10485 10486 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10487 XML_SCHEMAP_WARN_SKIP_SCHEMA, 10488 invokingNode, NULL, 10489 "Skipping import of schema located at '%s' for the " 10490 "namespace '%s', since this namespace was already " 10491 "imported with the schema located at '%s'", 10492 schemaLocation, importNamespace, bkt->schemaLocation); 10493 } 10494 goto exit; 10495 } 10496 } 10497 /* 10498 * No bucket + first location: load the doc and create a 10499 * bucket. 10500 */ 10501 } else { 10502 /* <include> and <redefine> */ 10503 if (bkt != NULL) { 10504 10505 if ((bkt->origTargetNamespace == NULL) && 10506 (bkt->targetNamespace != sourceTargetNamespace)) { 10507 xmlSchemaBucketPtr chamel; 10508 10509 /* 10510 * Chameleon include/redefine: skip loading only if it was 10511 * aleady build for the targetNamespace of the including 10512 * schema. 10513 */ 10514 /* 10515 * URGENT TODO: If the schema is a chameleon-include then copy 10516 * the components into the including schema and modify the 10517 * targetNamespace of those components, do nothing otherwise. 10518 * NOTE: This is currently worked-around by compiling the 10519 * chameleon for every destinct including targetNamespace; thus 10520 * not performant at the moment. 10521 * TODO: Check when the namespace in wildcards for chameleons 10522 * needs to be converted: before we built wildcard intersections 10523 * or after. 10524 * Answer: after! 10525 */ 10526 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt, 10527 schemaLocation, sourceTargetNamespace); 10528 if (chamel != NULL) { 10529 /* A fitting chameleon was already parsed; NOP. */ 10530 relation->bucket = chamel; 10531 goto exit; 10532 } 10533 /* 10534 * We need to parse the chameleon again for a different 10535 * targetNamespace. 10536 * CHAMELEON TODO: Optimize this by only parsing the 10537 * chameleon once, and then copying the components to 10538 * the new targetNamespace. 10539 */ 10540 bkt = NULL; 10541 } else { 10542 relation->bucket = bkt; 10543 goto exit; 10544 } 10545 } 10546 } 10547 if ((bkt != NULL) && (bkt->doc != NULL)) { 10548 PERROR_INT("xmlSchemaAddSchemaDoc", 10549 "trying to load a schema doc, but a doc is already " 10550 "assigned to the schema bucket"); 10551 goto exit_failure; 10552 } 10553 10554 doc_load: 10555 /* 10556 * Load the document. 10557 */ 10558 if (schemaDoc != NULL) { 10559 doc = schemaDoc; 10560 /* Don' free this one, since it was provided by the caller. */ 10561 preserveDoc = 1; 10562 /* TODO: Does the context or the doc hold the location? */ 10563 if (schemaDoc->URL != NULL) 10564 schemaLocation = xmlDictLookup(pctxt->dict, 10565 schemaDoc->URL, -1); 10566 else 10567 schemaLocation = BAD_CAST "in_memory_buffer"; 10568 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) { 10569 xmlParserCtxtPtr parserCtxt; 10570 10571 parserCtxt = xmlNewParserCtxt(); 10572 if (parserCtxt == NULL) { 10573 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, " 10574 "allocating a parser context", NULL); 10575 goto exit_failure; 10576 } 10577 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) { 10578 /* 10579 * TODO: Do we have to burden the schema parser dict with all 10580 * the content of the schema doc? 10581 */ 10582 xmlDictFree(parserCtxt->dict); 10583 parserCtxt->dict = pctxt->dict; 10584 xmlDictReference(parserCtxt->dict); 10585 } 10586 if (schemaLocation != NULL) { 10587 /* Parse from file. */ 10588 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation, 10589 NULL, SCHEMAS_PARSE_OPTIONS); 10590 } else if (schemaBuffer != NULL) { 10591 /* Parse from memory buffer. */ 10592 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen, 10593 NULL, NULL, SCHEMAS_PARSE_OPTIONS); 10594 schemaLocation = BAD_CAST "in_memory_buffer"; 10595 if (doc != NULL) 10596 doc->URL = xmlStrdup(schemaLocation); 10597 } 10598 /* 10599 * For <import>: 10600 * 2.1 The referent is (a fragment of) a resource which is an 10601 * XML document (see clause 1.1), which in turn corresponds to 10602 * a <schema> element information item in a well-formed information 10603 * set, which in turn corresponds to a valid schema. 10604 * TODO: (2.1) fragments of XML documents are not supported. 10605 * 10606 * 2.2 The referent is a <schema> element information item in 10607 * a well-formed information set, which in turn corresponds 10608 * to a valid schema. 10609 * TODO: (2.2) is not supported. 10610 */ 10611 if (doc == NULL) { 10612 xmlErrorPtr lerr; 10613 lerr = xmlGetLastError(); 10614 /* 10615 * Check if this a parser error, or if the document could 10616 * just not be located. 10617 * TODO: Try to find specific error codes to react only on 10618 * localisation failures. 10619 */ 10620 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) { 10621 /* 10622 * We assume a parser error here. 10623 */ 10624 located = 1; 10625 /* TODO: Error code ?? */ 10626 res = XML_SCHEMAP_SRC_IMPORT_2_1; 10627 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 10628 invokingNode, NULL, 10629 "Failed to parse the XML resource '%s'", 10630 schemaLocation, NULL); 10631 } 10632 } 10633 xmlFreeParserCtxt(parserCtxt); 10634 if ((doc == NULL) && located) 10635 goto exit_error; 10636 } else { 10637 xmlSchemaPErr(pctxt, NULL, 10638 XML_SCHEMAP_NOTHING_TO_PARSE, 10639 "No information for parsing was provided with the " 10640 "given schema parser context.\n", 10641 NULL, NULL); 10642 goto exit_failure; 10643 } 10644 /* 10645 * Preprocess the document. 10646 */ 10647 if (doc != NULL) { 10648 xmlNodePtr docElem = NULL; 10649 10650 located = 1; 10651 docElem = xmlDocGetRootElement(doc); 10652 if (docElem == NULL) { 10653 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT, 10654 invokingNode, NULL, 10655 "The document '%s' has no document element", 10656 schemaLocation, NULL); 10657 goto exit_error; 10658 } 10659 /* 10660 * Remove all the blank text nodes. 10661 */ 10662 xmlSchemaCleanupDoc(pctxt, docElem); 10663 /* 10664 * Check the schema's top level element. 10665 */ 10666 if (!IS_SCHEMA(docElem, "schema")) { 10667 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA, 10668 invokingNode, NULL, 10669 "The XML document '%s' is not a schema document", 10670 schemaLocation, NULL); 10671 goto exit_error; 10672 } 10673 /* 10674 * Note that we don't apply a type check for the 10675 * targetNamespace value here. 10676 */ 10677 targetNamespace = xmlSchemaGetProp(pctxt, docElem, 10678 "targetNamespace"); 10679 } 10680 10681 /* after_doc_loading: */ 10682 if ((bkt == NULL) && located) { 10683 /* Only create a bucket if the schema was located. */ 10684 bkt = xmlSchemaBucketCreate(pctxt, type, 10685 targetNamespace); 10686 if (bkt == NULL) 10687 goto exit_failure; 10688 } 10689 if (bkt != NULL) { 10690 bkt->schemaLocation = schemaLocation; 10691 bkt->located = located; 10692 if (doc != NULL) { 10693 bkt->doc = doc; 10694 bkt->targetNamespace = targetNamespace; 10695 bkt->origTargetNamespace = targetNamespace; 10696 if (preserveDoc) 10697 bkt->preserveDoc = 1; 10698 } 10699 if (WXS_IS_BUCKET_IMPMAIN(type)) 10700 bkt->imported++; 10701 /* 10702 * Add it to the graph of schemas. 10703 */ 10704 if (relation != NULL) 10705 relation->bucket = bkt; 10706 } 10707 10708 exit: 10709 /* 10710 * Return the bucket explicitely; this is needed for the 10711 * main schema. 10712 */ 10713 if (bucket != NULL) 10714 *bucket = bkt; 10715 return (0); 10716 10717 exit_error: 10718 if ((doc != NULL) && (! preserveDoc)) { 10719 xmlFreeDoc(doc); 10720 if (bkt != NULL) 10721 bkt->doc = NULL; 10722 } 10723 return(pctxt->err); 10724 10725 exit_failure: 10726 if ((doc != NULL) && (! preserveDoc)) { 10727 xmlFreeDoc(doc); 10728 if (bkt != NULL) 10729 bkt->doc = NULL; 10730 } 10731 return (-1); 10732 } 10733 10734 /** 10735 * xmlSchemaParseImport: 10736 * @ctxt: a schema validation context 10737 * @schema: the schema being built 10738 * @node: a subtree containing XML Schema informations 10739 * 10740 * parse a XML schema Import definition 10741 * *WARNING* this interface is highly subject to change 10742 * 10743 * Returns 0 in case of success, a positive error code if 10744 * not valid and -1 in case of an internal error. 10745 */ 10746 static int 10747 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 10748 xmlNodePtr node) 10749 { 10750 xmlNodePtr child; 10751 const xmlChar *namespaceName = NULL, *schemaLocation = NULL; 10752 const xmlChar *thisTargetNamespace; 10753 xmlAttrPtr attr; 10754 int ret = 0; 10755 xmlSchemaBucketPtr bucket = NULL; 10756 10757 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 10758 return (-1); 10759 10760 /* 10761 * Check for illegal attributes. 10762 */ 10763 attr = node->properties; 10764 while (attr != NULL) { 10765 if (attr->ns == NULL) { 10766 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10767 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) && 10768 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10769 xmlSchemaPIllegalAttrErr(pctxt, 10770 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10771 } 10772 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10773 xmlSchemaPIllegalAttrErr(pctxt, 10774 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10775 } 10776 attr = attr->next; 10777 } 10778 /* 10779 * Extract and validate attributes. 10780 */ 10781 if (xmlSchemaPValAttr(pctxt, NULL, node, 10782 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10783 &namespaceName) != 0) { 10784 xmlSchemaPSimpleTypeErr(pctxt, 10785 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10786 NULL, node, 10787 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10788 NULL, namespaceName, NULL, NULL, NULL); 10789 return (pctxt->err); 10790 } 10791 10792 if (xmlSchemaPValAttr(pctxt, NULL, node, 10793 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10794 &schemaLocation) != 0) { 10795 xmlSchemaPSimpleTypeErr(pctxt, 10796 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 10797 NULL, node, 10798 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10799 NULL, schemaLocation, NULL, NULL, NULL); 10800 return (pctxt->err); 10801 } 10802 /* 10803 * And now for the children... 10804 */ 10805 child = node->children; 10806 if (IS_SCHEMA(child, "annotation")) { 10807 /* 10808 * the annotation here is simply discarded ... 10809 * TODO: really? 10810 */ 10811 child = child->next; 10812 } 10813 if (child != NULL) { 10814 xmlSchemaPContentErr(pctxt, 10815 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 10816 NULL, node, child, NULL, 10817 "(annotation?)"); 10818 } 10819 /* 10820 * Apply additional constraints. 10821 * 10822 * Note that it is important to use the original @targetNamespace 10823 * (or none at all), to rule out imports of schemas _with_ a 10824 * @targetNamespace if the importing schema is a chameleon schema 10825 * (with no @targetNamespace). 10826 */ 10827 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace; 10828 if (namespaceName != NULL) { 10829 /* 10830 * 1.1 If the namespace [attribute] is present, then its `actual value` 10831 * must not match the `actual value` of the enclosing <schema>'s 10832 * targetNamespace [attribute]. 10833 */ 10834 if (xmlStrEqual(thisTargetNamespace, namespaceName)) { 10835 xmlSchemaPCustomErr(pctxt, 10836 XML_SCHEMAP_SRC_IMPORT_1_1, 10837 NULL, node, 10838 "The value of the attribute 'namespace' must not match " 10839 "the target namespace '%s' of the importing schema", 10840 thisTargetNamespace); 10841 return (pctxt->err); 10842 } 10843 } else { 10844 /* 10845 * 1.2 If the namespace [attribute] is not present, then the enclosing 10846 * <schema> must have a targetNamespace [attribute]. 10847 */ 10848 if (thisTargetNamespace == NULL) { 10849 xmlSchemaPCustomErr(pctxt, 10850 XML_SCHEMAP_SRC_IMPORT_1_2, 10851 NULL, node, 10852 "The attribute 'namespace' must be existent if " 10853 "the importing schema has no target namespace", 10854 NULL); 10855 return (pctxt->err); 10856 } 10857 } 10858 /* 10859 * Locate and acquire the schema document. 10860 */ 10861 if (schemaLocation != NULL) 10862 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict, 10863 schemaLocation, node); 10864 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT, 10865 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace, 10866 namespaceName, &bucket); 10867 10868 if (ret != 0) 10869 return(ret); 10870 10871 /* 10872 * For <import>: "It is *not* an error for the application 10873 * schema reference strategy to fail." 10874 * So just don't parse if no schema document was found. 10875 * Note that we will get no bucket if the schema could not be 10876 * located or if there was no schemaLocation. 10877 */ 10878 if ((bucket == NULL) && (schemaLocation != NULL)) { 10879 xmlSchemaCustomWarning(ACTXT_CAST pctxt, 10880 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, 10881 node, NULL, 10882 "Failed to locate a schema at location '%s'. " 10883 "Skipping the import", schemaLocation, NULL, NULL); 10884 } 10885 10886 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) { 10887 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket); 10888 } 10889 10890 return (ret); 10891 } 10892 10893 static int 10894 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt, 10895 xmlSchemaPtr schema, 10896 xmlNodePtr node, 10897 xmlChar **schemaLocation, 10898 int type) 10899 { 10900 xmlAttrPtr attr; 10901 10902 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) || 10903 (schemaLocation == NULL)) 10904 return (-1); 10905 10906 *schemaLocation = NULL; 10907 /* 10908 * Check for illegal attributes. 10909 * Applies for both <include> and <redefine>. 10910 */ 10911 attr = node->properties; 10912 while (attr != NULL) { 10913 if (attr->ns == NULL) { 10914 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 10915 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) { 10916 xmlSchemaPIllegalAttrErr(pctxt, 10917 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10918 } 10919 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 10920 xmlSchemaPIllegalAttrErr(pctxt, 10921 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 10922 } 10923 attr = attr->next; 10924 } 10925 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id"); 10926 /* 10927 * Preliminary step, extract the URI-Reference and make an URI 10928 * from the base. 10929 */ 10930 /* 10931 * Attribute "schemaLocation" is mandatory. 10932 */ 10933 attr = xmlSchemaGetPropNode(node, "schemaLocation"); 10934 if (attr != NULL) { 10935 xmlChar *base = NULL; 10936 xmlChar *uri = NULL; 10937 10938 if (xmlSchemaPValAttrNode(pctxt, NULL, attr, 10939 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), 10940 (const xmlChar **) schemaLocation) != 0) 10941 goto exit_error; 10942 base = xmlNodeGetBase(node->doc, node); 10943 if (base == NULL) { 10944 uri = xmlBuildURI(*schemaLocation, node->doc->URL); 10945 } else { 10946 uri = xmlBuildURI(*schemaLocation, base); 10947 xmlFree(base); 10948 } 10949 if (uri == NULL) { 10950 PERROR_INT("xmlSchemaParseIncludeOrRedefine", 10951 "could not build an URI from the schemaLocation") 10952 goto exit_failure; 10953 } 10954 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1); 10955 xmlFree(uri); 10956 } else { 10957 xmlSchemaPMissingAttrErr(pctxt, 10958 XML_SCHEMAP_S4S_ATTR_MISSING, 10959 NULL, node, "schemaLocation", NULL); 10960 goto exit_error; 10961 } 10962 /* 10963 * Report self-inclusion and self-redefinition. 10964 */ 10965 if (xmlStrEqual(*schemaLocation, pctxt->URL)) { 10966 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 10967 xmlSchemaPCustomErr(pctxt, 10968 XML_SCHEMAP_SRC_REDEFINE, 10969 NULL, node, 10970 "The schema document '%s' cannot redefine itself.", 10971 *schemaLocation); 10972 } else { 10973 xmlSchemaPCustomErr(pctxt, 10974 XML_SCHEMAP_SRC_INCLUDE, 10975 NULL, node, 10976 "The schema document '%s' cannot include itself.", 10977 *schemaLocation); 10978 } 10979 goto exit_error; 10980 } 10981 10982 return(0); 10983 exit_error: 10984 return(pctxt->err); 10985 exit_failure: 10986 return(-1); 10987 } 10988 10989 static int 10990 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt, 10991 xmlSchemaPtr schema, 10992 xmlNodePtr node, 10993 int type) 10994 { 10995 xmlNodePtr child = NULL; 10996 const xmlChar *schemaLocation = NULL; 10997 int res = 0; /* hasRedefinitions = 0 */ 10998 int isChameleon = 0, wasChameleon = 0; 10999 xmlSchemaBucketPtr bucket = NULL; 11000 11001 if ((pctxt == NULL) || (schema == NULL) || (node == NULL)) 11002 return (-1); 11003 11004 /* 11005 * Parse attributes. Note that the returned schemaLocation will 11006 * be already converted to an absolute URI. 11007 */ 11008 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema, 11009 node, (xmlChar **) (&schemaLocation), type); 11010 if (res != 0) 11011 return(res); 11012 /* 11013 * Load and add the schema document. 11014 */ 11015 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL, 11016 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket); 11017 if (res != 0) 11018 return(res); 11019 /* 11020 * If we get no schema bucket back, then this means that the schema 11021 * document could not be located or was broken XML or was not 11022 * a schema document. 11023 */ 11024 if ((bucket == NULL) || (bucket->doc == NULL)) { 11025 if (type == XML_SCHEMA_SCHEMA_INCLUDE) { 11026 /* 11027 * WARNING for <include>: 11028 * We will raise an error if the schema cannot be located 11029 * for inclusions, since the that was the feedback from the 11030 * schema people. I.e. the following spec piece will *not* be 11031 * satisfied: 11032 * SPEC src-include: "It is not an error for the `actual value` of the 11033 * schemaLocation [attribute] to fail to resolve it all, in which 11034 * case no corresponding inclusion is performed. 11035 * So do we need a warning report here?" 11036 */ 11037 res = XML_SCHEMAP_SRC_INCLUDE; 11038 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11039 node, NULL, 11040 "Failed to load the document '%s' for inclusion", 11041 schemaLocation, NULL); 11042 } else { 11043 /* 11044 * NOTE: This was changed to raise an error even if no redefinitions 11045 * are specified. 11046 * 11047 * SPEC src-redefine (1) 11048 * "If there are any element information items among the [children] 11049 * other than <annotation> then the `actual value` of the 11050 * schemaLocation [attribute] must successfully resolve." 11051 * TODO: Ask the WG if a the location has always to resolve 11052 * here as well! 11053 */ 11054 res = XML_SCHEMAP_SRC_REDEFINE; 11055 xmlSchemaCustomErr(ACTXT_CAST pctxt, res, 11056 node, NULL, 11057 "Failed to load the document '%s' for redefinition", 11058 schemaLocation, NULL); 11059 } 11060 } else { 11061 /* 11062 * Check targetNamespace sanity before parsing the new schema. 11063 * TODO: Note that we won't check further content if the 11064 * targetNamespace was bad. 11065 */ 11066 if (bucket->origTargetNamespace != NULL) { 11067 /* 11068 * SPEC src-include (2.1) 11069 * "SII has a targetNamespace [attribute], and its `actual 11070 * value` is identical to the `actual value` of the targetNamespace 11071 * [attribute] of SII' (which must have such an [attribute])." 11072 */ 11073 if (pctxt->targetNamespace == NULL) { 11074 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11075 XML_SCHEMAP_SRC_INCLUDE, 11076 node, NULL, 11077 "The target namespace of the included/redefined schema " 11078 "'%s' has to be absent, since the including/redefining " 11079 "schema has no target namespace", 11080 schemaLocation, NULL); 11081 goto exit_error; 11082 } else if (!xmlStrEqual(bucket->origTargetNamespace, 11083 pctxt->targetNamespace)) { 11084 /* TODO: Change error function. */ 11085 xmlSchemaPCustomErrExt(pctxt, 11086 XML_SCHEMAP_SRC_INCLUDE, 11087 NULL, node, 11088 "The target namespace '%s' of the included/redefined " 11089 "schema '%s' differs from '%s' of the " 11090 "including/redefining schema", 11091 bucket->origTargetNamespace, schemaLocation, 11092 pctxt->targetNamespace); 11093 goto exit_error; 11094 } 11095 } else if (pctxt->targetNamespace != NULL) { 11096 /* 11097 * Chameleons: the original target namespace will 11098 * differ from the resulting namespace. 11099 */ 11100 isChameleon = 1; 11101 if (bucket->parsed && 11102 bucket->origTargetNamespace != NULL) { 11103 xmlSchemaCustomErr(ACTXT_CAST pctxt, 11104 XML_SCHEMAP_SRC_INCLUDE, 11105 node, NULL, 11106 "The target namespace of the included/redefined schema " 11107 "'%s' has to be absent or the same as the " 11108 "including/redefining schema's target namespace", 11109 schemaLocation, NULL); 11110 goto exit_error; 11111 } 11112 bucket->targetNamespace = pctxt->targetNamespace; 11113 } 11114 } 11115 /* 11116 * Parse the schema. 11117 */ 11118 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) { 11119 if (isChameleon) { 11120 /* TODO: Get rid of this flag on the schema itself. */ 11121 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) { 11122 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11123 } else 11124 wasChameleon = 1; 11125 } 11126 xmlSchemaParseNewDoc(pctxt, schema, bucket); 11127 /* Restore chameleon flag. */ 11128 if (isChameleon && (!wasChameleon)) 11129 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS; 11130 } 11131 /* 11132 * And now for the children... 11133 */ 11134 child = node->children; 11135 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11136 /* 11137 * Parse (simpleType | complexType | group | attributeGroup))* 11138 */ 11139 pctxt->redefined = bucket; 11140 /* 11141 * How to proceed if the redefined schema was not located? 11142 */ 11143 pctxt->isRedefine = 1; 11144 while (IS_SCHEMA(child, "annotation") || 11145 IS_SCHEMA(child, "simpleType") || 11146 IS_SCHEMA(child, "complexType") || 11147 IS_SCHEMA(child, "group") || 11148 IS_SCHEMA(child, "attributeGroup")) { 11149 if (IS_SCHEMA(child, "annotation")) { 11150 /* 11151 * TODO: discard or not? 11152 */ 11153 } else if (IS_SCHEMA(child, "simpleType")) { 11154 xmlSchemaParseSimpleType(pctxt, schema, child, 1); 11155 } else if (IS_SCHEMA(child, "complexType")) { 11156 xmlSchemaParseComplexType(pctxt, schema, child, 1); 11157 /* hasRedefinitions = 1; */ 11158 } else if (IS_SCHEMA(child, "group")) { 11159 /* hasRedefinitions = 1; */ 11160 xmlSchemaParseModelGroupDefinition(pctxt, 11161 schema, child); 11162 } else if (IS_SCHEMA(child, "attributeGroup")) { 11163 /* hasRedefinitions = 1; */ 11164 xmlSchemaParseAttributeGroupDefinition(pctxt, schema, 11165 child); 11166 } 11167 child = child->next; 11168 } 11169 pctxt->redefined = NULL; 11170 pctxt->isRedefine = 0; 11171 } else { 11172 if (IS_SCHEMA(child, "annotation")) { 11173 /* 11174 * TODO: discard or not? 11175 */ 11176 child = child->next; 11177 } 11178 } 11179 if (child != NULL) { 11180 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED; 11181 if (type == XML_SCHEMA_SCHEMA_REDEFINE) { 11182 xmlSchemaPContentErr(pctxt, res, 11183 NULL, node, child, NULL, 11184 "(annotation | (simpleType | complexType | group | attributeGroup))*"); 11185 } else { 11186 xmlSchemaPContentErr(pctxt, res, 11187 NULL, node, child, NULL, 11188 "(annotation?)"); 11189 } 11190 } 11191 return(res); 11192 11193 exit_error: 11194 return(pctxt->err); 11195 } 11196 11197 static int 11198 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11199 xmlNodePtr node) 11200 { 11201 int res; 11202 #ifndef ENABLE_REDEFINE 11203 TODO 11204 return(0); 11205 #endif 11206 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11207 XML_SCHEMA_SCHEMA_REDEFINE); 11208 if (res != 0) 11209 return(res); 11210 return(0); 11211 } 11212 11213 static int 11214 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema, 11215 xmlNodePtr node) 11216 { 11217 int res; 11218 11219 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 11220 XML_SCHEMA_SCHEMA_INCLUDE); 11221 if (res != 0) 11222 return(res); 11223 return(0); 11224 } 11225 11226 /** 11227 * xmlSchemaParseModelGroup: 11228 * @ctxt: a schema validation context 11229 * @schema: the schema being built 11230 * @node: a subtree containing XML Schema informations 11231 * @type: the "compositor" type 11232 * @particleNeeded: if a a model group with a particle 11233 * 11234 * parse a XML schema Sequence definition. 11235 * Applies parts of: 11236 * Schema Representation Constraint: 11237 * Redefinition Constraints and Semantics (src-redefine) 11238 * (6.1), (6.1.1), (6.1.2) 11239 * 11240 * Schema Component Constraint: 11241 * All Group Limited (cos-all-limited) (2) 11242 * TODO: Actually this should go to component-level checks, 11243 * but is done here due to performance. Move it to an other layer 11244 * is schema construction via an API is implemented. 11245 * 11246 * *WARNING* this interface is highly subject to change 11247 * 11248 * Returns -1 in case of error, 0 if the declaration is improper and 11249 * 1 in case of success. 11250 */ 11251 static xmlSchemaTreeItemPtr 11252 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11253 xmlNodePtr node, xmlSchemaTypeType type, 11254 int withParticle) 11255 { 11256 xmlSchemaModelGroupPtr item; 11257 xmlSchemaParticlePtr particle = NULL; 11258 xmlNodePtr child = NULL; 11259 xmlAttrPtr attr; 11260 int min = 1, max = 1, isElemRef, hasRefs = 0; 11261 11262 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11263 return (NULL); 11264 /* 11265 * Create a model group with the given compositor. 11266 */ 11267 item = xmlSchemaAddModelGroup(ctxt, schema, type, node); 11268 if (item == NULL) 11269 return (NULL); 11270 11271 if (withParticle) { 11272 if (type == XML_SCHEMA_TYPE_ALL) { 11273 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)"); 11274 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1"); 11275 } else { 11276 /* choice + sequence */ 11277 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger"); 11278 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, 11279 "(xs:nonNegativeInteger | unbounded)"); 11280 } 11281 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max); 11282 /* 11283 * Create a particle 11284 */ 11285 particle = xmlSchemaAddParticle(ctxt, node, min, max); 11286 if (particle == NULL) 11287 return (NULL); 11288 particle->children = (xmlSchemaTreeItemPtr) item; 11289 /* 11290 * Check for illegal attributes. 11291 */ 11292 attr = node->properties; 11293 while (attr != NULL) { 11294 if (attr->ns == NULL) { 11295 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11296 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) && 11297 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) { 11298 xmlSchemaPIllegalAttrErr(ctxt, 11299 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11300 } 11301 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11302 xmlSchemaPIllegalAttrErr(ctxt, 11303 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11304 } 11305 attr = attr->next; 11306 } 11307 } else { 11308 /* 11309 * Check for illegal attributes. 11310 */ 11311 attr = node->properties; 11312 while (attr != NULL) { 11313 if (attr->ns == NULL) { 11314 if (!xmlStrEqual(attr->name, BAD_CAST "id")) { 11315 xmlSchemaPIllegalAttrErr(ctxt, 11316 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11317 } 11318 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11319 xmlSchemaPIllegalAttrErr(ctxt, 11320 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11321 } 11322 attr = attr->next; 11323 } 11324 } 11325 11326 /* 11327 * Extract and validate attributes. 11328 */ 11329 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11330 /* 11331 * And now for the children... 11332 */ 11333 child = node->children; 11334 if (IS_SCHEMA(child, "annotation")) { 11335 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 11336 child = child->next; 11337 } 11338 if (type == XML_SCHEMA_TYPE_ALL) { 11339 xmlSchemaParticlePtr part, last = NULL; 11340 11341 while (IS_SCHEMA(child, "element")) { 11342 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt, 11343 schema, child, &isElemRef, 0); 11344 /* 11345 * SPEC cos-all-limited (2) 11346 * "The {max occurs} of all the particles in the {particles} 11347 * of the ('all') group must be 0 or 1. 11348 */ 11349 if (part != NULL) { 11350 if (isElemRef) 11351 hasRefs++; 11352 if (part->minOccurs > 1) { 11353 xmlSchemaPCustomErr(ctxt, 11354 XML_SCHEMAP_COS_ALL_LIMITED, 11355 NULL, child, 11356 "Invalid value for minOccurs (must be 0 or 1)", 11357 NULL); 11358 /* Reset to 1. */ 11359 part->minOccurs = 1; 11360 } 11361 if (part->maxOccurs > 1) { 11362 xmlSchemaPCustomErr(ctxt, 11363 XML_SCHEMAP_COS_ALL_LIMITED, 11364 NULL, child, 11365 "Invalid value for maxOccurs (must be 0 or 1)", 11366 NULL); 11367 /* Reset to 1. */ 11368 part->maxOccurs = 1; 11369 } 11370 if (last == NULL) 11371 item->children = (xmlSchemaTreeItemPtr) part; 11372 else 11373 last->next = (xmlSchemaTreeItemPtr) part; 11374 last = part; 11375 } 11376 child = child->next; 11377 } 11378 if (child != NULL) { 11379 xmlSchemaPContentErr(ctxt, 11380 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11381 NULL, node, child, NULL, 11382 "(annotation?, (annotation?, element*)"); 11383 } 11384 } else { 11385 /* choice + sequence */ 11386 xmlSchemaTreeItemPtr part = NULL, last = NULL; 11387 11388 while ((IS_SCHEMA(child, "element")) || 11389 (IS_SCHEMA(child, "group")) || 11390 (IS_SCHEMA(child, "any")) || 11391 (IS_SCHEMA(child, "choice")) || 11392 (IS_SCHEMA(child, "sequence"))) { 11393 11394 if (IS_SCHEMA(child, "element")) { 11395 part = (xmlSchemaTreeItemPtr) 11396 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0); 11397 if (part && isElemRef) 11398 hasRefs++; 11399 } else if (IS_SCHEMA(child, "group")) { 11400 part = 11401 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11402 if (part != NULL) 11403 hasRefs++; 11404 /* 11405 * Handle redefinitions. 11406 */ 11407 if (ctxt->isRedefine && ctxt->redef && 11408 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) && 11409 part && part->children) 11410 { 11411 if ((xmlSchemaGetQNameRefName(part->children) == 11412 ctxt->redef->refName) && 11413 (xmlSchemaGetQNameRefTargetNs(part->children) == 11414 ctxt->redef->refTargetNs)) 11415 { 11416 /* 11417 * SPEC src-redefine: 11418 * (6.1) "If it has a <group> among its contents at 11419 * some level the `actual value` of whose ref 11420 * [attribute] is the same as the `actual value` of 11421 * its own name attribute plus target namespace, then 11422 * all of the following must be true:" 11423 * (6.1.1) "It must have exactly one such group." 11424 */ 11425 if (ctxt->redefCounter != 0) { 11426 xmlChar *str = NULL; 11427 11428 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11429 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11430 "The redefining model group definition " 11431 "'%s' must not contain more than one " 11432 "reference to the redefined definition", 11433 xmlSchemaFormatQName(&str, 11434 ctxt->redef->refTargetNs, 11435 ctxt->redef->refName), 11436 NULL); 11437 FREE_AND_NULL(str) 11438 part = NULL; 11439 } else if (((WXS_PARTICLE(part))->minOccurs != 1) || 11440 ((WXS_PARTICLE(part))->maxOccurs != 1)) 11441 { 11442 xmlChar *str = NULL; 11443 /* 11444 * SPEC src-redefine: 11445 * (6.1.2) "The `actual value` of both that 11446 * group's minOccurs and maxOccurs [attribute] 11447 * must be 1 (or `absent`). 11448 */ 11449 xmlSchemaCustomErr(ACTXT_CAST ctxt, 11450 XML_SCHEMAP_SRC_REDEFINE, child, NULL, 11451 "The redefining model group definition " 11452 "'%s' must not contain a reference to the " 11453 "redefined definition with a " 11454 "maxOccurs/minOccurs other than 1", 11455 xmlSchemaFormatQName(&str, 11456 ctxt->redef->refTargetNs, 11457 ctxt->redef->refName), 11458 NULL); 11459 FREE_AND_NULL(str) 11460 part = NULL; 11461 } 11462 ctxt->redef->reference = WXS_BASIC_CAST part; 11463 ctxt->redefCounter++; 11464 } 11465 } 11466 } else if (IS_SCHEMA(child, "any")) { 11467 part = (xmlSchemaTreeItemPtr) 11468 xmlSchemaParseAny(ctxt, schema, child); 11469 } else if (IS_SCHEMA(child, "choice")) { 11470 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11471 XML_SCHEMA_TYPE_CHOICE, 1); 11472 } else if (IS_SCHEMA(child, "sequence")) { 11473 part = xmlSchemaParseModelGroup(ctxt, schema, child, 11474 XML_SCHEMA_TYPE_SEQUENCE, 1); 11475 } 11476 if (part != NULL) { 11477 if (last == NULL) 11478 item->children = part; 11479 else 11480 last->next = part; 11481 last = part; 11482 } 11483 child = child->next; 11484 } 11485 if (child != NULL) { 11486 xmlSchemaPContentErr(ctxt, 11487 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11488 NULL, node, child, NULL, 11489 "(annotation?, (element | group | choice | sequence | any)*)"); 11490 } 11491 } 11492 if ((max == 0) && (min == 0)) 11493 return (NULL); 11494 if (hasRefs) { 11495 /* 11496 * We need to resolve references. 11497 */ 11498 WXS_ADD_PENDING(ctxt, item); 11499 } 11500 if (withParticle) 11501 return ((xmlSchemaTreeItemPtr) particle); 11502 else 11503 return ((xmlSchemaTreeItemPtr) item); 11504 } 11505 11506 /** 11507 * xmlSchemaParseRestriction: 11508 * @ctxt: a schema validation context 11509 * @schema: the schema being built 11510 * @node: a subtree containing XML Schema informations 11511 * 11512 * parse a XML schema Restriction definition 11513 * *WARNING* this interface is highly subject to change 11514 * 11515 * Returns the type definition or NULL in case of error 11516 */ 11517 static xmlSchemaTypePtr 11518 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11519 xmlNodePtr node, xmlSchemaTypeType parentType) 11520 { 11521 xmlSchemaTypePtr type; 11522 xmlNodePtr child = NULL; 11523 xmlAttrPtr attr; 11524 11525 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11526 return (NULL); 11527 /* Not a component, don't create it. */ 11528 type = ctxt->ctxtType; 11529 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 11530 11531 /* 11532 * Check for illegal attributes. 11533 */ 11534 attr = node->properties; 11535 while (attr != NULL) { 11536 if (attr->ns == NULL) { 11537 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11538 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11539 xmlSchemaPIllegalAttrErr(ctxt, 11540 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11541 } 11542 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11543 xmlSchemaPIllegalAttrErr(ctxt, 11544 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11545 } 11546 attr = attr->next; 11547 } 11548 /* 11549 * Extract and validate attributes. 11550 */ 11551 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11552 /* 11553 * Attribute 11554 */ 11555 /* 11556 * Extract the base type. The "base" attribute is mandatory if inside 11557 * a complex type or if redefining. 11558 * 11559 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> " 11560 * among its [children]), the simple type definition which is 11561 * the {content type} of the type definition `resolved` to by 11562 * the `actual value` of the base [attribute]" 11563 */ 11564 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base", 11565 &(type->baseNs), &(type->base)) == 0) 11566 { 11567 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) { 11568 xmlSchemaPMissingAttrErr(ctxt, 11569 XML_SCHEMAP_S4S_ATTR_MISSING, 11570 NULL, node, "base", NULL); 11571 } else if ((ctxt->isRedefine) && 11572 (type->flags & XML_SCHEMAS_TYPE_GLOBAL)) 11573 { 11574 if (type->base == NULL) { 11575 xmlSchemaPMissingAttrErr(ctxt, 11576 XML_SCHEMAP_S4S_ATTR_MISSING, 11577 NULL, node, "base", NULL); 11578 } else if ((! xmlStrEqual(type->base, type->name)) || 11579 (! xmlStrEqual(type->baseNs, type->targetNamespace))) 11580 { 11581 xmlChar *str1 = NULL, *str2 = NULL; 11582 /* 11583 * REDEFINE: SPEC src-redefine (5) 11584 * "Within the [children], each <simpleType> must have a 11585 * <restriction> among its [children] ... the `actual value` of 11586 * whose base [attribute] must be the same as the `actual value` 11587 * of its own name attribute plus target namespace;" 11588 */ 11589 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE, 11590 NULL, node, "This is a redefinition, but the QName " 11591 "value '%s' of the 'base' attribute does not match the " 11592 "type's designation '%s'", 11593 xmlSchemaFormatQName(&str1, type->baseNs, type->base), 11594 xmlSchemaFormatQName(&str2, type->targetNamespace, 11595 type->name), NULL); 11596 FREE_AND_NULL(str1); 11597 FREE_AND_NULL(str2); 11598 /* Avoid confusion and erase the values. */ 11599 type->base = NULL; 11600 type->baseNs = NULL; 11601 } 11602 } 11603 } 11604 /* 11605 * And now for the children... 11606 */ 11607 child = node->children; 11608 if (IS_SCHEMA(child, "annotation")) { 11609 /* 11610 * Add the annotation to the simple type ancestor. 11611 */ 11612 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11613 xmlSchemaParseAnnotation(ctxt, child, 1)); 11614 child = child->next; 11615 } 11616 if (parentType == XML_SCHEMA_TYPE_SIMPLE) { 11617 /* 11618 * Corresponds to <simpleType><restriction><simpleType>. 11619 */ 11620 if (IS_SCHEMA(child, "simpleType")) { 11621 if (type->base != NULL) { 11622 /* 11623 * src-restriction-base-or-simpleType 11624 * Either the base [attribute] or the simpleType [child] of the 11625 * <restriction> element must be present, but not both. 11626 */ 11627 xmlSchemaPContentErr(ctxt, 11628 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11629 NULL, node, child, 11630 "The attribute 'base' and the <simpleType> child are " 11631 "mutually exclusive", NULL); 11632 } else { 11633 type->baseType = (xmlSchemaTypePtr) 11634 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11635 } 11636 child = child->next; 11637 } else if (type->base == NULL) { 11638 xmlSchemaPContentErr(ctxt, 11639 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, 11640 NULL, node, child, 11641 "Either the attribute 'base' or a <simpleType> child " 11642 "must be present", NULL); 11643 } 11644 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11645 /* 11646 * Corresponds to <complexType><complexContent><restriction>... 11647 * followed by: 11648 * 11649 * Model groups <all>, <choice> and <sequence>. 11650 */ 11651 if (IS_SCHEMA(child, "all")) { 11652 type->subtypes = (xmlSchemaTypePtr) 11653 xmlSchemaParseModelGroup(ctxt, schema, child, 11654 XML_SCHEMA_TYPE_ALL, 1); 11655 child = child->next; 11656 } else if (IS_SCHEMA(child, "choice")) { 11657 type->subtypes = (xmlSchemaTypePtr) 11658 xmlSchemaParseModelGroup(ctxt, 11659 schema, child, XML_SCHEMA_TYPE_CHOICE, 1); 11660 child = child->next; 11661 } else if (IS_SCHEMA(child, "sequence")) { 11662 type->subtypes = (xmlSchemaTypePtr) 11663 xmlSchemaParseModelGroup(ctxt, schema, child, 11664 XML_SCHEMA_TYPE_SEQUENCE, 1); 11665 child = child->next; 11666 /* 11667 * Model group reference <group>. 11668 */ 11669 } else if (IS_SCHEMA(child, "group")) { 11670 type->subtypes = (xmlSchemaTypePtr) 11671 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11672 /* 11673 * Note that the reference will be resolved in 11674 * xmlSchemaResolveTypeReferences(); 11675 */ 11676 child = child->next; 11677 } 11678 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11679 /* 11680 * Corresponds to <complexType><simpleContent><restriction>... 11681 * 11682 * "1.1 the simple type definition corresponding to the <simpleType> 11683 * among the [children] of <restriction> if there is one;" 11684 */ 11685 if (IS_SCHEMA(child, "simpleType")) { 11686 /* 11687 * We will store the to-be-restricted simple type in 11688 * type->contentTypeDef *temporarily*. 11689 */ 11690 type->contentTypeDef = (xmlSchemaTypePtr) 11691 xmlSchemaParseSimpleType(ctxt, schema, child, 0); 11692 if ( type->contentTypeDef == NULL) 11693 return (NULL); 11694 child = child->next; 11695 } 11696 } 11697 11698 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) || 11699 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) { 11700 xmlSchemaFacetPtr facet, lastfacet = NULL; 11701 /* 11702 * Corresponds to <complexType><simpleContent><restriction>... 11703 * <simpleType><restriction>... 11704 */ 11705 11706 /* 11707 * Add the facets to the simple type ancestor. 11708 */ 11709 /* 11710 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of 11711 * Simple Type Definition Schema Representation Constraint: 11712 * *Single Facet Value* 11713 */ 11714 while ((IS_SCHEMA(child, "minInclusive")) || 11715 (IS_SCHEMA(child, "minExclusive")) || 11716 (IS_SCHEMA(child, "maxInclusive")) || 11717 (IS_SCHEMA(child, "maxExclusive")) || 11718 (IS_SCHEMA(child, "totalDigits")) || 11719 (IS_SCHEMA(child, "fractionDigits")) || 11720 (IS_SCHEMA(child, "pattern")) || 11721 (IS_SCHEMA(child, "enumeration")) || 11722 (IS_SCHEMA(child, "whiteSpace")) || 11723 (IS_SCHEMA(child, "length")) || 11724 (IS_SCHEMA(child, "maxLength")) || 11725 (IS_SCHEMA(child, "minLength"))) { 11726 facet = xmlSchemaParseFacet(ctxt, schema, child); 11727 if (facet != NULL) { 11728 if (lastfacet == NULL) 11729 type->facets = facet; 11730 else 11731 lastfacet->next = facet; 11732 lastfacet = facet; 11733 lastfacet->next = NULL; 11734 } 11735 child = child->next; 11736 } 11737 /* 11738 * Create links for derivation and validation. 11739 */ 11740 if (type->facets != NULL) { 11741 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL; 11742 11743 facet = type->facets; 11744 do { 11745 facetLink = (xmlSchemaFacetLinkPtr) 11746 xmlMalloc(sizeof(xmlSchemaFacetLink)); 11747 if (facetLink == NULL) { 11748 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL); 11749 xmlFree(facetLink); 11750 return (NULL); 11751 } 11752 facetLink->facet = facet; 11753 facetLink->next = NULL; 11754 if (lastFacetLink == NULL) 11755 type->facetSet = facetLink; 11756 else 11757 lastFacetLink->next = facetLink; 11758 lastFacetLink = facetLink; 11759 facet = facet->next; 11760 } while (facet != NULL); 11761 } 11762 } 11763 if (type->type == XML_SCHEMA_TYPE_COMPLEX) { 11764 /* 11765 * Attribute uses/declarations. 11766 */ 11767 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11768 (xmlSchemaItemListPtr *) &(type->attrUses), 11769 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 11770 return(NULL); 11771 /* 11772 * Attribute wildcard. 11773 */ 11774 if (IS_SCHEMA(child, "anyAttribute")) { 11775 type->attributeWildcard = 11776 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11777 child = child->next; 11778 } 11779 } 11780 if (child != NULL) { 11781 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11782 xmlSchemaPContentErr(ctxt, 11783 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11784 NULL, node, child, NULL, 11785 "annotation?, (group | all | choice | sequence)?, " 11786 "((attribute | attributeGroup)*, anyAttribute?))"); 11787 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) { 11788 xmlSchemaPContentErr(ctxt, 11789 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11790 NULL, node, child, NULL, 11791 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11792 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11793 "length | minLength | maxLength | enumeration | whiteSpace | " 11794 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))"); 11795 } else { 11796 /* Simple type */ 11797 xmlSchemaPContentErr(ctxt, 11798 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11799 NULL, node, child, NULL, 11800 "(annotation?, (simpleType?, (minExclusive | minInclusive | " 11801 "maxExclusive | maxInclusive | totalDigits | fractionDigits | " 11802 "length | minLength | maxLength | enumeration | whiteSpace | " 11803 "pattern)*))"); 11804 } 11805 } 11806 return (NULL); 11807 } 11808 11809 /** 11810 * xmlSchemaParseExtension: 11811 * @ctxt: a schema validation context 11812 * @schema: the schema being built 11813 * @node: a subtree containing XML Schema informations 11814 * 11815 * Parses an <extension>, which is found inside a 11816 * <simpleContent> or <complexContent>. 11817 * *WARNING* this interface is highly subject to change. 11818 * 11819 * TODO: Returns the type definition or NULL in case of error 11820 */ 11821 static xmlSchemaTypePtr 11822 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 11823 xmlNodePtr node, xmlSchemaTypeType parentType) 11824 { 11825 xmlSchemaTypePtr type; 11826 xmlNodePtr child = NULL; 11827 xmlAttrPtr attr; 11828 11829 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 11830 return (NULL); 11831 /* Not a component, don't create it. */ 11832 type = ctxt->ctxtType; 11833 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION; 11834 11835 /* 11836 * Check for illegal attributes. 11837 */ 11838 attr = node->properties; 11839 while (attr != NULL) { 11840 if (attr->ns == NULL) { 11841 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 11842 (!xmlStrEqual(attr->name, BAD_CAST "base"))) { 11843 xmlSchemaPIllegalAttrErr(ctxt, 11844 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11845 } 11846 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11847 xmlSchemaPIllegalAttrErr(ctxt, 11848 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11849 } 11850 attr = attr->next; 11851 } 11852 11853 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11854 11855 /* 11856 * Attribute "base" - mandatory. 11857 */ 11858 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node, 11859 "base", &(type->baseNs), &(type->base)) == 0) && 11860 (type->base == NULL)) { 11861 xmlSchemaPMissingAttrErr(ctxt, 11862 XML_SCHEMAP_S4S_ATTR_MISSING, 11863 NULL, node, "base", NULL); 11864 } 11865 /* 11866 * And now for the children... 11867 */ 11868 child = node->children; 11869 if (IS_SCHEMA(child, "annotation")) { 11870 /* 11871 * Add the annotation to the type ancestor. 11872 */ 11873 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 11874 xmlSchemaParseAnnotation(ctxt, child, 1)); 11875 child = child->next; 11876 } 11877 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11878 /* 11879 * Corresponds to <complexType><complexContent><extension>... and: 11880 * 11881 * Model groups <all>, <choice>, <sequence> and <group>. 11882 */ 11883 if (IS_SCHEMA(child, "all")) { 11884 type->subtypes = (xmlSchemaTypePtr) 11885 xmlSchemaParseModelGroup(ctxt, schema, 11886 child, XML_SCHEMA_TYPE_ALL, 1); 11887 child = child->next; 11888 } else if (IS_SCHEMA(child, "choice")) { 11889 type->subtypes = (xmlSchemaTypePtr) 11890 xmlSchemaParseModelGroup(ctxt, schema, 11891 child, XML_SCHEMA_TYPE_CHOICE, 1); 11892 child = child->next; 11893 } else if (IS_SCHEMA(child, "sequence")) { 11894 type->subtypes = (xmlSchemaTypePtr) 11895 xmlSchemaParseModelGroup(ctxt, schema, 11896 child, XML_SCHEMA_TYPE_SEQUENCE, 1); 11897 child = child->next; 11898 } else if (IS_SCHEMA(child, "group")) { 11899 type->subtypes = (xmlSchemaTypePtr) 11900 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 11901 /* 11902 * Note that the reference will be resolved in 11903 * xmlSchemaResolveTypeReferences(); 11904 */ 11905 child = child->next; 11906 } 11907 } 11908 if (child != NULL) { 11909 /* 11910 * Attribute uses/declarations. 11911 */ 11912 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 11913 (xmlSchemaItemListPtr *) &(type->attrUses), 11914 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1) 11915 return(NULL); 11916 /* 11917 * Attribute wildcard. 11918 */ 11919 if (IS_SCHEMA(child, "anyAttribute")) { 11920 ctxt->ctxtType->attributeWildcard = 11921 xmlSchemaParseAnyAttribute(ctxt, schema, child); 11922 child = child->next; 11923 } 11924 } 11925 if (child != NULL) { 11926 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) { 11927 /* Complex content extension. */ 11928 xmlSchemaPContentErr(ctxt, 11929 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11930 NULL, node, child, NULL, 11931 "(annotation?, ((group | all | choice | sequence)?, " 11932 "((attribute | attributeGroup)*, anyAttribute?)))"); 11933 } else { 11934 /* Simple content extension. */ 11935 xmlSchemaPContentErr(ctxt, 11936 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 11937 NULL, node, child, NULL, 11938 "(annotation?, ((attribute | attributeGroup)*, " 11939 "anyAttribute?))"); 11940 } 11941 } 11942 return (NULL); 11943 } 11944 11945 /** 11946 * xmlSchemaParseSimpleContent: 11947 * @ctxt: a schema validation context 11948 * @schema: the schema being built 11949 * @node: a subtree containing XML Schema informations 11950 * 11951 * parse a XML schema SimpleContent definition 11952 * *WARNING* this interface is highly subject to change 11953 * 11954 * Returns the type definition or NULL in case of error 11955 */ 11956 static int 11957 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, 11958 xmlSchemaPtr schema, xmlNodePtr node, 11959 int *hasRestrictionOrExtension) 11960 { 11961 xmlSchemaTypePtr type; 11962 xmlNodePtr child = NULL; 11963 xmlAttrPtr attr; 11964 11965 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 11966 (hasRestrictionOrExtension == NULL)) 11967 return (-1); 11968 *hasRestrictionOrExtension = 0; 11969 /* Not a component, don't create it. */ 11970 type = ctxt->ctxtType; 11971 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 11972 /* 11973 * Check for illegal attributes. 11974 */ 11975 attr = node->properties; 11976 while (attr != NULL) { 11977 if (attr->ns == NULL) { 11978 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) { 11979 xmlSchemaPIllegalAttrErr(ctxt, 11980 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11981 } 11982 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 11983 xmlSchemaPIllegalAttrErr(ctxt, 11984 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 11985 } 11986 attr = attr->next; 11987 } 11988 11989 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 11990 11991 /* 11992 * And now for the children... 11993 */ 11994 child = node->children; 11995 if (IS_SCHEMA(child, "annotation")) { 11996 /* 11997 * Add the annotation to the complex type ancestor. 11998 */ 11999 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12000 xmlSchemaParseAnnotation(ctxt, child, 1)); 12001 child = child->next; 12002 } 12003 if (child == NULL) { 12004 xmlSchemaPContentErr(ctxt, 12005 XML_SCHEMAP_S4S_ELEM_MISSING, 12006 NULL, node, NULL, NULL, 12007 "(annotation?, (restriction | extension))"); 12008 } 12009 if (child == NULL) { 12010 xmlSchemaPContentErr(ctxt, 12011 XML_SCHEMAP_S4S_ELEM_MISSING, 12012 NULL, node, NULL, NULL, 12013 "(annotation?, (restriction | extension))"); 12014 } 12015 if (IS_SCHEMA(child, "restriction")) { 12016 xmlSchemaParseRestriction(ctxt, schema, child, 12017 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 12018 (*hasRestrictionOrExtension) = 1; 12019 child = child->next; 12020 } else if (IS_SCHEMA(child, "extension")) { 12021 xmlSchemaParseExtension(ctxt, schema, child, 12022 XML_SCHEMA_TYPE_SIMPLE_CONTENT); 12023 (*hasRestrictionOrExtension) = 1; 12024 child = child->next; 12025 } 12026 if (child != NULL) { 12027 xmlSchemaPContentErr(ctxt, 12028 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12029 NULL, node, child, NULL, 12030 "(annotation?, (restriction | extension))"); 12031 } 12032 return (0); 12033 } 12034 12035 /** 12036 * xmlSchemaParseComplexContent: 12037 * @ctxt: a schema validation context 12038 * @schema: the schema being built 12039 * @node: a subtree containing XML Schema informations 12040 * 12041 * parse a XML schema ComplexContent definition 12042 * *WARNING* this interface is highly subject to change 12043 * 12044 * Returns the type definition or NULL in case of error 12045 */ 12046 static int 12047 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, 12048 xmlSchemaPtr schema, xmlNodePtr node, 12049 int *hasRestrictionOrExtension) 12050 { 12051 xmlSchemaTypePtr type; 12052 xmlNodePtr child = NULL; 12053 xmlAttrPtr attr; 12054 12055 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) || 12056 (hasRestrictionOrExtension == NULL)) 12057 return (-1); 12058 *hasRestrictionOrExtension = 0; 12059 /* Not a component, don't create it. */ 12060 type = ctxt->ctxtType; 12061 /* 12062 * Check for illegal attributes. 12063 */ 12064 attr = node->properties; 12065 while (attr != NULL) { 12066 if (attr->ns == NULL) { 12067 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) && 12068 (!xmlStrEqual(attr->name, BAD_CAST "mixed"))) 12069 { 12070 xmlSchemaPIllegalAttrErr(ctxt, 12071 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12072 } 12073 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12074 xmlSchemaPIllegalAttrErr(ctxt, 12075 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12076 } 12077 attr = attr->next; 12078 } 12079 12080 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12081 12082 /* 12083 * Set the 'mixed' on the complex type ancestor. 12084 */ 12085 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) { 12086 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0) 12087 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12088 } 12089 child = node->children; 12090 if (IS_SCHEMA(child, "annotation")) { 12091 /* 12092 * Add the annotation to the complex type ancestor. 12093 */ 12094 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type, 12095 xmlSchemaParseAnnotation(ctxt, child, 1)); 12096 child = child->next; 12097 } 12098 if (child == NULL) { 12099 xmlSchemaPContentErr(ctxt, 12100 XML_SCHEMAP_S4S_ELEM_MISSING, 12101 NULL, node, NULL, 12102 NULL, "(annotation?, (restriction | extension))"); 12103 } 12104 if (child == NULL) { 12105 xmlSchemaPContentErr(ctxt, 12106 XML_SCHEMAP_S4S_ELEM_MISSING, 12107 NULL, node, NULL, 12108 NULL, "(annotation?, (restriction | extension))"); 12109 } 12110 if (IS_SCHEMA(child, "restriction")) { 12111 xmlSchemaParseRestriction(ctxt, schema, child, 12112 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12113 (*hasRestrictionOrExtension) = 1; 12114 child = child->next; 12115 } else if (IS_SCHEMA(child, "extension")) { 12116 xmlSchemaParseExtension(ctxt, schema, child, 12117 XML_SCHEMA_TYPE_COMPLEX_CONTENT); 12118 (*hasRestrictionOrExtension) = 1; 12119 child = child->next; 12120 } 12121 if (child != NULL) { 12122 xmlSchemaPContentErr(ctxt, 12123 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12124 NULL, node, child, 12125 NULL, "(annotation?, (restriction | extension))"); 12126 } 12127 return (0); 12128 } 12129 12130 /** 12131 * xmlSchemaParseComplexType: 12132 * @ctxt: a schema validation context 12133 * @schema: the schema being built 12134 * @node: a subtree containing XML Schema informations 12135 * 12136 * parse a XML schema Complex Type definition 12137 * *WARNING* this interface is highly subject to change 12138 * 12139 * Returns the type definition or NULL in case of error 12140 */ 12141 static xmlSchemaTypePtr 12142 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, 12143 xmlNodePtr node, int topLevel) 12144 { 12145 xmlSchemaTypePtr type, ctxtType; 12146 xmlNodePtr child = NULL; 12147 const xmlChar *name = NULL; 12148 xmlAttrPtr attr; 12149 const xmlChar *attrValue; 12150 #ifdef ENABLE_NAMED_LOCALS 12151 char buf[40]; 12152 #endif 12153 int final = 0, block = 0, hasRestrictionOrExtension = 0; 12154 12155 12156 if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) 12157 return (NULL); 12158 12159 ctxtType = ctxt->ctxtType; 12160 12161 if (topLevel) { 12162 attr = xmlSchemaGetPropNode(node, "name"); 12163 if (attr == NULL) { 12164 xmlSchemaPMissingAttrErr(ctxt, 12165 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL); 12166 return (NULL); 12167 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr, 12168 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) { 12169 return (NULL); 12170 } 12171 } 12172 12173 if (topLevel == 0) { 12174 /* 12175 * Parse as local complex type definition. 12176 */ 12177 #ifdef ENABLE_NAMED_LOCALS 12178 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1); 12179 type = xmlSchemaAddType(ctxt, schema, 12180 XML_SCHEMA_TYPE_COMPLEX, 12181 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1), 12182 ctxt->targetNamespace, node, 0); 12183 #else 12184 type = xmlSchemaAddType(ctxt, schema, 12185 XML_SCHEMA_TYPE_COMPLEX, 12186 NULL, ctxt->targetNamespace, node, 0); 12187 #endif 12188 if (type == NULL) 12189 return (NULL); 12190 name = type->name; 12191 type->node = node; 12192 type->type = XML_SCHEMA_TYPE_COMPLEX; 12193 /* 12194 * TODO: We need the target namespace. 12195 */ 12196 } else { 12197 /* 12198 * Parse as global complex type definition. 12199 */ 12200 type = xmlSchemaAddType(ctxt, schema, 12201 XML_SCHEMA_TYPE_COMPLEX, 12202 name, ctxt->targetNamespace, node, 1); 12203 if (type == NULL) 12204 return (NULL); 12205 type->node = node; 12206 type->type = XML_SCHEMA_TYPE_COMPLEX; 12207 type->flags |= XML_SCHEMAS_TYPE_GLOBAL; 12208 } 12209 type->targetNamespace = ctxt->targetNamespace; 12210 /* 12211 * Handle attributes. 12212 */ 12213 attr = node->properties; 12214 while (attr != NULL) { 12215 if (attr->ns == NULL) { 12216 if (xmlStrEqual(attr->name, BAD_CAST "id")) { 12217 /* 12218 * Attribute "id". 12219 */ 12220 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id"); 12221 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) { 12222 /* 12223 * Attribute "mixed". 12224 */ 12225 if (xmlSchemaPGetBoolNodeValue(ctxt, 12226 NULL, (xmlNodePtr) attr)) 12227 type->flags |= XML_SCHEMAS_TYPE_MIXED; 12228 } else if (topLevel) { 12229 /* 12230 * Attributes of global complex type definitions. 12231 */ 12232 if (xmlStrEqual(attr->name, BAD_CAST "name")) { 12233 /* Pass. */ 12234 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) { 12235 /* 12236 * Attribute "abstract". 12237 */ 12238 if (xmlSchemaPGetBoolNodeValue(ctxt, 12239 NULL, (xmlNodePtr) attr)) 12240 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT; 12241 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) { 12242 /* 12243 * Attribute "final". 12244 */ 12245 attrValue = xmlSchemaGetNodeContent(ctxt, 12246 (xmlNodePtr) attr); 12247 if (xmlSchemaPValAttrBlockFinal(attrValue, 12248 &(type->flags), 12249 -1, 12250 XML_SCHEMAS_TYPE_FINAL_EXTENSION, 12251 XML_SCHEMAS_TYPE_FINAL_RESTRICTION, 12252 -1, -1, -1) != 0) 12253 { 12254 xmlSchemaPSimpleTypeErr(ctxt, 12255 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12256 NULL, (xmlNodePtr) attr, NULL, 12257 "(#all | List of (extension | restriction))", 12258 attrValue, NULL, NULL, NULL); 12259 } else 12260 final = 1; 12261 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) { 12262 /* 12263 * Attribute "block". 12264 */ 12265 attrValue = xmlSchemaGetNodeContent(ctxt, 12266 (xmlNodePtr) attr); 12267 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags), 12268 -1, 12269 XML_SCHEMAS_TYPE_BLOCK_EXTENSION, 12270 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION, 12271 -1, -1, -1) != 0) { 12272 xmlSchemaPSimpleTypeErr(ctxt, 12273 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, 12274 NULL, (xmlNodePtr) attr, NULL, 12275 "(#all | List of (extension | restriction)) ", 12276 attrValue, NULL, NULL, NULL); 12277 } else 12278 block = 1; 12279 } else { 12280 xmlSchemaPIllegalAttrErr(ctxt, 12281 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12282 } 12283 } else { 12284 xmlSchemaPIllegalAttrErr(ctxt, 12285 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12286 } 12287 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) { 12288 xmlSchemaPIllegalAttrErr(ctxt, 12289 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr); 12290 } 12291 attr = attr->next; 12292 } 12293 if (! block) { 12294 /* 12295 * Apply default "block" values. 12296 */ 12297 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION) 12298 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION; 12299 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION) 12300 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION; 12301 } 12302 if (! final) { 12303 /* 12304 * Apply default "block" values. 12305 */ 12306 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION) 12307 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION; 12308 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION) 12309 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION; 12310 } 12311 /* 12312 * And now for the children... 12313 */ 12314 child = node->children; 12315 if (IS_SCHEMA(child, "annotation")) { 12316 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1); 12317 child = child->next; 12318 } 12319 ctxt->ctxtType = type; 12320 if (IS_SCHEMA(child, "simpleContent")) { 12321 /* 12322 * <complexType><simpleContent>... 12323 * 3.4.3 : 2.2 12324 * Specifying mixed='true' when the <simpleContent> 12325 * alternative is chosen has no effect 12326 */ 12327 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 12328 type->flags ^= XML_SCHEMAS_TYPE_MIXED; 12329 xmlSchemaParseSimpleContent(ctxt, schema, child, 12330 &hasRestrictionOrExtension); 12331 child = child->next; 12332 } else if (IS_SCHEMA(child, "complexContent")) { 12333 /* 12334 * <complexType><complexContent>... 12335 */ 12336 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 12337 xmlSchemaParseComplexContent(ctxt, schema, child, 12338 &hasRestrictionOrExtension); 12339 child = child->next; 12340 } else { 12341 /* 12342 * E.g <complexType><sequence>... or <complexType><attribute>... etc. 12343 * 12344 * SPEC 12345 * "...the third alternative (neither <simpleContent> nor 12346 * <complexContent>) is chosen. This case is understood as shorthand 12347 * for complex content restricting the `ur-type definition`, and the 12348 * details of the mappings should be modified as necessary. 12349 */ 12350 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 12351 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION; 12352 /* 12353 * Parse model groups. 12354 */ 12355 if (IS_SCHEMA(child, "all")) { 12356 type->subtypes = (xmlSchemaTypePtr) 12357 xmlSchemaParseModelGroup(ctxt, schema, child, 12358 XML_SCHEMA_TYPE_ALL, 1); 12359 child = child->next; 12360 } else if (IS_SCHEMA(child, "choice")) { 12361 type->subtypes = (xmlSchemaTypePtr) 12362 xmlSchemaParseModelGroup(ctxt, schema, child, 12363 XML_SCHEMA_TYPE_CHOICE, 1); 12364 child = child->next; 12365 } else if (IS_SCHEMA(child, "sequence")) { 12366 type->subtypes = (xmlSchemaTypePtr) 12367 xmlSchemaParseModelGroup(ctxt, schema, child, 12368 XML_SCHEMA_TYPE_SEQUENCE, 1); 12369 child = child->next; 12370 } else if (IS_SCHEMA(child, "group")) { 12371 type->subtypes = (xmlSchemaTypePtr) 12372 xmlSchemaParseModelGroupDefRef(ctxt, schema, child); 12373 /* 12374 * Note that the reference will be resolved in 12375 * xmlSchemaResolveTypeReferences(); 12376 */ 12377 child = child->next; 12378 } 12379 /* 12380 * Parse attribute decls/refs. 12381 */ 12382 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child, 12383 (xmlSchemaItemListPtr *) &(type->attrUses), 12384 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1) 12385 return(NULL); 12386 /* 12387 * Parse attribute wildcard. 12388 */ 12389 if (IS_SCHEMA(child, "anyAttribute")) { 12390 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child); 12391 child = child->next; 12392 } 12393 } 12394 if (child != NULL) { 12395 xmlSchemaPContentErr(ctxt, 12396 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, 12397 NULL, node, child, 12398 NULL, "(annotation?, (simpleContent | complexContent | " 12399 "((group | all | choice | sequence)?, ((attribute | " 12400 "attributeGroup)*, anyAttribute?))))"); 12401 } 12402 /* 12403 * REDEFINE: SPEC src-redefine (5) 12404 */ 12405 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) { 12406 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE, 12407 NULL, node, "This is a redefinition, thus the " 12408 "<complexType> must have a <restriction> or <extension> " 12409 "grand-child", NULL); 12410 } 12411 ctxt->ctxtType = ctxtType; 12412 return (type); 12413 } 12414 12415 /************************************************************************ 12416 * * 12417 * Validating using Schemas * 12418 * * 12419 ************************************************************************/ 12420 12421 /************************************************************************ 12422 * * 12423 * Reading/Writing Schemas * 12424 * * 12425 ************************************************************************/ 12426 12427 #if 0 /* Will be enabled if it is clear what options are needed. */ 12428 /** 12429 * xmlSchemaParserCtxtSetOptions: 12430 * @ctxt: a schema parser context 12431 * @options: a combination of xmlSchemaParserOption 12432 * 12433 * Sets the options to be used during the parse. 12434 * 12435 * Returns 0 in case of success, -1 in case of an 12436 * API error. 12437 */ 12438 static int 12439 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt, 12440 int options) 12441 12442 { 12443 int i; 12444 12445 if (ctxt == NULL) 12446 return (-1); 12447 /* 12448 * WARNING: Change the start value if adding to the 12449 * xmlSchemaParseOption. 12450 */ 12451 for (i = 1; i < (int) sizeof(int) * 8; i++) { 12452 if (options & 1<<i) { 12453 return (-1); 12454 } 12455 } 12456 ctxt->options = options; 12457 return (0); 12458 } 12459 12460 /** 12461 * xmlSchemaValidCtxtGetOptions: 12462 * @ctxt: a schema parser context 12463 * 12464 * Returns the option combination of the parser context. 12465 */ 12466 static int 12467 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt) 12468 12469 { 12470 if (ctxt == NULL) 12471 return (-1); 12472 else 12473 return (ctxt->options); 12474 } 12475 #endif 12476 12477 /** 12478 * xmlSchemaNewParserCtxt: 12479 * @URL: the location of the schema 12480 * 12481 * Create an XML Schemas parse context for that file/resource expected 12482 * to contain an XML Schemas file. 12483 * 12484 * Returns the parser context or NULL in case of error 12485 */ 12486 xmlSchemaParserCtxtPtr 12487 xmlSchemaNewParserCtxt(const char *URL) 12488 { 12489 xmlSchemaParserCtxtPtr ret; 12490 12491 if (URL == NULL) 12492 return (NULL); 12493 12494 ret = xmlSchemaParserCtxtCreate(); 12495 if (ret == NULL) 12496 return(NULL); 12497 ret->dict = xmlDictCreate(); 12498 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1); 12499 return (ret); 12500 } 12501 12502 /** 12503 * xmlSchemaNewMemParserCtxt: 12504 * @buffer: a pointer to a char array containing the schemas 12505 * @size: the size of the array 12506 * 12507 * Create an XML Schemas parse context for that memory buffer expected 12508 * to contain an XML Schemas file. 12509 * 12510 * Returns the parser context or NULL in case of error 12511 */ 12512 xmlSchemaParserCtxtPtr 12513 xmlSchemaNewMemParserCtxt(const char *buffer, int size) 12514 { 12515 xmlSchemaParserCtxtPtr ret; 12516 12517 if ((buffer == NULL) || (size <= 0)) 12518 return (NULL); 12519 ret = xmlSchemaParserCtxtCreate(); 12520 if (ret == NULL) 12521 return(NULL); 12522 ret->buffer = buffer; 12523 ret->size = size; 12524 ret->dict = xmlDictCreate(); 12525 return (ret); 12526 } 12527 12528 /** 12529 * xmlSchemaNewDocParserCtxt: 12530 * @doc: a preparsed document tree 12531 * 12532 * Create an XML Schemas parse context for that document. 12533 * NB. The document may be modified during the parsing process. 12534 * 12535 * Returns the parser context or NULL in case of error 12536 */ 12537 xmlSchemaParserCtxtPtr 12538 xmlSchemaNewDocParserCtxt(xmlDocPtr doc) 12539 { 12540 xmlSchemaParserCtxtPtr ret; 12541 12542 if (doc == NULL) 12543 return (NULL); 12544 ret = xmlSchemaParserCtxtCreate(); 12545 if (ret == NULL) 12546 return(NULL); 12547 ret->doc = doc; 12548 ret->dict = xmlDictCreate(); 12549 /* The application has responsibility for the document */ 12550 ret->preserve = 1; 12551 12552 return (ret); 12553 } 12554 12555 /** 12556 * xmlSchemaFreeParserCtxt: 12557 * @ctxt: the schema parser context 12558 * 12559 * Free the resources associated to the schema parser context 12560 */ 12561 void 12562 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) 12563 { 12564 if (ctxt == NULL) 12565 return; 12566 if (ctxt->doc != NULL && !ctxt->preserve) 12567 xmlFreeDoc(ctxt->doc); 12568 if (ctxt->vctxt != NULL) { 12569 xmlSchemaFreeValidCtxt(ctxt->vctxt); 12570 } 12571 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) { 12572 xmlSchemaConstructionCtxtFree(ctxt->constructor); 12573 ctxt->constructor = NULL; 12574 ctxt->ownsConstructor = 0; 12575 } 12576 if (ctxt->attrProhibs != NULL) 12577 xmlSchemaItemListFree(ctxt->attrProhibs); 12578 xmlDictFree(ctxt->dict); 12579 xmlFree(ctxt); 12580 } 12581 12582 /************************************************************************ 12583 * * 12584 * Building the content models * 12585 * * 12586 ************************************************************************/ 12587 12588 /** 12589 * xmlSchemaBuildContentModelForSubstGroup: 12590 * 12591 * Returns 1 if nillable, 0 otherwise 12592 */ 12593 static int 12594 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt, 12595 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end) 12596 { 12597 xmlAutomataStatePtr start, tmp; 12598 xmlSchemaElementPtr elemDecl, member; 12599 xmlSchemaSubstGroupPtr substGroup; 12600 int i; 12601 int ret = 0; 12602 12603 elemDecl = (xmlSchemaElementPtr) particle->children; 12604 /* 12605 * Wrap the substitution group with a CHOICE. 12606 */ 12607 start = pctxt->state; 12608 if (end == NULL) 12609 end = xmlAutomataNewState(pctxt->am); 12610 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl); 12611 if (substGroup == NULL) { 12612 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle), 12613 XML_SCHEMAP_INTERNAL, 12614 "Internal error: xmlSchemaBuildContentModelForSubstGroup, " 12615 "declaration is marked having a subst. group but none " 12616 "available.\n", elemDecl->name, NULL); 12617 return(0); 12618 } 12619 if (counter >= 0) { 12620 /* 12621 * NOTE that we put the declaration in, even if it's abstract. 12622 * However, an error will be raised during *validation* if an element 12623 * information item shall be validated against an abstract element 12624 * declaration. 12625 */ 12626 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter); 12627 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12628 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12629 /* 12630 * Add subst. group members. 12631 */ 12632 for (i = 0; i < substGroup->members->nbItems; i++) { 12633 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12634 xmlAutomataNewTransition2(pctxt->am, tmp, end, 12635 member->name, member->targetNamespace, member); 12636 } 12637 } else if (particle->maxOccurs == 1) { 12638 /* 12639 * NOTE that we put the declaration in, even if it's abstract, 12640 */ 12641 xmlAutomataNewEpsilon(pctxt->am, 12642 xmlAutomataNewTransition2(pctxt->am, 12643 start, NULL, 12644 elemDecl->name, elemDecl->targetNamespace, elemDecl), end); 12645 /* 12646 * Add subst. group members. 12647 */ 12648 for (i = 0; i < substGroup->members->nbItems; i++) { 12649 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12650 /* 12651 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2() 12652 * was incorrectly used instead of xmlAutomataNewTransition2() 12653 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL 12654 * section in xmlSchemaBuildAContentModel() ). 12655 * TODO: Check if xmlAutomataNewOnceTrans2() was instead 12656 * intended for the above "counter" section originally. I.e., 12657 * check xs:all with subst-groups. 12658 * 12659 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL, 12660 * member->name, member->targetNamespace, 12661 * 1, 1, member); 12662 */ 12663 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL, 12664 member->name, member->targetNamespace, member); 12665 xmlAutomataNewEpsilon(pctxt->am, tmp, end); 12666 } 12667 } else { 12668 xmlAutomataStatePtr hop; 12669 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12670 UNBOUNDED : particle->maxOccurs - 1; 12671 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12672 12673 counter = 12674 xmlAutomataNewCounter(pctxt->am, minOccurs, 12675 maxOccurs); 12676 hop = xmlAutomataNewState(pctxt->am); 12677 12678 xmlAutomataNewEpsilon(pctxt->am, 12679 xmlAutomataNewTransition2(pctxt->am, 12680 start, NULL, 12681 elemDecl->name, elemDecl->targetNamespace, elemDecl), 12682 hop); 12683 /* 12684 * Add subst. group members. 12685 */ 12686 for (i = 0; i < substGroup->members->nbItems; i++) { 12687 member = (xmlSchemaElementPtr) substGroup->members->items[i]; 12688 xmlAutomataNewEpsilon(pctxt->am, 12689 xmlAutomataNewTransition2(pctxt->am, 12690 start, NULL, 12691 member->name, member->targetNamespace, member), 12692 hop); 12693 } 12694 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12695 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12696 } 12697 if (particle->minOccurs == 0) { 12698 xmlAutomataNewEpsilon(pctxt->am, start, end); 12699 ret = 1; 12700 } 12701 pctxt->state = end; 12702 return(ret); 12703 } 12704 12705 /** 12706 * xmlSchemaBuildContentModelForElement: 12707 * 12708 * Returns 1 if nillable, 0 otherwise 12709 */ 12710 static int 12711 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt, 12712 xmlSchemaParticlePtr particle) 12713 { 12714 int ret = 0; 12715 12716 if (((xmlSchemaElementPtr) particle->children)->flags & 12717 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 12718 /* 12719 * Substitution groups. 12720 */ 12721 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL); 12722 } else { 12723 xmlSchemaElementPtr elemDecl; 12724 xmlAutomataStatePtr start; 12725 12726 elemDecl = (xmlSchemaElementPtr) particle->children; 12727 12728 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) 12729 return(0); 12730 if (particle->maxOccurs == 1) { 12731 start = ctxt->state; 12732 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12733 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12734 } else if ((particle->maxOccurs >= UNBOUNDED) && 12735 (particle->minOccurs < 2)) { 12736 /* Special case. */ 12737 start = ctxt->state; 12738 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12739 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12740 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state, 12741 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12742 } else { 12743 int counter; 12744 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 12745 UNBOUNDED : particle->maxOccurs - 1; 12746 int minOccurs = particle->minOccurs < 1 ? 12747 0 : particle->minOccurs - 1; 12748 12749 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL); 12750 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs); 12751 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL, 12752 elemDecl->name, elemDecl->targetNamespace, elemDecl); 12753 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter); 12754 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state, 12755 NULL, counter); 12756 } 12757 if (particle->minOccurs == 0) { 12758 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); 12759 ret = 1; 12760 } 12761 } 12762 return(ret); 12763 } 12764 12765 /** 12766 * xmlSchemaBuildAContentModel: 12767 * @ctxt: the schema parser context 12768 * @particle: the particle component 12769 * @name: the complex type's name whose content is being built 12770 * 12771 * Create the automaton for the {content type} of a complex type. 12772 * 12773 * Returns 1 if the content is nillable, 0 otherwise 12774 */ 12775 static int 12776 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt, 12777 xmlSchemaParticlePtr particle) 12778 { 12779 int ret = 0, tmp2; 12780 12781 if (particle == NULL) { 12782 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL"); 12783 return(1); 12784 } 12785 if (particle->children == NULL) { 12786 /* 12787 * Just return in this case. A missing "term" of the particle 12788 * might arise due to an invalid "term" component. 12789 */ 12790 return(1); 12791 } 12792 12793 switch (particle->children->type) { 12794 case XML_SCHEMA_TYPE_ANY: { 12795 xmlAutomataStatePtr start, end; 12796 xmlSchemaWildcardPtr wild; 12797 xmlSchemaWildcardNsPtr ns; 12798 12799 wild = (xmlSchemaWildcardPtr) particle->children; 12800 12801 start = pctxt->state; 12802 end = xmlAutomataNewState(pctxt->am); 12803 12804 if (particle->maxOccurs == 1) { 12805 if (wild->any == 1) { 12806 /* 12807 * We need to add both transitions: 12808 * 12809 * 1. the {"*", "*"} for elements in a namespace. 12810 */ 12811 pctxt->state = 12812 xmlAutomataNewTransition2(pctxt->am, 12813 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12814 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12815 /* 12816 * 2. the {"*"} for elements in no namespace. 12817 */ 12818 pctxt->state = 12819 xmlAutomataNewTransition2(pctxt->am, 12820 start, NULL, BAD_CAST "*", NULL, wild); 12821 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12822 12823 } else if (wild->nsSet != NULL) { 12824 ns = wild->nsSet; 12825 do { 12826 pctxt->state = start; 12827 pctxt->state = xmlAutomataNewTransition2(pctxt->am, 12828 pctxt->state, NULL, BAD_CAST "*", ns->value, wild); 12829 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 12830 ns = ns->next; 12831 } while (ns != NULL); 12832 12833 } else if (wild->negNsSet != NULL) { 12834 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12835 start, end, BAD_CAST "*", wild->negNsSet->value, 12836 wild); 12837 } 12838 } else { 12839 int counter; 12840 xmlAutomataStatePtr hop; 12841 int maxOccurs = 12842 particle->maxOccurs == UNBOUNDED ? UNBOUNDED : 12843 particle->maxOccurs - 1; 12844 int minOccurs = 12845 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 12846 12847 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 12848 hop = xmlAutomataNewState(pctxt->am); 12849 if (wild->any == 1) { 12850 pctxt->state = 12851 xmlAutomataNewTransition2(pctxt->am, 12852 start, NULL, BAD_CAST "*", BAD_CAST "*", wild); 12853 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12854 pctxt->state = 12855 xmlAutomataNewTransition2(pctxt->am, 12856 start, NULL, BAD_CAST "*", NULL, wild); 12857 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12858 } else if (wild->nsSet != NULL) { 12859 ns = wild->nsSet; 12860 do { 12861 pctxt->state = 12862 xmlAutomataNewTransition2(pctxt->am, 12863 start, NULL, BAD_CAST "*", ns->value, wild); 12864 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 12865 ns = ns->next; 12866 } while (ns != NULL); 12867 12868 } else if (wild->negNsSet != NULL) { 12869 pctxt->state = xmlAutomataNewNegTrans(pctxt->am, 12870 start, hop, BAD_CAST "*", wild->negNsSet->value, 12871 wild); 12872 } 12873 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter); 12874 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 12875 } 12876 if (particle->minOccurs == 0) { 12877 xmlAutomataNewEpsilon(pctxt->am, start, end); 12878 ret = 1; 12879 } 12880 pctxt->state = end; 12881 break; 12882 } 12883 case XML_SCHEMA_TYPE_ELEMENT: 12884 ret = xmlSchemaBuildContentModelForElement(pctxt, particle); 12885 break; 12886 case XML_SCHEMA_TYPE_SEQUENCE:{ 12887 xmlSchemaTreeItemPtr sub; 12888 12889 ret = 1; 12890 /* 12891 * If max and min occurances are default (1) then 12892 * simply iterate over the particles of the <sequence>. 12893 */ 12894 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) { 12895 sub = particle->children->children; 12896 12897 while (sub != NULL) { 12898 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12899 (xmlSchemaParticlePtr) sub); 12900 if (tmp2 != 1) ret = 0; 12901 sub = sub->next; 12902 } 12903 } else { 12904 xmlAutomataStatePtr oldstate = pctxt->state; 12905 12906 if (particle->maxOccurs >= UNBOUNDED) { 12907 if (particle->minOccurs > 1) { 12908 xmlAutomataStatePtr tmp; 12909 int counter; 12910 12911 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12912 oldstate, NULL); 12913 oldstate = pctxt->state; 12914 12915 counter = xmlAutomataNewCounter(pctxt->am, 12916 particle->minOccurs - 1, UNBOUNDED); 12917 12918 sub = particle->children->children; 12919 while (sub != NULL) { 12920 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12921 (xmlSchemaParticlePtr) sub); 12922 if (tmp2 != 1) ret = 0; 12923 sub = sub->next; 12924 } 12925 tmp = pctxt->state; 12926 xmlAutomataNewCountedTrans(pctxt->am, tmp, 12927 oldstate, counter); 12928 pctxt->state = 12929 xmlAutomataNewCounterTrans(pctxt->am, tmp, 12930 NULL, counter); 12931 if (ret == 1) 12932 xmlAutomataNewEpsilon(pctxt->am, 12933 oldstate, pctxt->state); 12934 12935 } else { 12936 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12937 oldstate, NULL); 12938 oldstate = pctxt->state; 12939 12940 sub = particle->children->children; 12941 while (sub != NULL) { 12942 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12943 (xmlSchemaParticlePtr) sub); 12944 if (tmp2 != 1) ret = 0; 12945 sub = sub->next; 12946 } 12947 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, 12948 oldstate); 12949 /* 12950 * epsilon needed to block previous trans from 12951 * being allowed to enter back from another 12952 * construct 12953 */ 12954 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12955 pctxt->state, NULL); 12956 if (particle->minOccurs == 0) { 12957 xmlAutomataNewEpsilon(pctxt->am, 12958 oldstate, pctxt->state); 12959 ret = 1; 12960 } 12961 } 12962 } else if ((particle->maxOccurs > 1) 12963 || (particle->minOccurs > 1)) { 12964 xmlAutomataStatePtr tmp; 12965 int counter; 12966 12967 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 12968 oldstate, NULL); 12969 oldstate = pctxt->state; 12970 12971 counter = xmlAutomataNewCounter(pctxt->am, 12972 particle->minOccurs - 1, 12973 particle->maxOccurs - 1); 12974 12975 sub = particle->children->children; 12976 while (sub != NULL) { 12977 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12978 (xmlSchemaParticlePtr) sub); 12979 if (tmp2 != 1) ret = 0; 12980 sub = sub->next; 12981 } 12982 tmp = pctxt->state; 12983 xmlAutomataNewCountedTrans(pctxt->am, 12984 tmp, oldstate, counter); 12985 pctxt->state = 12986 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL, 12987 counter); 12988 if ((particle->minOccurs == 0) || (ret == 1)) { 12989 xmlAutomataNewEpsilon(pctxt->am, 12990 oldstate, pctxt->state); 12991 ret = 1; 12992 } 12993 } else { 12994 sub = particle->children->children; 12995 while (sub != NULL) { 12996 tmp2 = xmlSchemaBuildAContentModel(pctxt, 12997 (xmlSchemaParticlePtr) sub); 12998 if (tmp2 != 1) ret = 0; 12999 sub = sub->next; 13000 } 13001 13002 /* 13003 * epsilon needed to block previous trans from 13004 * being allowed to enter back from another 13005 * construct 13006 */ 13007 pctxt->state = xmlAutomataNewEpsilon(pctxt->am, 13008 pctxt->state, NULL); 13009 13010 if (particle->minOccurs == 0) { 13011 xmlAutomataNewEpsilon(pctxt->am, oldstate, 13012 pctxt->state); 13013 ret = 1; 13014 } 13015 } 13016 } 13017 break; 13018 } 13019 case XML_SCHEMA_TYPE_CHOICE:{ 13020 xmlSchemaTreeItemPtr sub; 13021 xmlAutomataStatePtr start, end; 13022 13023 ret = 0; 13024 start = pctxt->state; 13025 end = xmlAutomataNewState(pctxt->am); 13026 13027 /* 13028 * iterate over the subtypes and remerge the end with an 13029 * epsilon transition 13030 */ 13031 if (particle->maxOccurs == 1) { 13032 sub = particle->children->children; 13033 while (sub != NULL) { 13034 pctxt->state = start; 13035 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13036 (xmlSchemaParticlePtr) sub); 13037 if (tmp2 == 1) ret = 1; 13038 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end); 13039 sub = sub->next; 13040 } 13041 } else { 13042 int counter; 13043 xmlAutomataStatePtr hop, base; 13044 int maxOccurs = particle->maxOccurs == UNBOUNDED ? 13045 UNBOUNDED : particle->maxOccurs - 1; 13046 int minOccurs = 13047 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1; 13048 13049 /* 13050 * use a counter to keep track of the number of transtions 13051 * which went through the choice. 13052 */ 13053 counter = 13054 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs); 13055 hop = xmlAutomataNewState(pctxt->am); 13056 base = xmlAutomataNewState(pctxt->am); 13057 13058 sub = particle->children->children; 13059 while (sub != NULL) { 13060 pctxt->state = base; 13061 tmp2 = xmlSchemaBuildAContentModel(pctxt, 13062 (xmlSchemaParticlePtr) sub); 13063 if (tmp2 == 1) ret = 1; 13064 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop); 13065 sub = sub->next; 13066 } 13067 xmlAutomataNewEpsilon(pctxt->am, start, base); 13068 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter); 13069 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter); 13070 if (ret == 1) 13071 xmlAutomataNewEpsilon(pctxt->am, base, end); 13072 } 13073 if (particle->minOccurs == 0) { 13074 xmlAutomataNewEpsilon(pctxt->am, start, end); 13075 ret = 1; 13076 } 13077 pctxt->state = end; 13078 break; 13079 } 13080 case XML_SCHEMA_TYPE_ALL:{ 13081 xmlAutomataStatePtr start, tmp; 13082 xmlSchemaParticlePtr sub; 13083 xmlSchemaElementPtr elemDecl; 13084 13085 ret = 1; 13086 13087 sub = (xmlSchemaParticlePtr) particle->children->children; 13088 if (sub == NULL) 13089 break; 13090 13091 ret = 0; 13092 13093 start = pctxt->state; 13094 tmp = xmlAutomataNewState(pctxt->am); 13095 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp); 13096 pctxt->state = tmp; 13097 while (sub != NULL) { 13098 pctxt->state = tmp; 13099 13100 elemDecl = (xmlSchemaElementPtr) sub->children; 13101 if (elemDecl == NULL) { 13102 PERROR_INT("xmlSchemaBuildAContentModel", 13103 "<element> particle has no term"); 13104 return(ret); 13105 }; 13106 /* 13107 * NOTE: The {max occurs} of all the particles in the 13108 * {particles} of the group must be 0 or 1; this is 13109 * already ensured during the parse of the content of 13110 * <all>. 13111 */ 13112 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) { 13113 int counter; 13114 13115 /* 13116 * This is an abstract group, we need to share 13117 * the same counter for all the element transitions 13118 * derived from the group 13119 */ 13120 counter = xmlAutomataNewCounter(pctxt->am, 13121 sub->minOccurs, sub->maxOccurs); 13122 xmlSchemaBuildContentModelForSubstGroup(pctxt, 13123 sub, counter, pctxt->state); 13124 } else { 13125 if ((sub->minOccurs == 1) && 13126 (sub->maxOccurs == 1)) { 13127 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state, 13128 pctxt->state, 13129 elemDecl->name, 13130 elemDecl->targetNamespace, 13131 1, 1, elemDecl); 13132 } else if ((sub->minOccurs == 0) && 13133 (sub->maxOccurs == 1)) { 13134 13135 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state, 13136 pctxt->state, 13137 elemDecl->name, 13138 elemDecl->targetNamespace, 13139 0, 13140 1, 13141 elemDecl); 13142 } 13143 } 13144 sub = (xmlSchemaParticlePtr) sub->next; 13145 } 13146 pctxt->state = 13147 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0); 13148 if (particle->minOccurs == 0) { 13149 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state); 13150 ret = 1; 13151 } 13152 break; 13153 } 13154 case XML_SCHEMA_TYPE_GROUP: 13155 /* 13156 * If we hit a model group definition, then this means that 13157 * it was empty, thus was not substituted for the containing 13158 * model group. Just do nothing in this case. 13159 * TODO: But the group should be substituted and not occur at 13160 * all in the content model at this point. Fix this. 13161 */ 13162 ret = 1; 13163 break; 13164 default: 13165 xmlSchemaInternalErr2(ACTXT_CAST pctxt, 13166 "xmlSchemaBuildAContentModel", 13167 "found unexpected term of type '%s' in content model", 13168 WXS_ITEM_TYPE_NAME(particle->children), NULL); 13169 return(ret); 13170 } 13171 return(ret); 13172 } 13173 13174 /** 13175 * xmlSchemaBuildContentModel: 13176 * @ctxt: the schema parser context 13177 * @type: the complex type definition 13178 * @name: the element name 13179 * 13180 * Builds the content model of the complex type. 13181 */ 13182 static void 13183 xmlSchemaBuildContentModel(xmlSchemaTypePtr type, 13184 xmlSchemaParserCtxtPtr ctxt) 13185 { 13186 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) || 13187 (type->contModel != NULL) || 13188 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) && 13189 (type->contentType != XML_SCHEMA_CONTENT_MIXED))) 13190 return; 13191 13192 #ifdef DEBUG_CONTENT 13193 xmlGenericError(xmlGenericErrorContext, 13194 "Building content model for %s\n", name); 13195 #endif 13196 ctxt->am = NULL; 13197 ctxt->am = xmlNewAutomata(); 13198 if (ctxt->am == NULL) { 13199 xmlGenericError(xmlGenericErrorContext, 13200 "Cannot create automata for complex type %s\n", type->name); 13201 return; 13202 } 13203 ctxt->state = xmlAutomataGetInitState(ctxt->am); 13204 /* 13205 * Build the automaton. 13206 */ 13207 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type)); 13208 xmlAutomataSetFinalState(ctxt->am, ctxt->state); 13209 type->contModel = xmlAutomataCompile(ctxt->am); 13210 if (type->contModel == NULL) { 13211 xmlSchemaPCustomErr(ctxt, 13212 XML_SCHEMAP_INTERNAL, 13213 WXS_BASIC_CAST type, type->node, 13214 "Failed to compile the content model", NULL); 13215 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) { 13216 xmlSchemaPCustomErr(ctxt, 13217 XML_SCHEMAP_NOT_DETERMINISTIC, 13218 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */ 13219 WXS_BASIC_CAST type, type->node, 13220 "The content model is not determinist", NULL); 13221 } else { 13222 #ifdef DEBUG_CONTENT_REGEXP 13223 xmlGenericError(xmlGenericErrorContext, 13224 "Content model of %s:\n", type->name); 13225 xmlRegexpPrint(stderr, type->contModel); 13226 #endif 13227 } 13228 ctxt->state = NULL; 13229 xmlFreeAutomata(ctxt->am); 13230 ctxt->am = NULL; 13231 } 13232 13233 /** 13234 * xmlSchemaResolveElementReferences: 13235 * @elem: the schema element context 13236 * @ctxt: the schema parser context 13237 * 13238 * Resolves the references of an element declaration 13239 * or particle, which has an element declaration as it's 13240 * term. 13241 */ 13242 static void 13243 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl, 13244 xmlSchemaParserCtxtPtr ctxt) 13245 { 13246 if ((ctxt == NULL) || (elemDecl == NULL) || 13247 ((elemDecl != NULL) && 13248 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED))) 13249 return; 13250 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED; 13251 13252 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) { 13253 xmlSchemaTypePtr type; 13254 13255 /* (type definition) ... otherwise the type definition `resolved` 13256 * to by the `actual value` of the type [attribute] ... 13257 */ 13258 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType, 13259 elemDecl->namedTypeNs); 13260 if (type == NULL) { 13261 xmlSchemaPResCompAttrErr(ctxt, 13262 XML_SCHEMAP_SRC_RESOLVE, 13263 WXS_BASIC_CAST elemDecl, elemDecl->node, 13264 "type", elemDecl->namedType, elemDecl->namedTypeNs, 13265 XML_SCHEMA_TYPE_BASIC, "type definition"); 13266 } else 13267 elemDecl->subtypes = type; 13268 } 13269 if (elemDecl->substGroup != NULL) { 13270 xmlSchemaElementPtr substHead; 13271 13272 /* 13273 * FIXME TODO: Do we need a new field in _xmlSchemaElement for 13274 * substitutionGroup? 13275 */ 13276 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup, 13277 elemDecl->substGroupNs); 13278 if (substHead == NULL) { 13279 xmlSchemaPResCompAttrErr(ctxt, 13280 XML_SCHEMAP_SRC_RESOLVE, 13281 WXS_BASIC_CAST elemDecl, NULL, 13282 "substitutionGroup", elemDecl->substGroup, 13283 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL); 13284 } else { 13285 xmlSchemaResolveElementReferences(substHead, ctxt); 13286 /* 13287 * Set the "substitution group affiliation". 13288 * NOTE that now we use the "refDecl" field for this. 13289 */ 13290 WXS_SUBST_HEAD(elemDecl) = substHead; 13291 /* 13292 * The type definitions is set to: 13293 * SPEC "...the {type definition} of the element 13294 * declaration `resolved` to by the `actual value` 13295 * of the substitutionGroup [attribute], if present" 13296 */ 13297 if (elemDecl->subtypes == NULL) 13298 elemDecl->subtypes = substHead->subtypes; 13299 } 13300 } 13301 /* 13302 * SPEC "The definition of anyType serves as the default type definition 13303 * for element declarations whose XML representation does not specify one." 13304 */ 13305 if ((elemDecl->subtypes == NULL) && 13306 (elemDecl->namedType == NULL) && 13307 (elemDecl->substGroup == NULL)) 13308 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE); 13309 } 13310 13311 /** 13312 * xmlSchemaResolveUnionMemberTypes: 13313 * @ctxt: the schema parser context 13314 * @type: the schema simple type definition 13315 * 13316 * Checks and builds the "member type definitions" property of the union 13317 * simple type. This handles part (1), part (2) is done in 13318 * xmlSchemaFinishMemberTypeDefinitionsProperty() 13319 * 13320 * Returns -1 in case of an internal error, 0 otherwise. 13321 */ 13322 static int 13323 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt, 13324 xmlSchemaTypePtr type) 13325 { 13326 13327 xmlSchemaTypeLinkPtr link, lastLink, newLink; 13328 xmlSchemaTypePtr memberType; 13329 13330 /* 13331 * SPEC (1) "If the <union> alternative is chosen, then [Definition:] 13332 * define the explicit members as the type definitions `resolved` 13333 * to by the items in the `actual value` of the memberTypes [attribute], 13334 * if any, followed by the type definitions corresponding to the 13335 * <simpleType>s among the [children] of <union>, if any." 13336 */ 13337 /* 13338 * Resolve references. 13339 */ 13340 link = type->memberTypes; 13341 lastLink = NULL; 13342 while (link != NULL) { 13343 const xmlChar *name, *nsName; 13344 13345 name = ((xmlSchemaQNameRefPtr) link->type)->name; 13346 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace; 13347 13348 memberType = xmlSchemaGetType(ctxt->schema, name, nsName); 13349 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) { 13350 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 13351 WXS_BASIC_CAST type, type->node, "memberTypes", 13352 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL); 13353 /* 13354 * Remove the member type link. 13355 */ 13356 if (lastLink == NULL) 13357 type->memberTypes = link->next; 13358 else 13359 lastLink->next = link->next; 13360 newLink = link; 13361 link = link->next; 13362 xmlFree(newLink); 13363 } else { 13364 link->type = memberType; 13365 lastLink = link; 13366 link = link->next; 13367 } 13368 } 13369 /* 13370 * Add local simple types, 13371 */ 13372 memberType = type->subtypes; 13373 while (memberType != NULL) { 13374 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink)); 13375 if (link == NULL) { 13376 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL); 13377 return (-1); 13378 } 13379 link->type = memberType; 13380 link->next = NULL; 13381 if (lastLink == NULL) 13382 type->memberTypes = link; 13383 else 13384 lastLink->next = link; 13385 lastLink = link; 13386 memberType = memberType->next; 13387 } 13388 return (0); 13389 } 13390 13391 /** 13392 * xmlSchemaIsDerivedFromBuiltInType: 13393 * @ctxt: the schema parser context 13394 * @type: the type definition 13395 * @valType: the value type 13396 * 13397 * 13398 * Returns 1 if the type has the given value type, or 13399 * is derived from such a type. 13400 */ 13401 static int 13402 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13403 { 13404 if (type == NULL) 13405 return (0); 13406 if (WXS_IS_COMPLEX(type)) 13407 return (0); 13408 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13409 if (type->builtInType == valType) 13410 return(1); 13411 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13412 (type->builtInType == XML_SCHEMAS_ANYTYPE)) 13413 return (0); 13414 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13415 } 13416 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13417 } 13418 13419 #if 0 13420 /** 13421 * xmlSchemaIsDerivedFromBuiltInType: 13422 * @ctxt: the schema parser context 13423 * @type: the type definition 13424 * @valType: the value type 13425 * 13426 * 13427 * Returns 1 if the type has the given value type, or 13428 * is derived from such a type. 13429 */ 13430 static int 13431 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType) 13432 { 13433 if (type == NULL) 13434 return (0); 13435 if (WXS_IS_COMPLEX(type)) 13436 return (0); 13437 if (type->type == XML_SCHEMA_TYPE_BASIC) { 13438 if (type->builtInType == valType) 13439 return(1); 13440 return (0); 13441 } else 13442 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType)); 13443 13444 return (0); 13445 } 13446 13447 static xmlSchemaTypePtr 13448 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type) 13449 { 13450 if (type == NULL) 13451 return (NULL); 13452 if (WXS_IS_COMPLEX(type)) 13453 return (NULL); 13454 if (type->type == XML_SCHEMA_TYPE_BASIC) 13455 return(type); 13456 return(xmlSchemaQueryBuiltInType(type->subtypes)); 13457 } 13458 #endif 13459 13460 /** 13461 * xmlSchemaGetPrimitiveType: 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 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type) 13469 { 13470 13471 while (type != NULL) { 13472 /* 13473 * Note that anySimpleType is actually not a primitive type 13474 * but we need that here. 13475 */ 13476 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) || 13477 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE)) 13478 return (type); 13479 type = type->baseType; 13480 } 13481 13482 return (NULL); 13483 } 13484 13485 #if 0 13486 /** 13487 * xmlSchemaGetBuiltInTypeAncestor: 13488 * @type: the simpleType definition 13489 * 13490 * Returns the primitive type of the given type or 13491 * NULL in case of error. 13492 */ 13493 static xmlSchemaTypePtr 13494 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type) 13495 { 13496 if (WXS_IS_LIST(type) || WXS_IS_UNION(type)) 13497 return (0); 13498 while (type != NULL) { 13499 if (type->type == XML_SCHEMA_TYPE_BASIC) 13500 return (type); 13501 type = type->baseType; 13502 } 13503 13504 return (NULL); 13505 } 13506 #endif 13507 13508 /** 13509 * xmlSchemaCloneWildcardNsConstraints: 13510 * @ctxt: the schema parser context 13511 * @dest: the destination wildcard 13512 * @source: the source wildcard 13513 * 13514 * Clones the namespace constraints of source 13515 * and assignes them to dest. 13516 * Returns -1 on internal error, 0 otherwise. 13517 */ 13518 static int 13519 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, 13520 xmlSchemaWildcardPtr dest, 13521 xmlSchemaWildcardPtr source) 13522 { 13523 xmlSchemaWildcardNsPtr cur, tmp, last; 13524 13525 if ((source == NULL) || (dest == NULL)) 13526 return(-1); 13527 dest->any = source->any; 13528 cur = source->nsSet; 13529 last = NULL; 13530 while (cur != NULL) { 13531 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13532 if (tmp == NULL) 13533 return(-1); 13534 tmp->value = cur->value; 13535 if (last == NULL) 13536 dest->nsSet = tmp; 13537 else 13538 last->next = tmp; 13539 last = tmp; 13540 cur = cur->next; 13541 } 13542 if (dest->negNsSet != NULL) 13543 xmlSchemaFreeWildcardNsSet(dest->negNsSet); 13544 if (source->negNsSet != NULL) { 13545 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13546 if (dest->negNsSet == NULL) 13547 return(-1); 13548 dest->negNsSet->value = source->negNsSet->value; 13549 } else 13550 dest->negNsSet = NULL; 13551 return(0); 13552 } 13553 13554 /** 13555 * xmlSchemaUnionWildcards: 13556 * @ctxt: the schema parser context 13557 * @completeWild: the first wildcard 13558 * @curWild: the second wildcard 13559 * 13560 * Unions the namespace constraints of the given wildcards. 13561 * @completeWild will hold the resulting union. 13562 * Returns a positive error code on failure, -1 in case of an 13563 * internal error, 0 otherwise. 13564 */ 13565 static int 13566 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, 13567 xmlSchemaWildcardPtr completeWild, 13568 xmlSchemaWildcardPtr curWild) 13569 { 13570 xmlSchemaWildcardNsPtr cur, curB, tmp; 13571 13572 /* 13573 * 1 If O1 and O2 are the same value, then that value must be the 13574 * value. 13575 */ 13576 if ((completeWild->any == curWild->any) && 13577 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13578 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13579 13580 if ((completeWild->negNsSet == NULL) || 13581 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13582 13583 if (completeWild->nsSet != NULL) { 13584 int found = 0; 13585 13586 /* 13587 * Check equality of sets. 13588 */ 13589 cur = completeWild->nsSet; 13590 while (cur != NULL) { 13591 found = 0; 13592 curB = curWild->nsSet; 13593 while (curB != NULL) { 13594 if (cur->value == curB->value) { 13595 found = 1; 13596 break; 13597 } 13598 curB = curB->next; 13599 } 13600 if (!found) 13601 break; 13602 cur = cur->next; 13603 } 13604 if (found) 13605 return(0); 13606 } else 13607 return(0); 13608 } 13609 } 13610 /* 13611 * 2 If either O1 or O2 is any, then any must be the value 13612 */ 13613 if (completeWild->any != curWild->any) { 13614 if (completeWild->any == 0) { 13615 completeWild->any = 1; 13616 if (completeWild->nsSet != NULL) { 13617 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13618 completeWild->nsSet = NULL; 13619 } 13620 if (completeWild->negNsSet != NULL) { 13621 xmlFree(completeWild->negNsSet); 13622 completeWild->negNsSet = NULL; 13623 } 13624 } 13625 return (0); 13626 } 13627 /* 13628 * 3 If both O1 and O2 are sets of (namespace names or `absent`), 13629 * then the union of those sets must be the value. 13630 */ 13631 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13632 int found; 13633 xmlSchemaWildcardNsPtr start; 13634 13635 cur = curWild->nsSet; 13636 start = completeWild->nsSet; 13637 while (cur != NULL) { 13638 found = 0; 13639 curB = start; 13640 while (curB != NULL) { 13641 if (cur->value == curB->value) { 13642 found = 1; 13643 break; 13644 } 13645 curB = curB->next; 13646 } 13647 if (!found) { 13648 tmp = xmlSchemaNewWildcardNsConstraint(ctxt); 13649 if (tmp == NULL) 13650 return (-1); 13651 tmp->value = cur->value; 13652 tmp->next = completeWild->nsSet; 13653 completeWild->nsSet = tmp; 13654 } 13655 cur = cur->next; 13656 } 13657 13658 return(0); 13659 } 13660 /* 13661 * 4 If the two are negations of different values (namespace names 13662 * or `absent`), then a pair of not and `absent` must be the value. 13663 */ 13664 if ((completeWild->negNsSet != NULL) && 13665 (curWild->negNsSet != NULL) && 13666 (completeWild->negNsSet->value != curWild->negNsSet->value)) { 13667 completeWild->negNsSet->value = NULL; 13668 13669 return(0); 13670 } 13671 /* 13672 * 5. 13673 */ 13674 if (((completeWild->negNsSet != NULL) && 13675 (completeWild->negNsSet->value != NULL) && 13676 (curWild->nsSet != NULL)) || 13677 ((curWild->negNsSet != NULL) && 13678 (curWild->negNsSet->value != NULL) && 13679 (completeWild->nsSet != NULL))) { 13680 13681 int nsFound, absentFound = 0; 13682 13683 if (completeWild->nsSet != NULL) { 13684 cur = completeWild->nsSet; 13685 curB = curWild->negNsSet; 13686 } else { 13687 cur = curWild->nsSet; 13688 curB = completeWild->negNsSet; 13689 } 13690 nsFound = 0; 13691 while (cur != NULL) { 13692 if (cur->value == NULL) 13693 absentFound = 1; 13694 else if (cur->value == curB->value) 13695 nsFound = 1; 13696 if (nsFound && absentFound) 13697 break; 13698 cur = cur->next; 13699 } 13700 13701 if (nsFound && absentFound) { 13702 /* 13703 * 5.1 If the set S includes both the negated namespace 13704 * name and `absent`, then any must be the value. 13705 */ 13706 completeWild->any = 1; 13707 if (completeWild->nsSet != NULL) { 13708 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13709 completeWild->nsSet = NULL; 13710 } 13711 if (completeWild->negNsSet != NULL) { 13712 xmlFree(completeWild->negNsSet); 13713 completeWild->negNsSet = NULL; 13714 } 13715 } else if (nsFound && (!absentFound)) { 13716 /* 13717 * 5.2 If the set S includes the negated namespace name 13718 * but not `absent`, then a pair of not and `absent` must 13719 * be the value. 13720 */ 13721 if (completeWild->nsSet != NULL) { 13722 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13723 completeWild->nsSet = NULL; 13724 } 13725 if (completeWild->negNsSet == NULL) { 13726 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13727 if (completeWild->negNsSet == NULL) 13728 return (-1); 13729 } 13730 completeWild->negNsSet->value = NULL; 13731 } else if ((!nsFound) && absentFound) { 13732 /* 13733 * 5.3 If the set S includes `absent` but not the negated 13734 * namespace name, then the union is not expressible. 13735 */ 13736 xmlSchemaPErr(ctxt, completeWild->node, 13737 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, 13738 "The union of the wilcard is not expressible.\n", 13739 NULL, NULL); 13740 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); 13741 } else if ((!nsFound) && (!absentFound)) { 13742 /* 13743 * 5.4 If the set S does not include either the negated namespace 13744 * name or `absent`, then whichever of O1 or O2 is a pair of not 13745 * and a namespace name must be the value. 13746 */ 13747 if (completeWild->negNsSet == NULL) { 13748 if (completeWild->nsSet != NULL) { 13749 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13750 completeWild->nsSet = NULL; 13751 } 13752 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13753 if (completeWild->negNsSet == NULL) 13754 return (-1); 13755 completeWild->negNsSet->value = curWild->negNsSet->value; 13756 } 13757 } 13758 return (0); 13759 } 13760 /* 13761 * 6. 13762 */ 13763 if (((completeWild->negNsSet != NULL) && 13764 (completeWild->negNsSet->value == NULL) && 13765 (curWild->nsSet != NULL)) || 13766 ((curWild->negNsSet != NULL) && 13767 (curWild->negNsSet->value == NULL) && 13768 (completeWild->nsSet != NULL))) { 13769 13770 if (completeWild->nsSet != NULL) { 13771 cur = completeWild->nsSet; 13772 } else { 13773 cur = curWild->nsSet; 13774 } 13775 while (cur != NULL) { 13776 if (cur->value == NULL) { 13777 /* 13778 * 6.1 If the set S includes `absent`, then any must be the 13779 * value. 13780 */ 13781 completeWild->any = 1; 13782 if (completeWild->nsSet != NULL) { 13783 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13784 completeWild->nsSet = NULL; 13785 } 13786 if (completeWild->negNsSet != NULL) { 13787 xmlFree(completeWild->negNsSet); 13788 completeWild->negNsSet = NULL; 13789 } 13790 return (0); 13791 } 13792 cur = cur->next; 13793 } 13794 if (completeWild->negNsSet == NULL) { 13795 /* 13796 * 6.2 If the set S does not include `absent`, then a pair of not 13797 * and `absent` must be the value. 13798 */ 13799 if (completeWild->nsSet != NULL) { 13800 xmlSchemaFreeWildcardNsSet(completeWild->nsSet); 13801 completeWild->nsSet = NULL; 13802 } 13803 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt); 13804 if (completeWild->negNsSet == NULL) 13805 return (-1); 13806 completeWild->negNsSet->value = NULL; 13807 } 13808 return (0); 13809 } 13810 return (0); 13811 13812 } 13813 13814 /** 13815 * xmlSchemaIntersectWildcards: 13816 * @ctxt: the schema parser context 13817 * @completeWild: the first wildcard 13818 * @curWild: the second wildcard 13819 * 13820 * Intersects the namespace constraints of the given wildcards. 13821 * @completeWild will hold the resulting intersection. 13822 * Returns a positive error code on failure, -1 in case of an 13823 * internal error, 0 otherwise. 13824 */ 13825 static int 13826 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, 13827 xmlSchemaWildcardPtr completeWild, 13828 xmlSchemaWildcardPtr curWild) 13829 { 13830 xmlSchemaWildcardNsPtr cur, curB, prev, tmp; 13831 13832 /* 13833 * 1 If O1 and O2 are the same value, then that value must be the 13834 * value. 13835 */ 13836 if ((completeWild->any == curWild->any) && 13837 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) && 13838 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) { 13839 13840 if ((completeWild->negNsSet == NULL) || 13841 (completeWild->negNsSet->value == curWild->negNsSet->value)) { 13842 13843 if (completeWild->nsSet != NULL) { 13844 int found = 0; 13845 13846 /* 13847 * Check equality of sets. 13848 */ 13849 cur = completeWild->nsSet; 13850 while (cur != NULL) { 13851 found = 0; 13852 curB = curWild->nsSet; 13853 while (curB != NULL) { 13854 if (cur->value == curB->value) { 13855 found = 1; 13856 break; 13857 } 13858 curB = curB->next; 13859 } 13860 if (!found) 13861 break; 13862 cur = cur->next; 13863 } 13864 if (found) 13865 return(0); 13866 } else 13867 return(0); 13868 } 13869 } 13870 /* 13871 * 2 If either O1 or O2 is any, then the other must be the value. 13872 */ 13873 if ((completeWild->any != curWild->any) && (completeWild->any)) { 13874 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13875 return(-1); 13876 return(0); 13877 } 13878 /* 13879 * 3 If either O1 or O2 is a pair of not and a value (a namespace 13880 * name or `absent`) and the other is a set of (namespace names or 13881 * `absent`), then that set, minus the negated value if it was in 13882 * the set, minus `absent` if it was in the set, must be the value. 13883 */ 13884 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) || 13885 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) { 13886 const xmlChar *neg; 13887 13888 if (completeWild->nsSet == NULL) { 13889 neg = completeWild->negNsSet->value; 13890 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1) 13891 return(-1); 13892 } else 13893 neg = curWild->negNsSet->value; 13894 /* 13895 * Remove absent and negated. 13896 */ 13897 prev = NULL; 13898 cur = completeWild->nsSet; 13899 while (cur != NULL) { 13900 if (cur->value == NULL) { 13901 if (prev == NULL) 13902 completeWild->nsSet = cur->next; 13903 else 13904 prev->next = cur->next; 13905 xmlFree(cur); 13906 break; 13907 } 13908 prev = cur; 13909 cur = cur->next; 13910 } 13911 if (neg != NULL) { 13912 prev = NULL; 13913 cur = completeWild->nsSet; 13914 while (cur != NULL) { 13915 if (cur->value == neg) { 13916 if (prev == NULL) 13917 completeWild->nsSet = cur->next; 13918 else 13919 prev->next = cur->next; 13920 xmlFree(cur); 13921 break; 13922 } 13923 prev = cur; 13924 cur = cur->next; 13925 } 13926 } 13927 13928 return(0); 13929 } 13930 /* 13931 * 4 If both O1 and O2 are sets of (namespace names or `absent`), 13932 * then the intersection of those sets must be the value. 13933 */ 13934 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) { 13935 int found; 13936 13937 cur = completeWild->nsSet; 13938 prev = NULL; 13939 while (cur != NULL) { 13940 found = 0; 13941 curB = curWild->nsSet; 13942 while (curB != NULL) { 13943 if (cur->value == curB->value) { 13944 found = 1; 13945 break; 13946 } 13947 curB = curB->next; 13948 } 13949 if (!found) { 13950 if (prev == NULL) 13951 completeWild->nsSet = cur->next; 13952 else 13953 prev->next = cur->next; 13954 tmp = cur->next; 13955 xmlFree(cur); 13956 cur = tmp; 13957 continue; 13958 } 13959 prev = cur; 13960 cur = cur->next; 13961 } 13962 13963 return(0); 13964 } 13965 /* 5 If the two are negations of different namespace names, 13966 * then the intersection is not expressible 13967 */ 13968 if ((completeWild->negNsSet != NULL) && 13969 (curWild->negNsSet != NULL) && 13970 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13971 (completeWild->negNsSet->value != NULL) && 13972 (curWild->negNsSet->value != NULL)) { 13973 13974 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, 13975 "The intersection of the wilcard is not expressible.\n", 13976 NULL, NULL); 13977 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); 13978 } 13979 /* 13980 * 6 If the one is a negation of a namespace name and the other 13981 * is a negation of `absent`, then the one which is the negation 13982 * of a namespace name must be the value. 13983 */ 13984 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) && 13985 (completeWild->negNsSet->value != curWild->negNsSet->value) && 13986 (completeWild->negNsSet->value == NULL)) { 13987 completeWild->negNsSet->value = curWild->negNsSet->value; 13988 } 13989 return(0); 13990 } 13991 13992 /** 13993 * xmlSchemaIsWildcardNsConstraintSubset: 13994 * @ctxt: the schema parser context 13995 * @sub: the first wildcard 13996 * @super: the second wildcard 13997 * 13998 * Schema Component Constraint: Wildcard Subset (cos-ns-subset) 13999 * 14000 * Returns 0 if the namespace constraint of @sub is an intensional 14001 * subset of @super, 1 otherwise. 14002 */ 14003 static int 14004 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub, 14005 xmlSchemaWildcardPtr super) 14006 { 14007 /* 14008 * 1 super must be any. 14009 */ 14010 if (super->any) 14011 return (0); 14012 /* 14013 * 2.1 sub must be a pair of not and a namespace name or `absent`. 14014 * 2.2 super must be a pair of not and the same value. 14015 */ 14016 if ((sub->negNsSet != NULL) && 14017 (super->negNsSet != NULL) && 14018 (sub->negNsSet->value == super->negNsSet->value)) 14019 return (0); 14020 /* 14021 * 3.1 sub must be a set whose members are either namespace names or `absent`. 14022 */ 14023 if (sub->nsSet != NULL) { 14024 /* 14025 * 3.2.1 super must be the same set or a superset thereof. 14026 */ 14027 if (super->nsSet != NULL) { 14028 xmlSchemaWildcardNsPtr cur, curB; 14029 int found = 0; 14030 14031 cur = sub->nsSet; 14032 while (cur != NULL) { 14033 found = 0; 14034 curB = super->nsSet; 14035 while (curB != NULL) { 14036 if (cur->value == curB->value) { 14037 found = 1; 14038 break; 14039 } 14040 curB = curB->next; 14041 } 14042 if (!found) 14043 return (1); 14044 cur = cur->next; 14045 } 14046 if (found) 14047 return (0); 14048 } else if (super->negNsSet != NULL) { 14049 xmlSchemaWildcardNsPtr cur; 14050 /* 14051 * 3.2.2 super must be a pair of not and a namespace name or 14052 * `absent` and that value must not be in sub's set. 14053 */ 14054 cur = sub->nsSet; 14055 while (cur != NULL) { 14056 if (cur->value == super->negNsSet->value) 14057 return (1); 14058 cur = cur->next; 14059 } 14060 return (0); 14061 } 14062 } 14063 return (1); 14064 } 14065 14066 static int 14067 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse, 14068 int *fixed, 14069 const xmlChar **value, 14070 xmlSchemaValPtr *val) 14071 { 14072 *fixed = 0; 14073 *value = NULL; 14074 if (val != 0) 14075 *val = NULL; 14076 14077 if (attruse->defValue != NULL) { 14078 *value = attruse->defValue; 14079 if (val != NULL) 14080 *val = attruse->defVal; 14081 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED) 14082 *fixed = 1; 14083 return(1); 14084 } else if ((attruse->attrDecl != NULL) && 14085 (attruse->attrDecl->defValue != NULL)) { 14086 *value = attruse->attrDecl->defValue; 14087 if (val != NULL) 14088 *val = attruse->attrDecl->defVal; 14089 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED) 14090 *fixed = 1; 14091 return(1); 14092 } 14093 return(0); 14094 } 14095 /** 14096 * xmlSchemaCheckCVCWildcardNamespace: 14097 * @wild: the wildcard 14098 * @ns: the namespace 14099 * 14100 * Validation Rule: Wildcard allows Namespace Name 14101 * (cvc-wildcard-namespace) 14102 * 14103 * Returns 0 if the given namespace matches the wildcard, 14104 * 1 otherwise and -1 on API errors. 14105 */ 14106 static int 14107 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild, 14108 const xmlChar* ns) 14109 { 14110 if (wild == NULL) 14111 return(-1); 14112 14113 if (wild->any) 14114 return(0); 14115 else if (wild->nsSet != NULL) { 14116 xmlSchemaWildcardNsPtr cur; 14117 14118 cur = wild->nsSet; 14119 while (cur != NULL) { 14120 if (xmlStrEqual(cur->value, ns)) 14121 return(0); 14122 cur = cur->next; 14123 } 14124 } else if ((wild->negNsSet != NULL) && (ns != NULL) && 14125 (!xmlStrEqual(wild->negNsSet->value, ns))) 14126 return(0); 14127 14128 return(1); 14129 } 14130 14131 #define XML_SCHEMA_ACTION_DERIVE 0 14132 #define XML_SCHEMA_ACTION_REDEFINE 1 14133 14134 #define WXS_ACTION_STR(a) \ 14135 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined" 14136 14137 /* 14138 * Schema Component Constraint: 14139 * Derivation Valid (Restriction, Complex) 14140 * derivation-ok-restriction (2) - (4) 14141 * 14142 * ATTENTION: 14143 * In XML Schema 1.1 this will be: 14144 * Validation Rule: 14145 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3) 14146 * 14147 */ 14148 static int 14149 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt, 14150 int action, 14151 xmlSchemaBasicItemPtr item, 14152 xmlSchemaBasicItemPtr baseItem, 14153 xmlSchemaItemListPtr uses, 14154 xmlSchemaItemListPtr baseUses, 14155 xmlSchemaWildcardPtr wild, 14156 xmlSchemaWildcardPtr baseWild) 14157 { 14158 xmlSchemaAttributeUsePtr cur = NULL, bcur; 14159 int i, j, found; /* err = 0; */ 14160 const xmlChar *bEffValue; 14161 int effFixed; 14162 14163 if (uses != NULL) { 14164 for (i = 0; i < uses->nbItems; i++) { 14165 cur = uses->items[i]; 14166 found = 0; 14167 if (baseUses == NULL) 14168 goto not_found; 14169 for (j = 0; j < baseUses->nbItems; j++) { 14170 bcur = baseUses->items[j]; 14171 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14172 WXS_ATTRUSE_DECL_NAME(bcur)) && 14173 (WXS_ATTRUSE_DECL_TNS(cur) == 14174 WXS_ATTRUSE_DECL_TNS(bcur))) 14175 { 14176 /* 14177 * (2.1) "If there is an attribute use in the {attribute 14178 * uses} of the {base type definition} (call this B) whose 14179 * {attribute declaration} has the same {name} and {target 14180 * namespace}, then all of the following must be true:" 14181 */ 14182 found = 1; 14183 14184 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) && 14185 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED)) 14186 { 14187 xmlChar *str = NULL; 14188 /* 14189 * (2.1.1) "one of the following must be true:" 14190 * (2.1.1.1) "B's {required} is false." 14191 * (2.1.1.2) "R's {required} is true." 14192 */ 14193 xmlSchemaPAttrUseErr4(pctxt, 14194 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, 14195 WXS_ITEM_NODE(item), item, cur, 14196 "The 'optional' attribute use is inconsistent " 14197 "with the corresponding 'required' attribute use of " 14198 "the %s %s", 14199 WXS_ACTION_STR(action), 14200 xmlSchemaGetComponentDesignation(&str, baseItem), 14201 NULL, NULL); 14202 FREE_AND_NULL(str); 14203 /* err = pctxt->err; */ 14204 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 14205 WXS_ATTRUSE_TYPEDEF(cur), 14206 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0) 14207 { 14208 xmlChar *strA = NULL, *strB = NULL, *strC = NULL; 14209 14210 /* 14211 * SPEC (2.1.2) "R's {attribute declaration}'s 14212 * {type definition} must be validly derived from 14213 * B's {type definition} given the empty set as 14214 * defined in Type Derivation OK (Simple) ($3.14.6)." 14215 */ 14216 xmlSchemaPAttrUseErr4(pctxt, 14217 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, 14218 WXS_ITEM_NODE(item), item, cur, 14219 "The attribute declaration's %s " 14220 "is not validly derived from " 14221 "the corresponding %s of the " 14222 "attribute declaration in the %s %s", 14223 xmlSchemaGetComponentDesignation(&strA, 14224 WXS_ATTRUSE_TYPEDEF(cur)), 14225 xmlSchemaGetComponentDesignation(&strB, 14226 WXS_ATTRUSE_TYPEDEF(bcur)), 14227 WXS_ACTION_STR(action), 14228 xmlSchemaGetComponentDesignation(&strC, baseItem)); 14229 /* xmlSchemaGetComponentDesignation(&str, baseItem), */ 14230 FREE_AND_NULL(strA); 14231 FREE_AND_NULL(strB); 14232 FREE_AND_NULL(strC); 14233 /* err = pctxt->err; */ 14234 } else { 14235 /* 14236 * 2.1.3 [Definition:] Let the effective value 14237 * constraint of an attribute use be its {value 14238 * constraint}, if present, otherwise its {attribute 14239 * declaration}'s {value constraint} . 14240 */ 14241 xmlSchemaGetEffectiveValueConstraint(bcur, 14242 &effFixed, &bEffValue, NULL); 14243 /* 14244 * 2.1.3 ... one of the following must be true 14245 * 14246 * 2.1.3.1 B's `effective value constraint` is 14247 * `absent` or default. 14248 */ 14249 if ((bEffValue != NULL) && 14250 (effFixed == 1)) { 14251 const xmlChar *rEffValue = NULL; 14252 14253 xmlSchemaGetEffectiveValueConstraint(bcur, 14254 &effFixed, &rEffValue, NULL); 14255 /* 14256 * 2.1.3.2 R's `effective value constraint` is 14257 * fixed with the same string as B's. 14258 * MAYBE TODO: Compare the computed values. 14259 * Hmm, it says "same string" so 14260 * string-equality might really be sufficient. 14261 */ 14262 if ((effFixed == 0) || 14263 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue))) 14264 { 14265 xmlChar *str = NULL; 14266 14267 xmlSchemaPAttrUseErr4(pctxt, 14268 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, 14269 WXS_ITEM_NODE(item), item, cur, 14270 "The effective value constraint of the " 14271 "attribute use is inconsistent with " 14272 "its correspondent in the %s %s", 14273 WXS_ACTION_STR(action), 14274 xmlSchemaGetComponentDesignation(&str, 14275 baseItem), 14276 NULL, NULL); 14277 FREE_AND_NULL(str); 14278 /* err = pctxt->err; */ 14279 } 14280 } 14281 } 14282 break; 14283 } 14284 } 14285 not_found: 14286 if (!found) { 14287 /* 14288 * (2.2) "otherwise the {base type definition} must have an 14289 * {attribute wildcard} and the {target namespace} of the 14290 * R's {attribute declaration} must be `valid` with respect 14291 * to that wildcard, as defined in Wildcard allows Namespace 14292 * Name ($3.10.4)." 14293 */ 14294 if ((baseWild == NULL) || 14295 (xmlSchemaCheckCVCWildcardNamespace(baseWild, 14296 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0)) 14297 { 14298 xmlChar *str = NULL; 14299 14300 xmlSchemaPAttrUseErr4(pctxt, 14301 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, 14302 WXS_ITEM_NODE(item), item, cur, 14303 "Neither a matching attribute use, " 14304 "nor a matching wildcard exists in the %s %s", 14305 WXS_ACTION_STR(action), 14306 xmlSchemaGetComponentDesignation(&str, baseItem), 14307 NULL, NULL); 14308 FREE_AND_NULL(str); 14309 /* err = pctxt->err; */ 14310 } 14311 } 14312 } 14313 } 14314 /* 14315 * SPEC derivation-ok-restriction (3): 14316 * (3) "For each attribute use in the {attribute uses} of the {base type 14317 * definition} whose {required} is true, there must be an attribute 14318 * use with an {attribute declaration} with the same {name} and 14319 * {target namespace} as its {attribute declaration} in the {attribute 14320 * uses} of the complex type definition itself whose {required} is true. 14321 */ 14322 if (baseUses != NULL) { 14323 for (j = 0; j < baseUses->nbItems; j++) { 14324 bcur = baseUses->items[j]; 14325 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED) 14326 continue; 14327 found = 0; 14328 if (uses != NULL) { 14329 for (i = 0; i < uses->nbItems; i++) { 14330 cur = uses->items[i]; 14331 if ((WXS_ATTRUSE_DECL_NAME(cur) == 14332 WXS_ATTRUSE_DECL_NAME(bcur)) && 14333 (WXS_ATTRUSE_DECL_TNS(cur) == 14334 WXS_ATTRUSE_DECL_TNS(bcur))) { 14335 found = 1; 14336 break; 14337 } 14338 } 14339 } 14340 if (!found) { 14341 xmlChar *strA = NULL, *strB = NULL; 14342 14343 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14344 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, 14345 NULL, item, 14346 "A matching attribute use for the " 14347 "'required' %s of the %s %s is missing", 14348 xmlSchemaGetComponentDesignation(&strA, bcur), 14349 WXS_ACTION_STR(action), 14350 xmlSchemaGetComponentDesignation(&strB, baseItem), 14351 NULL); 14352 FREE_AND_NULL(strA); 14353 FREE_AND_NULL(strB); 14354 } 14355 } 14356 } 14357 /* 14358 * derivation-ok-restriction (4) 14359 */ 14360 if (wild != NULL) { 14361 /* 14362 * (4) "If there is an {attribute wildcard}, all of the 14363 * following must be true:" 14364 */ 14365 if (baseWild == NULL) { 14366 xmlChar *str = NULL; 14367 14368 /* 14369 * (4.1) "The {base type definition} must also have one." 14370 */ 14371 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14372 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, 14373 NULL, item, 14374 "The %s has an attribute wildcard, " 14375 "but the %s %s '%s' does not have one", 14376 WXS_ITEM_TYPE_NAME(item), 14377 WXS_ACTION_STR(action), 14378 WXS_ITEM_TYPE_NAME(baseItem), 14379 xmlSchemaGetComponentQName(&str, baseItem)); 14380 FREE_AND_NULL(str); 14381 return(pctxt->err); 14382 } else if ((baseWild->any == 0) && 14383 xmlSchemaCheckCOSNSSubset(wild, baseWild)) 14384 { 14385 xmlChar *str = NULL; 14386 /* 14387 * (4.2) "The complex type definition's {attribute wildcard}'s 14388 * {namespace constraint} must be a subset of the {base type 14389 * definition}'s {attribute wildcard}'s {namespace constraint}, 14390 * as defined by Wildcard Subset ($3.10.6)." 14391 */ 14392 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14393 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, 14394 NULL, item, 14395 "The attribute wildcard is not a valid " 14396 "subset of the wildcard in the %s %s '%s'", 14397 WXS_ACTION_STR(action), 14398 WXS_ITEM_TYPE_NAME(baseItem), 14399 xmlSchemaGetComponentQName(&str, baseItem), 14400 NULL); 14401 FREE_AND_NULL(str); 14402 return(pctxt->err); 14403 } 14404 /* 4.3 Unless the {base type definition} is the `ur-type 14405 * definition`, the complex type definition's {attribute 14406 * wildcard}'s {process contents} must be identical to or 14407 * stronger than the {base type definition}'s {attribute 14408 * wildcard}'s {process contents}, where strict is stronger 14409 * than lax is stronger than skip. 14410 */ 14411 if ((! WXS_IS_ANYTYPE(baseItem)) && 14412 (wild->processContents < baseWild->processContents)) { 14413 xmlChar *str = NULL; 14414 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 14415 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, 14416 NULL, baseItem, 14417 "The {process contents} of the attribute wildcard is " 14418 "weaker than the one in the %s %s '%s'", 14419 WXS_ACTION_STR(action), 14420 WXS_ITEM_TYPE_NAME(baseItem), 14421 xmlSchemaGetComponentQName(&str, baseItem), 14422 NULL); 14423 FREE_AND_NULL(str) 14424 return(pctxt->err); 14425 } 14426 } 14427 return(0); 14428 } 14429 14430 14431 static int 14432 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt, 14433 xmlSchemaBasicItemPtr item, 14434 xmlSchemaWildcardPtr *completeWild, 14435 xmlSchemaItemListPtr list, 14436 xmlSchemaItemListPtr prohibs); 14437 /** 14438 * xmlSchemaFixupTypeAttributeUses: 14439 * @ctxt: the schema parser context 14440 * @type: the complex type definition 14441 * 14442 * 14443 * Builds the wildcard and the attribute uses on the given complex type. 14444 * Returns -1 if an internal error occurs, 0 otherwise. 14445 * 14446 * ATTENTION TODO: Experimantally this uses pointer comparisons for 14447 * strings, so recheck this if we start to hardcode some schemata, since 14448 * they might not be in the same dict. 14449 * NOTE: It is allowed to "extend" the xs:anyType type. 14450 */ 14451 static int 14452 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt, 14453 xmlSchemaTypePtr type) 14454 { 14455 xmlSchemaTypePtr baseType = NULL; 14456 xmlSchemaAttributeUsePtr use; 14457 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL; 14458 14459 if (type->baseType == NULL) { 14460 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14461 "no base type"); 14462 return (-1); 14463 } 14464 baseType = type->baseType; 14465 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14466 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1) 14467 return(-1); 14468 14469 uses = type->attrUses; 14470 baseUses = baseType->attrUses; 14471 /* 14472 * Expand attribute group references. And build the 'complete' 14473 * wildcard, i.e. intersect multiple wildcards. 14474 * Move attribute prohibitions into a separate list. 14475 */ 14476 if (uses != NULL) { 14477 if (WXS_IS_RESTRICTION(type)) { 14478 /* 14479 * This one will transfer all attr. prohibitions 14480 * into pctxt->attrProhibs. 14481 */ 14482 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14483 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14484 pctxt->attrProhibs) == -1) 14485 { 14486 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14487 "failed to expand attributes"); 14488 } 14489 if (pctxt->attrProhibs->nbItems != 0) 14490 prohibs = pctxt->attrProhibs; 14491 } else { 14492 if (xmlSchemaExpandAttributeGroupRefs(pctxt, 14493 WXS_BASIC_CAST type, &(type->attributeWildcard), uses, 14494 NULL) == -1) 14495 { 14496 PERROR_INT("xmlSchemaFixupTypeAttributeUses", 14497 "failed to expand attributes"); 14498 } 14499 } 14500 } 14501 /* 14502 * Inherit the attribute uses of the base type. 14503 */ 14504 if (baseUses != NULL) { 14505 int i, j; 14506 xmlSchemaAttributeUseProhibPtr pro; 14507 14508 if (WXS_IS_RESTRICTION(type)) { 14509 int usesCount; 14510 xmlSchemaAttributeUsePtr tmp; 14511 14512 if (uses != NULL) 14513 usesCount = uses->nbItems; 14514 else 14515 usesCount = 0; 14516 14517 /* Restriction. */ 14518 for (i = 0; i < baseUses->nbItems; i++) { 14519 use = baseUses->items[i]; 14520 if (prohibs) { 14521 /* 14522 * Filter out prohibited uses. 14523 */ 14524 for (j = 0; j < prohibs->nbItems; j++) { 14525 pro = prohibs->items[j]; 14526 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) && 14527 (WXS_ATTRUSE_DECL_TNS(use) == 14528 pro->targetNamespace)) 14529 { 14530 goto inherit_next; 14531 } 14532 } 14533 } 14534 if (usesCount) { 14535 /* 14536 * Filter out existing uses. 14537 */ 14538 for (j = 0; j < usesCount; j++) { 14539 tmp = uses->items[j]; 14540 if ((WXS_ATTRUSE_DECL_NAME(use) == 14541 WXS_ATTRUSE_DECL_NAME(tmp)) && 14542 (WXS_ATTRUSE_DECL_TNS(use) == 14543 WXS_ATTRUSE_DECL_TNS(tmp))) 14544 { 14545 goto inherit_next; 14546 } 14547 } 14548 } 14549 if (uses == NULL) { 14550 type->attrUses = xmlSchemaItemListCreate(); 14551 if (type->attrUses == NULL) 14552 goto exit_failure; 14553 uses = type->attrUses; 14554 } 14555 xmlSchemaItemListAddSize(uses, 2, use); 14556 inherit_next: {} 14557 } 14558 } else { 14559 /* Extension. */ 14560 for (i = 0; i < baseUses->nbItems; i++) { 14561 use = baseUses->items[i]; 14562 if (uses == NULL) { 14563 type->attrUses = xmlSchemaItemListCreate(); 14564 if (type->attrUses == NULL) 14565 goto exit_failure; 14566 uses = type->attrUses; 14567 } 14568 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use); 14569 } 14570 } 14571 } 14572 /* 14573 * Shrink attr. uses. 14574 */ 14575 if (uses) { 14576 if (uses->nbItems == 0) { 14577 xmlSchemaItemListFree(uses); 14578 type->attrUses = NULL; 14579 } 14580 /* 14581 * TODO: We could shrink the size of the array 14582 * to fit the actual number of items. 14583 */ 14584 } 14585 /* 14586 * Compute the complete wildcard. 14587 */ 14588 if (WXS_IS_EXTENSION(type)) { 14589 if (baseType->attributeWildcard != NULL) { 14590 /* 14591 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then 14592 * the appropriate case among the following:" 14593 */ 14594 if (type->attributeWildcard != NULL) { 14595 /* 14596 * Union the complete wildcard with the base wildcard. 14597 * SPEC {attribute wildcard} 14598 * (3.2.2.1.2) "otherwise a wildcard whose {process contents} 14599 * and {annotation} are those of the `complete wildcard`, 14600 * and whose {namespace constraint} is the intensional union 14601 * of the {namespace constraint} of the `complete wildcard` 14602 * and of the `base wildcard`, as defined in Attribute 14603 * Wildcard Union ($3.10.6)." 14604 */ 14605 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard, 14606 baseType->attributeWildcard) == -1) 14607 goto exit_failure; 14608 } else { 14609 /* 14610 * (3.2.2.1.1) "If the `complete wildcard` is `absent`, 14611 * then the `base wildcard`." 14612 */ 14613 type->attributeWildcard = baseType->attributeWildcard; 14614 } 14615 } else { 14616 /* 14617 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the 14618 * `complete wildcard`" 14619 * NOOP 14620 */ 14621 } 14622 } else { 14623 /* 14624 * SPEC {attribute wildcard} 14625 * (3.1) "If the <restriction> alternative is chosen, then the 14626 * `complete wildcard`;" 14627 * NOOP 14628 */ 14629 } 14630 14631 return (0); 14632 14633 exit_failure: 14634 return(-1); 14635 } 14636 14637 /** 14638 * xmlSchemaTypeFinalContains: 14639 * @schema: the schema 14640 * @type: the type definition 14641 * @final: the final 14642 * 14643 * Evaluates if a type definition contains the given "final". 14644 * This does take "finalDefault" into account as well. 14645 * 14646 * Returns 1 if the type does containt the given "final", 14647 * 0 otherwise. 14648 */ 14649 static int 14650 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final) 14651 { 14652 if (type == NULL) 14653 return (0); 14654 if (type->flags & final) 14655 return (1); 14656 else 14657 return (0); 14658 } 14659 14660 /** 14661 * xmlSchemaGetUnionSimpleTypeMemberTypes: 14662 * @type: the Union Simple Type 14663 * 14664 * Returns a list of member types of @type if existing, 14665 * returns NULL otherwise. 14666 */ 14667 static xmlSchemaTypeLinkPtr 14668 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type) 14669 { 14670 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) { 14671 if (type->memberTypes != NULL) 14672 return (type->memberTypes); 14673 else 14674 type = type->baseType; 14675 } 14676 return (NULL); 14677 } 14678 14679 /** 14680 * xmlSchemaGetParticleTotalRangeMin: 14681 * @particle: the particle 14682 * 14683 * Schema Component Constraint: Effective Total Range 14684 * (all and sequence) + (choice) 14685 * 14686 * Returns the minimun Effective Total Range. 14687 */ 14688 static int 14689 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle) 14690 { 14691 if ((particle->children == NULL) || 14692 (particle->minOccurs == 0)) 14693 return (0); 14694 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14695 int min = -1, cur; 14696 xmlSchemaParticlePtr part = 14697 (xmlSchemaParticlePtr) particle->children->children; 14698 14699 if (part == NULL) 14700 return (0); 14701 while (part != NULL) { 14702 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14703 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14704 cur = part->minOccurs; 14705 else 14706 cur = xmlSchemaGetParticleTotalRangeMin(part); 14707 if (cur == 0) 14708 return (0); 14709 if ((min > cur) || (min == -1)) 14710 min = cur; 14711 part = (xmlSchemaParticlePtr) part->next; 14712 } 14713 return (particle->minOccurs * min); 14714 } else { 14715 /* <all> and <sequence> */ 14716 int sum = 0; 14717 xmlSchemaParticlePtr part = 14718 (xmlSchemaParticlePtr) particle->children->children; 14719 14720 if (part == NULL) 14721 return (0); 14722 do { 14723 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14724 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14725 sum += part->minOccurs; 14726 else 14727 sum += xmlSchemaGetParticleTotalRangeMin(part); 14728 part = (xmlSchemaParticlePtr) part->next; 14729 } while (part != NULL); 14730 return (particle->minOccurs * sum); 14731 } 14732 } 14733 14734 #if 0 14735 /** 14736 * xmlSchemaGetParticleTotalRangeMax: 14737 * @particle: the particle 14738 * 14739 * Schema Component Constraint: Effective Total Range 14740 * (all and sequence) + (choice) 14741 * 14742 * Returns the maximum Effective Total Range. 14743 */ 14744 static int 14745 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle) 14746 { 14747 if ((particle->children == NULL) || 14748 (particle->children->children == NULL)) 14749 return (0); 14750 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) { 14751 int max = -1, cur; 14752 xmlSchemaParticlePtr part = 14753 (xmlSchemaParticlePtr) particle->children->children; 14754 14755 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14756 if (part->children == NULL) 14757 continue; 14758 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14759 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14760 cur = part->maxOccurs; 14761 else 14762 cur = xmlSchemaGetParticleTotalRangeMax(part); 14763 if (cur == UNBOUNDED) 14764 return (UNBOUNDED); 14765 if ((max < cur) || (max == -1)) 14766 max = cur; 14767 } 14768 /* TODO: Handle overflows? */ 14769 return (particle->maxOccurs * max); 14770 } else { 14771 /* <all> and <sequence> */ 14772 int sum = 0, cur; 14773 xmlSchemaParticlePtr part = 14774 (xmlSchemaParticlePtr) particle->children->children; 14775 14776 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) { 14777 if (part->children == NULL) 14778 continue; 14779 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || 14780 (part->children->type == XML_SCHEMA_TYPE_ANY)) 14781 cur = part->maxOccurs; 14782 else 14783 cur = xmlSchemaGetParticleTotalRangeMax(part); 14784 if (cur == UNBOUNDED) 14785 return (UNBOUNDED); 14786 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED)) 14787 return (UNBOUNDED); 14788 sum += cur; 14789 } 14790 /* TODO: Handle overflows? */ 14791 return (particle->maxOccurs * sum); 14792 } 14793 } 14794 #endif 14795 14796 /** 14797 * xmlSchemaIsParticleEmptiable: 14798 * @particle: the particle 14799 * 14800 * Schema Component Constraint: Particle Emptiable 14801 * Checks whether the given particle is emptiable. 14802 * 14803 * Returns 1 if emptiable, 0 otherwise. 14804 */ 14805 static int 14806 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle) 14807 { 14808 /* 14809 * SPEC (1) "Its {min occurs} is 0." 14810 */ 14811 if ((particle == NULL) || (particle->minOccurs == 0) || 14812 (particle->children == NULL)) 14813 return (1); 14814 /* 14815 * SPEC (2) "Its {term} is a group and the minimum part of the 14816 * effective total range of that group, [...] is 0." 14817 */ 14818 if (WXS_IS_MODEL_GROUP(particle->children)) { 14819 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0) 14820 return (1); 14821 } 14822 return (0); 14823 } 14824 14825 /** 14826 * xmlSchemaCheckCOSSTDerivedOK: 14827 * @actxt: a context 14828 * @type: the derived simple type definition 14829 * @baseType: the base type definition 14830 * @subset: the subset of ('restriction', ect.) 14831 * 14832 * Schema Component Constraint: 14833 * Type Derivation OK (Simple) (cos-st-derived-OK) 14834 * 14835 * Checks wheter @type can be validly 14836 * derived from @baseType. 14837 * 14838 * Returns 0 on success, an positive error code otherwise. 14839 */ 14840 static int 14841 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 14842 xmlSchemaTypePtr type, 14843 xmlSchemaTypePtr baseType, 14844 int subset) 14845 { 14846 /* 14847 * 1 They are the same type definition. 14848 * TODO: The identy check might have to be more complex than this. 14849 */ 14850 if (type == baseType) 14851 return (0); 14852 /* 14853 * 2.1 restriction is not in the subset, or in the {final} 14854 * of its own {base type definition}; 14855 * 14856 * NOTE that this will be used also via "xsi:type". 14857 * 14858 * TODO: Revise this, it looks strange. How can the "type" 14859 * not be fixed or *in* fixing? 14860 */ 14861 if (WXS_IS_TYPE_NOT_FIXED(type)) 14862 if (xmlSchemaTypeFixup(type, actxt) == -1) 14863 return(-1); 14864 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 14865 if (xmlSchemaTypeFixup(baseType, actxt) == -1) 14866 return(-1); 14867 if ((subset & SUBSET_RESTRICTION) || 14868 (xmlSchemaTypeFinalContains(type->baseType, 14869 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) { 14870 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1); 14871 } 14872 /* 2.2 */ 14873 if (type->baseType == baseType) { 14874 /* 14875 * 2.2.1 D's `base type definition` is B. 14876 */ 14877 return (0); 14878 } 14879 /* 14880 * 2.2.2 D's `base type definition` is not the `ur-type definition` 14881 * and is validly derived from B given the subset, as defined by this 14882 * constraint. 14883 */ 14884 if ((! WXS_IS_ANYTYPE(type->baseType)) && 14885 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 14886 baseType, subset) == 0)) { 14887 return (0); 14888 } 14889 /* 14890 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type 14891 * definition`. 14892 */ 14893 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) && 14894 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) { 14895 return (0); 14896 } 14897 /* 14898 * 2.2.4 B's {variety} is union and D is validly derived from a type 14899 * definition in B's {member type definitions} given the subset, as 14900 * defined by this constraint. 14901 * 14902 * NOTE: This seems not to involve built-in types, since there is no 14903 * built-in Union Simple Type. 14904 */ 14905 if (WXS_IS_UNION(baseType)) { 14906 xmlSchemaTypeLinkPtr cur; 14907 14908 cur = baseType->memberTypes; 14909 while (cur != NULL) { 14910 if (WXS_IS_TYPE_NOT_FIXED(cur->type)) 14911 if (xmlSchemaTypeFixup(cur->type, actxt) == -1) 14912 return(-1); 14913 if (xmlSchemaCheckCOSSTDerivedOK(actxt, 14914 type, cur->type, subset) == 0) 14915 { 14916 /* 14917 * It just has to be validly derived from at least one 14918 * member-type. 14919 */ 14920 return (0); 14921 } 14922 cur = cur->next; 14923 } 14924 } 14925 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2); 14926 } 14927 14928 /** 14929 * xmlSchemaCheckTypeDefCircularInternal: 14930 * @pctxt: the schema parser context 14931 * @ctxtType: the type definition 14932 * @ancestor: an ancestor of @ctxtType 14933 * 14934 * Checks st-props-correct (2) + ct-props-correct (3). 14935 * Circular type definitions are not allowed. 14936 * 14937 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is 14938 * circular, 0 otherwise. 14939 */ 14940 static int 14941 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt, 14942 xmlSchemaTypePtr ctxtType, 14943 xmlSchemaTypePtr ancestor) 14944 { 14945 int ret; 14946 14947 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC)) 14948 return (0); 14949 14950 if (ctxtType == ancestor) { 14951 xmlSchemaPCustomErr(pctxt, 14952 XML_SCHEMAP_ST_PROPS_CORRECT_2, 14953 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType), 14954 "The definition is circular", NULL); 14955 return (XML_SCHEMAP_ST_PROPS_CORRECT_2); 14956 } 14957 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) { 14958 /* 14959 * Avoid inifinite recursion on circular types not yet checked. 14960 */ 14961 return (0); 14962 } 14963 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED; 14964 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType, 14965 ancestor->baseType); 14966 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED; 14967 return (ret); 14968 } 14969 14970 /** 14971 * xmlSchemaCheckTypeDefCircular: 14972 * @item: the complex/simple type definition 14973 * @ctxt: the parser context 14974 * @name: the name 14975 * 14976 * Checks for circular type definitions. 14977 */ 14978 static void 14979 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item, 14980 xmlSchemaParserCtxtPtr ctxt) 14981 { 14982 if ((item == NULL) || 14983 (item->type == XML_SCHEMA_TYPE_BASIC) || 14984 (item->baseType == NULL)) 14985 return; 14986 xmlSchemaCheckTypeDefCircularInternal(ctxt, item, 14987 item->baseType); 14988 } 14989 14990 /* 14991 * Simple Type Definition Representation OK (src-simple-type) 4 14992 * 14993 * "4 Circular union type definition is disallowed. That is, if the 14994 * <union> alternative is chosen, there must not be any entries in the 14995 * memberTypes [attribute] at any depth which resolve to the component 14996 * corresponding to the <simpleType>." 14997 * 14998 * Note that this should work on the *representation* of a component, 14999 * thus assumes any union types in the member types not being yet 15000 * substituted. At this stage we need the variety of the types 15001 * to be already computed. 15002 */ 15003 static int 15004 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt, 15005 xmlSchemaTypePtr ctxType, 15006 xmlSchemaTypeLinkPtr members) 15007 { 15008 xmlSchemaTypeLinkPtr member; 15009 xmlSchemaTypePtr memberType; 15010 15011 member = members; 15012 while (member != NULL) { 15013 memberType = member->type; 15014 while ((memberType != NULL) && 15015 (memberType->type != XML_SCHEMA_TYPE_BASIC)) { 15016 if (memberType == ctxType) { 15017 xmlSchemaPCustomErr(pctxt, 15018 XML_SCHEMAP_SRC_SIMPLE_TYPE_4, 15019 WXS_BASIC_CAST ctxType, NULL, 15020 "The union type definition is circular", NULL); 15021 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4); 15022 } 15023 if ((WXS_IS_UNION(memberType)) && 15024 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0)) 15025 { 15026 int res; 15027 memberType->flags |= XML_SCHEMAS_TYPE_MARKED; 15028 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, 15029 ctxType, 15030 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType)); 15031 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED; 15032 if (res != 0) 15033 return(res); 15034 } 15035 memberType = memberType->baseType; 15036 } 15037 member = member->next; 15038 } 15039 return(0); 15040 } 15041 15042 static int 15043 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt, 15044 xmlSchemaTypePtr type) 15045 { 15046 if (! WXS_IS_UNION(type)) 15047 return(0); 15048 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type, 15049 type->memberTypes)); 15050 } 15051 15052 /** 15053 * xmlSchemaResolveTypeReferences: 15054 * @item: the complex/simple type definition 15055 * @ctxt: the parser context 15056 * @name: the name 15057 * 15058 * Resolvese type definition references 15059 */ 15060 static void 15061 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef, 15062 xmlSchemaParserCtxtPtr ctxt) 15063 { 15064 if (typeDef == NULL) 15065 return; 15066 15067 /* 15068 * Resolve the base type. 15069 */ 15070 if (typeDef->baseType == NULL) { 15071 typeDef->baseType = xmlSchemaGetType(ctxt->schema, 15072 typeDef->base, typeDef->baseNs); 15073 if (typeDef->baseType == NULL) { 15074 xmlSchemaPResCompAttrErr(ctxt, 15075 XML_SCHEMAP_SRC_RESOLVE, 15076 WXS_BASIC_CAST typeDef, typeDef->node, 15077 "base", typeDef->base, typeDef->baseNs, 15078 XML_SCHEMA_TYPE_SIMPLE, NULL); 15079 return; 15080 } 15081 } 15082 if (WXS_IS_SIMPLE(typeDef)) { 15083 if (WXS_IS_UNION(typeDef)) { 15084 /* 15085 * Resolve the memberTypes. 15086 */ 15087 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef); 15088 return; 15089 } else if (WXS_IS_LIST(typeDef)) { 15090 /* 15091 * Resolve the itemType. 15092 */ 15093 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) { 15094 15095 typeDef->subtypes = xmlSchemaGetType(ctxt->schema, 15096 typeDef->base, typeDef->baseNs); 15097 15098 if ((typeDef->subtypes == NULL) || 15099 (! WXS_IS_SIMPLE(typeDef->subtypes))) 15100 { 15101 typeDef->subtypes = NULL; 15102 xmlSchemaPResCompAttrErr(ctxt, 15103 XML_SCHEMAP_SRC_RESOLVE, 15104 WXS_BASIC_CAST typeDef, typeDef->node, 15105 "itemType", typeDef->base, typeDef->baseNs, 15106 XML_SCHEMA_TYPE_SIMPLE, NULL); 15107 } 15108 } 15109 return; 15110 } 15111 } 15112 /* 15113 * The ball of letters below means, that if we have a particle 15114 * which has a QName-helper component as its {term}, we want 15115 * to resolve it... 15116 */ 15117 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) && 15118 ((WXS_TYPE_CONTENTTYPE(typeDef))->type == 15119 XML_SCHEMA_TYPE_PARTICLE) && 15120 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) && 15121 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type == 15122 XML_SCHEMA_EXTRA_QNAMEREF)) 15123 { 15124 xmlSchemaQNameRefPtr ref = 15125 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef); 15126 xmlSchemaModelGroupDefPtr groupDef; 15127 15128 /* 15129 * URGENT TODO: Test this. 15130 */ 15131 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL; 15132 /* 15133 * Resolve the MG definition reference. 15134 */ 15135 groupDef = 15136 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema, 15137 ref->itemType, ref->name, ref->targetNamespace); 15138 if (groupDef == NULL) { 15139 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE, 15140 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), 15141 "ref", ref->name, ref->targetNamespace, ref->itemType, 15142 NULL); 15143 /* Remove the particle. */ 15144 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15145 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL) 15146 /* Remove the particle. */ 15147 WXS_TYPE_CONTENTTYPE(typeDef) = NULL; 15148 else { 15149 /* 15150 * Assign the MG definition's {model group} to the 15151 * particle's {term}. 15152 */ 15153 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef); 15154 15155 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) { 15156 /* 15157 * SPEC cos-all-limited (1.2) 15158 * "1.2 the {term} property of a particle with 15159 * {max occurs}=1 which is part of a pair which constitutes 15160 * the {content type} of a complex type definition." 15161 */ 15162 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) { 15163 xmlSchemaCustomErr(ACTXT_CAST ctxt, 15164 /* TODO: error code */ 15165 XML_SCHEMAP_COS_ALL_LIMITED, 15166 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL, 15167 "The particle's {max occurs} must be 1, since the " 15168 "reference resolves to an 'all' model group", 15169 NULL, NULL); 15170 } 15171 } 15172 } 15173 } 15174 } 15175 15176 15177 15178 /** 15179 * xmlSchemaCheckSTPropsCorrect: 15180 * @ctxt: the schema parser context 15181 * @type: the simple type definition 15182 * 15183 * Checks st-props-correct. 15184 * 15185 * Returns 0 if the properties are correct, 15186 * if not, a positive error code and -1 on internal 15187 * errors. 15188 */ 15189 static int 15190 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt, 15191 xmlSchemaTypePtr type) 15192 { 15193 xmlSchemaTypePtr baseType = type->baseType; 15194 xmlChar *str = NULL; 15195 15196 /* STATE: error funcs converted. */ 15197 /* 15198 * Schema Component Constraint: Simple Type Definition Properties Correct 15199 * 15200 * NOTE: This is somehow redundant, since we actually built a simple type 15201 * to have all the needed information; this acts as an self test. 15202 */ 15203 /* Base type: If the datatype has been `derived` by `restriction` 15204 * then the Simple Type Definition component from which it is `derived`, 15205 * otherwise the Simple Type Definition for anySimpleType ($4.1.6). 15206 */ 15207 if (baseType == NULL) { 15208 /* 15209 * TODO: Think about: "modulo the impact of Missing 15210 * Sub-components ($5.3)." 15211 */ 15212 xmlSchemaPCustomErr(ctxt, 15213 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15214 WXS_BASIC_CAST type, NULL, 15215 "No base type existent", NULL); 15216 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15217 15218 } 15219 if (! WXS_IS_SIMPLE(baseType)) { 15220 xmlSchemaPCustomErr(ctxt, 15221 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15222 WXS_BASIC_CAST type, NULL, 15223 "The base type '%s' is not a simple type", 15224 xmlSchemaGetComponentQName(&str, baseType)); 15225 FREE_AND_NULL(str) 15226 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15227 } 15228 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) && 15229 (WXS_IS_RESTRICTION(type) == 0) && 15230 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) && 15231 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) { 15232 xmlSchemaPCustomErr(ctxt, 15233 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15234 WXS_BASIC_CAST type, NULL, 15235 "A type, derived by list or union, must have " 15236 "the simple ur-type definition as base type, not '%s'", 15237 xmlSchemaGetComponentQName(&str, baseType)); 15238 FREE_AND_NULL(str) 15239 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15240 } 15241 /* 15242 * Variety: One of {atomic, list, union}. 15243 */ 15244 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) && 15245 (! WXS_IS_LIST(type))) { 15246 xmlSchemaPCustomErr(ctxt, 15247 XML_SCHEMAP_ST_PROPS_CORRECT_1, 15248 WXS_BASIC_CAST type, NULL, 15249 "The variety is absent", NULL); 15250 return (XML_SCHEMAP_ST_PROPS_CORRECT_1); 15251 } 15252 /* TODO: Finish this. Hmm, is this finished? */ 15253 15254 /* 15255 * 3 The {final} of the {base type definition} must not contain restriction. 15256 */ 15257 if (xmlSchemaTypeFinalContains(baseType, 15258 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15259 xmlSchemaPCustomErr(ctxt, 15260 XML_SCHEMAP_ST_PROPS_CORRECT_3, 15261 WXS_BASIC_CAST type, NULL, 15262 "The 'final' of its base type '%s' must not contain " 15263 "'restriction'", 15264 xmlSchemaGetComponentQName(&str, baseType)); 15265 FREE_AND_NULL(str) 15266 return (XML_SCHEMAP_ST_PROPS_CORRECT_3); 15267 } 15268 15269 /* 15270 * 2 All simple type definitions must be derived ultimately from the `simple 15271 * ur-type definition` (so circular definitions are disallowed). That is, it 15272 * must be possible to reach a built-in primitive datatype or the `simple 15273 * ur-type definition` by repeatedly following the {base type definition}. 15274 * 15275 * NOTE: this is done in xmlSchemaCheckTypeDefCircular(). 15276 */ 15277 return (0); 15278 } 15279 15280 /** 15281 * xmlSchemaCheckCOSSTRestricts: 15282 * @ctxt: the schema parser context 15283 * @type: the simple type definition 15284 * 15285 * Schema Component Constraint: 15286 * Derivation Valid (Restriction, Simple) (cos-st-restricts) 15287 15288 * Checks if the given @type (simpleType) is derived validly by restriction. 15289 * STATUS: 15290 * 15291 * Returns -1 on internal errors, 0 if the type is validly derived, 15292 * a positive error code otherwise. 15293 */ 15294 static int 15295 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt, 15296 xmlSchemaTypePtr type) 15297 { 15298 xmlChar *str = NULL; 15299 15300 if (type->type != XML_SCHEMA_TYPE_SIMPLE) { 15301 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15302 "given type is not a user-derived simpleType"); 15303 return (-1); 15304 } 15305 15306 if (WXS_IS_ATOMIC(type)) { 15307 xmlSchemaTypePtr primitive; 15308 /* 15309 * 1.1 The {base type definition} must be an atomic simple 15310 * type definition or a built-in primitive datatype. 15311 */ 15312 if (! WXS_IS_ATOMIC(type->baseType)) { 15313 xmlSchemaPCustomErr(pctxt, 15314 XML_SCHEMAP_COS_ST_RESTRICTS_1_1, 15315 WXS_BASIC_CAST type, NULL, 15316 "The base type '%s' is not an atomic simple type", 15317 xmlSchemaGetComponentQName(&str, type->baseType)); 15318 FREE_AND_NULL(str) 15319 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1); 15320 } 15321 /* 1.2 The {final} of the {base type definition} must not contain 15322 * restriction. 15323 */ 15324 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */ 15325 if (xmlSchemaTypeFinalContains(type->baseType, 15326 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15327 xmlSchemaPCustomErr(pctxt, 15328 XML_SCHEMAP_COS_ST_RESTRICTS_1_2, 15329 WXS_BASIC_CAST type, NULL, 15330 "The final of its base type '%s' must not contain 'restriction'", 15331 xmlSchemaGetComponentQName(&str, type->baseType)); 15332 FREE_AND_NULL(str) 15333 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2); 15334 } 15335 15336 /* 15337 * 1.3.1 DF must be an allowed constraining facet for the {primitive 15338 * type definition}, as specified in the appropriate subsection of 3.2 15339 * Primitive datatypes. 15340 */ 15341 if (type->facets != NULL) { 15342 xmlSchemaFacetPtr facet; 15343 int ok = 1; 15344 15345 primitive = xmlSchemaGetPrimitiveType(type); 15346 if (primitive == NULL) { 15347 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15348 "failed to get primitive type"); 15349 return (-1); 15350 } 15351 facet = type->facets; 15352 do { 15353 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) { 15354 ok = 0; 15355 xmlSchemaPIllegalFacetAtomicErr(pctxt, 15356 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, 15357 type, primitive, facet); 15358 } 15359 facet = facet->next; 15360 } while (facet != NULL); 15361 if (ok == 0) 15362 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1); 15363 } 15364 /* 15365 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets} 15366 * of the {base type definition} (call this BF),then the DF's {value} 15367 * must be a valid restriction of BF's {value} as defined in 15368 * [XML Schemas: Datatypes]." 15369 * 15370 * NOTE (1.3.2) Facet derivation constraints are currently handled in 15371 * xmlSchemaDeriveAndValidateFacets() 15372 */ 15373 } else if (WXS_IS_LIST(type)) { 15374 xmlSchemaTypePtr itemType = NULL; 15375 15376 itemType = type->subtypes; 15377 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) { 15378 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15379 "failed to evaluate the item type"); 15380 return (-1); 15381 } 15382 if (WXS_IS_TYPE_NOT_FIXED(itemType)) 15383 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt); 15384 /* 15385 * 2.1 The {item type definition} must have a {variety} of atomic or 15386 * union (in which case all the {member type definitions} 15387 * must be atomic). 15388 */ 15389 if ((! WXS_IS_ATOMIC(itemType)) && 15390 (! WXS_IS_UNION(itemType))) { 15391 xmlSchemaPCustomErr(pctxt, 15392 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15393 WXS_BASIC_CAST type, NULL, 15394 "The item type '%s' does not have a variety of atomic or union", 15395 xmlSchemaGetComponentQName(&str, itemType)); 15396 FREE_AND_NULL(str) 15397 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15398 } else if (WXS_IS_UNION(itemType)) { 15399 xmlSchemaTypeLinkPtr member; 15400 15401 member = itemType->memberTypes; 15402 while (member != NULL) { 15403 if (! WXS_IS_ATOMIC(member->type)) { 15404 xmlSchemaPCustomErr(pctxt, 15405 XML_SCHEMAP_COS_ST_RESTRICTS_2_1, 15406 WXS_BASIC_CAST type, NULL, 15407 "The item type is a union type, but the " 15408 "member type '%s' of this item type is not atomic", 15409 xmlSchemaGetComponentQName(&str, member->type)); 15410 FREE_AND_NULL(str) 15411 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1); 15412 } 15413 member = member->next; 15414 } 15415 } 15416 15417 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) { 15418 xmlSchemaFacetPtr facet; 15419 /* 15420 * This is the case if we have: <simpleType><list .. 15421 */ 15422 /* 15423 * 2.3.1 15424 * 2.3.1.1 The {final} of the {item type definition} must not 15425 * contain list. 15426 */ 15427 if (xmlSchemaTypeFinalContains(itemType, 15428 XML_SCHEMAS_TYPE_FINAL_LIST)) { 15429 xmlSchemaPCustomErr(pctxt, 15430 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, 15431 WXS_BASIC_CAST type, NULL, 15432 "The final of its item type '%s' must not contain 'list'", 15433 xmlSchemaGetComponentQName(&str, itemType)); 15434 FREE_AND_NULL(str) 15435 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1); 15436 } 15437 /* 15438 * 2.3.1.2 The {facets} must only contain the whiteSpace 15439 * facet component. 15440 * OPTIMIZE TODO: the S4S already disallows any facet 15441 * to be specified. 15442 */ 15443 if (type->facets != NULL) { 15444 facet = type->facets; 15445 do { 15446 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) { 15447 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15448 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, 15449 type, facet); 15450 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2); 15451 } 15452 facet = facet->next; 15453 } while (facet != NULL); 15454 } 15455 /* 15456 * MAYBE TODO: (Hmm, not really) Datatypes states: 15457 * A `list` datatype can be `derived` from an `atomic` datatype 15458 * whose `lexical space` allows space (such as string or anyURI)or 15459 * a `union` datatype any of whose {member type definitions}'s 15460 * `lexical space` allows space. 15461 */ 15462 } else { 15463 /* 15464 * This is the case if we have: <simpleType><restriction ... 15465 * I.e. the variety of "list" is inherited. 15466 */ 15467 /* 15468 * 2.3.2 15469 * 2.3.2.1 The {base type definition} must have a {variety} of list. 15470 */ 15471 if (! WXS_IS_LIST(type->baseType)) { 15472 xmlSchemaPCustomErr(pctxt, 15473 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, 15474 WXS_BASIC_CAST type, NULL, 15475 "The base type '%s' must be a list type", 15476 xmlSchemaGetComponentQName(&str, type->baseType)); 15477 FREE_AND_NULL(str) 15478 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1); 15479 } 15480 /* 15481 * 2.3.2.2 The {final} of the {base type definition} must not 15482 * contain restriction. 15483 */ 15484 if (xmlSchemaTypeFinalContains(type->baseType, 15485 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15486 xmlSchemaPCustomErr(pctxt, 15487 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, 15488 WXS_BASIC_CAST type, NULL, 15489 "The 'final' of the base type '%s' must not contain 'restriction'", 15490 xmlSchemaGetComponentQName(&str, type->baseType)); 15491 FREE_AND_NULL(str) 15492 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2); 15493 } 15494 /* 15495 * 2.3.2.3 The {item type definition} must be validly derived 15496 * from the {base type definition}'s {item type definition} given 15497 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6). 15498 */ 15499 { 15500 xmlSchemaTypePtr baseItemType; 15501 15502 baseItemType = type->baseType->subtypes; 15503 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) { 15504 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15505 "failed to eval the item type of a base type"); 15506 return (-1); 15507 } 15508 if ((itemType != baseItemType) && 15509 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType, 15510 baseItemType, 0) != 0)) { 15511 xmlChar *strBIT = NULL, *strBT = NULL; 15512 xmlSchemaPCustomErrExt(pctxt, 15513 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, 15514 WXS_BASIC_CAST type, NULL, 15515 "The item type '%s' is not validly derived from " 15516 "the item type '%s' of the base type '%s'", 15517 xmlSchemaGetComponentQName(&str, itemType), 15518 xmlSchemaGetComponentQName(&strBIT, baseItemType), 15519 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15520 15521 FREE_AND_NULL(str) 15522 FREE_AND_NULL(strBIT) 15523 FREE_AND_NULL(strBT) 15524 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3); 15525 } 15526 } 15527 15528 if (type->facets != NULL) { 15529 xmlSchemaFacetPtr facet; 15530 int ok = 1; 15531 /* 15532 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern 15533 * and enumeration facet components are allowed among the {facets}. 15534 */ 15535 facet = type->facets; 15536 do { 15537 switch (facet->type) { 15538 case XML_SCHEMA_FACET_LENGTH: 15539 case XML_SCHEMA_FACET_MINLENGTH: 15540 case XML_SCHEMA_FACET_MAXLENGTH: 15541 case XML_SCHEMA_FACET_WHITESPACE: 15542 /* 15543 * TODO: 2.5.1.2 List datatypes 15544 * The value of `whiteSpace` is fixed to the value collapse. 15545 */ 15546 case XML_SCHEMA_FACET_PATTERN: 15547 case XML_SCHEMA_FACET_ENUMERATION: 15548 break; 15549 default: { 15550 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15551 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, 15552 type, facet); 15553 /* 15554 * We could return, but it's nicer to report all 15555 * invalid facets. 15556 */ 15557 ok = 0; 15558 } 15559 } 15560 facet = facet->next; 15561 } while (facet != NULL); 15562 if (ok == 0) 15563 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4); 15564 /* 15565 * SPEC (2.3.2.5) (same as 1.3.2) 15566 * 15567 * NOTE (2.3.2.5) This is currently done in 15568 * xmlSchemaDeriveAndValidateFacets() 15569 */ 15570 } 15571 } 15572 } else if (WXS_IS_UNION(type)) { 15573 /* 15574 * 3.1 The {member type definitions} must all have {variety} of 15575 * atomic or list. 15576 */ 15577 xmlSchemaTypeLinkPtr member; 15578 15579 member = type->memberTypes; 15580 while (member != NULL) { 15581 if (WXS_IS_TYPE_NOT_FIXED(member->type)) 15582 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt); 15583 15584 if ((! WXS_IS_ATOMIC(member->type)) && 15585 (! WXS_IS_LIST(member->type))) { 15586 xmlSchemaPCustomErr(pctxt, 15587 XML_SCHEMAP_COS_ST_RESTRICTS_3_1, 15588 WXS_BASIC_CAST type, NULL, 15589 "The member type '%s' is neither an atomic, nor a list type", 15590 xmlSchemaGetComponentQName(&str, member->type)); 15591 FREE_AND_NULL(str) 15592 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1); 15593 } 15594 member = member->next; 15595 } 15596 /* 15597 * 3.3.1 If the {base type definition} is the `simple ur-type 15598 * definition` 15599 */ 15600 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) { 15601 /* 15602 * 3.3.1.1 All of the {member type definitions} must have a 15603 * {final} which does not contain union. 15604 */ 15605 member = type->memberTypes; 15606 while (member != NULL) { 15607 if (xmlSchemaTypeFinalContains(member->type, 15608 XML_SCHEMAS_TYPE_FINAL_UNION)) { 15609 xmlSchemaPCustomErr(pctxt, 15610 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, 15611 WXS_BASIC_CAST type, NULL, 15612 "The 'final' of member type '%s' contains 'union'", 15613 xmlSchemaGetComponentQName(&str, member->type)); 15614 FREE_AND_NULL(str) 15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1); 15616 } 15617 member = member->next; 15618 } 15619 /* 15620 * 3.3.1.2 The {facets} must be empty. 15621 */ 15622 if (type->facetSet != NULL) { 15623 xmlSchemaPCustomErr(pctxt, 15624 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, 15625 WXS_BASIC_CAST type, NULL, 15626 "No facets allowed", NULL); 15627 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2); 15628 } 15629 } else { 15630 /* 15631 * 3.3.2.1 The {base type definition} must have a {variety} of union. 15632 * I.e. the variety of "list" is inherited. 15633 */ 15634 if (! WXS_IS_UNION(type->baseType)) { 15635 xmlSchemaPCustomErr(pctxt, 15636 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, 15637 WXS_BASIC_CAST type, NULL, 15638 "The base type '%s' is not a union type", 15639 xmlSchemaGetComponentQName(&str, type->baseType)); 15640 FREE_AND_NULL(str) 15641 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1); 15642 } 15643 /* 15644 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction. 15645 */ 15646 if (xmlSchemaTypeFinalContains(type->baseType, 15647 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) { 15648 xmlSchemaPCustomErr(pctxt, 15649 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, 15650 WXS_BASIC_CAST type, NULL, 15651 "The 'final' of its base type '%s' must not contain 'restriction'", 15652 xmlSchemaGetComponentQName(&str, type->baseType)); 15653 FREE_AND_NULL(str) 15654 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2); 15655 } 15656 /* 15657 * 3.3.2.3 The {member type definitions}, in order, must be validly 15658 * derived from the corresponding type definitions in the {base 15659 * type definition}'s {member type definitions} given the empty set, 15660 * as defined in Type Derivation OK (Simple) ($3.14.6). 15661 */ 15662 { 15663 xmlSchemaTypeLinkPtr baseMember; 15664 15665 /* 15666 * OPTIMIZE: if the type is restricting, it has no local defined 15667 * member types and inherits the member types of the base type; 15668 * thus a check for equality can be skipped. 15669 */ 15670 /* 15671 * Even worse: I cannot see a scenario where a restricting 15672 * union simple type can have other member types as the member 15673 * types of it's base type. This check seems not necessary with 15674 * respect to the derivation process in libxml2. 15675 * But necessary if constructing types with an API. 15676 */ 15677 if (type->memberTypes != NULL) { 15678 member = type->memberTypes; 15679 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType); 15680 if ((member == NULL) && (baseMember != NULL)) { 15681 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15682 "different number of member types in base"); 15683 } 15684 while (member != NULL) { 15685 if (baseMember == NULL) { 15686 PERROR_INT("xmlSchemaCheckCOSSTRestricts", 15687 "different number of member types in base"); 15688 } else if ((member->type != baseMember->type) && 15689 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, 15690 member->type, baseMember->type, 0) != 0)) { 15691 xmlChar *strBMT = NULL, *strBT = NULL; 15692 15693 xmlSchemaPCustomErrExt(pctxt, 15694 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, 15695 WXS_BASIC_CAST type, NULL, 15696 "The member type %s is not validly " 15697 "derived from its corresponding member " 15698 "type %s of the base type %s", 15699 xmlSchemaGetComponentQName(&str, member->type), 15700 xmlSchemaGetComponentQName(&strBMT, baseMember->type), 15701 xmlSchemaGetComponentQName(&strBT, type->baseType)); 15702 FREE_AND_NULL(str) 15703 FREE_AND_NULL(strBMT) 15704 FREE_AND_NULL(strBT) 15705 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3); 15706 } 15707 member = member->next; 15708 if (baseMember != NULL) 15709 baseMember = baseMember->next; 15710 } 15711 } 15712 } 15713 /* 15714 * 3.3.2.4 Only pattern and enumeration facet components are 15715 * allowed among the {facets}. 15716 */ 15717 if (type->facets != NULL) { 15718 xmlSchemaFacetPtr facet; 15719 int ok = 1; 15720 15721 facet = type->facets; 15722 do { 15723 if ((facet->type != XML_SCHEMA_FACET_PATTERN) && 15724 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) { 15725 xmlSchemaPIllegalFacetListUnionErr(pctxt, 15726 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, 15727 type, facet); 15728 ok = 0; 15729 } 15730 facet = facet->next; 15731 } while (facet != NULL); 15732 if (ok == 0) 15733 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4); 15734 15735 } 15736 /* 15737 * SPEC (3.3.2.5) (same as 1.3.2) 15738 * 15739 * NOTE (3.3.2.5) This is currently done in 15740 * xmlSchemaDeriveAndValidateFacets() 15741 */ 15742 } 15743 } 15744 15745 return (0); 15746 } 15747 15748 /** 15749 * xmlSchemaCheckSRCSimpleType: 15750 * @ctxt: the schema parser context 15751 * @type: the simple type definition 15752 * 15753 * Checks crc-simple-type constraints. 15754 * 15755 * Returns 0 if the constraints are satisfied, 15756 * if not a positive error code and -1 on internal 15757 * errors. 15758 */ 15759 #if 0 15760 static int 15761 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt, 15762 xmlSchemaTypePtr type) 15763 { 15764 /* 15765 * src-simple-type.1 The corresponding simple type definition, if any, 15766 * must satisfy the conditions set out in Constraints on Simple Type 15767 * Definition Schema Components ($3.14.6). 15768 */ 15769 if (WXS_IS_RESTRICTION(type)) { 15770 /* 15771 * src-simple-type.2 "If the <restriction> alternative is chosen, 15772 * either it must have a base [attribute] or a <simpleType> among its 15773 * [children], but not both." 15774 * NOTE: This is checked in the parse function of <restriction>. 15775 */ 15776 /* 15777 * 15778 */ 15779 } else if (WXS_IS_LIST(type)) { 15780 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have 15781 * an itemType [attribute] or a <simpleType> among its [children], 15782 * but not both." 15783 * 15784 * NOTE: This is checked in the parse function of <list>. 15785 */ 15786 } else if (WXS_IS_UNION(type)) { 15787 /* 15788 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular(). 15789 */ 15790 } 15791 return (0); 15792 } 15793 #endif 15794 15795 static int 15796 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt) 15797 { 15798 if (ctxt->vctxt == NULL) { 15799 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL); 15800 if (ctxt->vctxt == NULL) { 15801 xmlSchemaPErr(ctxt, NULL, 15802 XML_SCHEMAP_INTERNAL, 15803 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, " 15804 "failed to create a temp. validation context.\n", 15805 NULL, NULL); 15806 return (-1); 15807 } 15808 /* TODO: Pass user data. */ 15809 xmlSchemaSetValidErrors(ctxt->vctxt, 15810 ctxt->error, ctxt->warning, ctxt->errCtxt); 15811 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, 15812 ctxt->serror, ctxt->errCtxt); 15813 } 15814 return (0); 15815 } 15816 15817 static int 15818 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt, 15819 xmlNodePtr node, 15820 xmlSchemaTypePtr type, 15821 const xmlChar *value, 15822 xmlSchemaValPtr *retVal, 15823 int fireErrors, 15824 int normalize, 15825 int isNormalized); 15826 15827 /** 15828 * xmlSchemaParseCheckCOSValidDefault: 15829 * @pctxt: the schema parser context 15830 * @type: the simple type definition 15831 * @value: the default value 15832 * @node: an optional node (the holder of the value) 15833 * 15834 * Schema Component Constraint: Element Default Valid (Immediate) 15835 * (cos-valid-default) 15836 * This will be used by the parser only. For the validator there's 15837 * an other version. 15838 * 15839 * Returns 0 if the constraints are satisfied, 15840 * if not, a positive error code and -1 on internal 15841 * errors. 15842 */ 15843 static int 15844 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, 15845 xmlNodePtr node, 15846 xmlSchemaTypePtr type, 15847 const xmlChar *value, 15848 xmlSchemaValPtr *val) 15849 { 15850 int ret = 0; 15851 15852 /* 15853 * cos-valid-default: 15854 * Schema Component Constraint: Element Default Valid (Immediate) 15855 * For a string to be a valid default with respect to a type 15856 * definition the appropriate case among the following must be true: 15857 */ 15858 if WXS_IS_COMPLEX(type) { 15859 /* 15860 * Complex type. 15861 * 15862 * SPEC (2.1) "its {content type} must be a simple type definition 15863 * or mixed." 15864 * SPEC (2.2.2) "If the {content type} is mixed, then the {content 15865 * type}'s particle must be `emptiable` as defined by 15866 * Particle Emptiable ($3.9.6)." 15867 */ 15868 if ((! WXS_HAS_SIMPLE_CONTENT(type)) && 15869 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) { 15870 /* NOTE that this covers (2.2.2) as well. */ 15871 xmlSchemaPCustomErr(pctxt, 15872 XML_SCHEMAP_COS_VALID_DEFAULT_2_1, 15873 WXS_BASIC_CAST type, type->node, 15874 "For a string to be a valid default, the type definition " 15875 "must be a simple type or a complex type with mixed content " 15876 "and a particle emptiable", NULL); 15877 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1); 15878 } 15879 } 15880 /* 15881 * 1 If the type definition is a simple type definition, then the string 15882 * must be `valid` with respect to that definition as defined by String 15883 * Valid ($3.14.4). 15884 * 15885 * AND 15886 * 15887 * 2.2.1 If the {content type} is a simple type definition, then the 15888 * string must be `valid` with respect to that simple type definition 15889 * as defined by String Valid ($3.14.4). 15890 */ 15891 if (WXS_IS_SIMPLE(type)) 15892 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15893 type, value, val, 1, 1, 0); 15894 else if (WXS_HAS_SIMPLE_CONTENT(type)) 15895 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node, 15896 type->contentTypeDef, value, val, 1, 1, 0); 15897 else 15898 return (ret); 15899 15900 if (ret < 0) { 15901 PERROR_INT("xmlSchemaParseCheckCOSValidDefault", 15902 "calling xmlSchemaVCheckCVCSimpleType()"); 15903 } 15904 15905 return (ret); 15906 } 15907 15908 /** 15909 * xmlSchemaCheckCTPropsCorrect: 15910 * @ctxt: the schema parser context 15911 * @type: the complex type definition 15912 * 15913 *.(4.6) Constraints on Complex Type Definition Schema Components 15914 * Schema Component Constraint: 15915 * Complex Type Definition Properties Correct (ct-props-correct) 15916 * STATUS: (seems) complete 15917 * 15918 * Returns 0 if the constraints are satisfied, a positive 15919 * error code if not and -1 if an internal error occurred. 15920 */ 15921 static int 15922 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, 15923 xmlSchemaTypePtr type) 15924 { 15925 /* 15926 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily. 15927 * 15928 * SPEC (1) "The values of the properties of a complex type definition must 15929 * be as described in the property tableau in The Complex Type Definition 15930 * Schema Component ($3.4.1), modulo the impact of Missing 15931 * Sub-components ($5.3)." 15932 */ 15933 if ((type->baseType != NULL) && 15934 (WXS_IS_SIMPLE(type->baseType)) && 15935 (WXS_IS_EXTENSION(type) == 0)) { 15936 /* 15937 * SPEC (2) "If the {base type definition} is a simple type definition, 15938 * the {derivation method} must be extension." 15939 */ 15940 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15941 XML_SCHEMAP_SRC_CT_1, 15942 NULL, WXS_BASIC_CAST type, 15943 "If the base type is a simple type, the derivation method must be " 15944 "'extension'", NULL, NULL); 15945 return (XML_SCHEMAP_SRC_CT_1); 15946 } 15947 /* 15948 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type 15949 * definition`. That is, it must be possible to reach the `ur-type 15950 * definition` by repeatedly following the {base type definition}." 15951 * 15952 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular(). 15953 */ 15954 /* 15955 * NOTE that (4) and (5) need the following: 15956 * - attribute uses need to be already inherited (apply attr. prohibitions) 15957 * - attribute group references need to be expanded already 15958 * - simple types need to be typefixed already 15959 */ 15960 if (type->attrUses && 15961 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1)) 15962 { 15963 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses; 15964 xmlSchemaAttributeUsePtr use, tmp; 15965 int i, j, hasId = 0; 15966 15967 for (i = uses->nbItems -1; i >= 0; i--) { 15968 use = uses->items[i]; 15969 15970 /* 15971 * SPEC ct-props-correct 15972 * (4) "Two distinct attribute declarations in the 15973 * {attribute uses} must not have identical {name}s and 15974 * {target namespace}s." 15975 */ 15976 if (i > 0) { 15977 for (j = i -1; j >= 0; j--) { 15978 tmp = uses->items[j]; 15979 if ((WXS_ATTRUSE_DECL_NAME(use) == 15980 WXS_ATTRUSE_DECL_NAME(tmp)) && 15981 (WXS_ATTRUSE_DECL_TNS(use) == 15982 WXS_ATTRUSE_DECL_TNS(tmp))) 15983 { 15984 xmlChar *str = NULL; 15985 15986 xmlSchemaCustomErr(ACTXT_CAST pctxt, 15987 XML_SCHEMAP_AG_PROPS_CORRECT, 15988 NULL, WXS_BASIC_CAST type, 15989 "Duplicate %s", 15990 xmlSchemaGetComponentDesignation(&str, use), 15991 NULL); 15992 FREE_AND_NULL(str); 15993 /* 15994 * Remove the duplicate. 15995 */ 15996 if (xmlSchemaItemListRemove(uses, i) == -1) 15997 goto exit_failure; 15998 goto next_use; 15999 } 16000 } 16001 } 16002 /* 16003 * SPEC ct-props-correct 16004 * (5) "Two distinct attribute declarations in the 16005 * {attribute uses} must not have {type definition}s which 16006 * are or are derived from ID." 16007 */ 16008 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) { 16009 if (xmlSchemaIsDerivedFromBuiltInType( 16010 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID)) 16011 { 16012 if (hasId) { 16013 xmlChar *str = NULL; 16014 16015 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16016 XML_SCHEMAP_AG_PROPS_CORRECT, 16017 NULL, WXS_BASIC_CAST type, 16018 "There must not exist more than one attribute " 16019 "declaration of type 'xs:ID' " 16020 "(or derived from 'xs:ID'). The %s violates this " 16021 "constraint", 16022 xmlSchemaGetComponentDesignation(&str, use), 16023 NULL); 16024 FREE_AND_NULL(str); 16025 if (xmlSchemaItemListRemove(uses, i) == -1) 16026 goto exit_failure; 16027 } 16028 16029 hasId = 1; 16030 } 16031 } 16032 next_use: {} 16033 } 16034 } 16035 return (0); 16036 exit_failure: 16037 return(-1); 16038 } 16039 16040 static int 16041 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA, 16042 xmlSchemaTypePtr typeB) 16043 { 16044 /* 16045 * TODO: This should implement component-identity 16046 * in the future. 16047 */ 16048 if ((typeA == NULL) || (typeB == NULL)) 16049 return (0); 16050 return (typeA == typeB); 16051 } 16052 16053 /** 16054 * xmlSchemaCheckCOSCTDerivedOK: 16055 * @ctxt: the schema parser context 16056 * @type: the to-be derived complex type definition 16057 * @baseType: the base complex type definition 16058 * @set: the given set 16059 * 16060 * Schema Component Constraint: 16061 * Type Derivation OK (Complex) (cos-ct-derived-ok) 16062 * 16063 * STATUS: completed 16064 * 16065 * Returns 0 if the constraints are satisfied, or 1 16066 * if not. 16067 */ 16068 static int 16069 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16070 xmlSchemaTypePtr type, 16071 xmlSchemaTypePtr baseType, 16072 int set) 16073 { 16074 int equal = xmlSchemaAreEqualTypes(type, baseType); 16075 /* TODO: Error codes. */ 16076 /* 16077 * SPEC "For a complex type definition (call it D, for derived) 16078 * to be validly derived from a type definition (call this 16079 * B, for base) given a subset of {extension, restriction} 16080 * all of the following must be true:" 16081 */ 16082 if (! equal) { 16083 /* 16084 * SPEC (1) "If B and D are not the same type definition, then the 16085 * {derivation method} of D must not be in the subset." 16086 */ 16087 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) || 16088 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type)))) 16089 return (1); 16090 } else { 16091 /* 16092 * SPEC (2.1) "B and D must be the same type definition." 16093 */ 16094 return (0); 16095 } 16096 /* 16097 * SPEC (2.2) "B must be D's {base type definition}." 16098 */ 16099 if (type->baseType == baseType) 16100 return (0); 16101 /* 16102 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type 16103 * definition`." 16104 */ 16105 if (WXS_IS_ANYTYPE(type->baseType)) 16106 return (1); 16107 16108 if (WXS_IS_COMPLEX(type->baseType)) { 16109 /* 16110 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it 16111 * must be validly derived from B given the subset as defined by this 16112 * constraint." 16113 */ 16114 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType, 16115 baseType, set)); 16116 } else { 16117 /* 16118 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it 16119 * must be validly derived from B given the subset as defined in Type 16120 * Derivation OK (Simple) ($3.14.6). 16121 */ 16122 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType, 16123 baseType, set)); 16124 } 16125 } 16126 16127 /** 16128 * xmlSchemaCheckCOSDerivedOK: 16129 * @type: the derived simple type definition 16130 * @baseType: the base type definition 16131 * 16132 * Calls: 16133 * Type Derivation OK (Simple) AND Type Derivation OK (Complex) 16134 * 16135 * Checks wheter @type can be validly derived from @baseType. 16136 * 16137 * Returns 0 on success, an positive error code otherwise. 16138 */ 16139 static int 16140 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, 16141 xmlSchemaTypePtr type, 16142 xmlSchemaTypePtr baseType, 16143 int set) 16144 { 16145 if (WXS_IS_SIMPLE(type)) 16146 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set)); 16147 else 16148 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set)); 16149 } 16150 16151 /** 16152 * xmlSchemaCheckCOSCTExtends: 16153 * @ctxt: the schema parser context 16154 * @type: the complex type definition 16155 * 16156 * (3.4.6) Constraints on Complex Type Definition Schema Components 16157 * Schema Component Constraint: 16158 * Derivation Valid (Extension) (cos-ct-extends) 16159 * 16160 * STATUS: 16161 * missing: 16162 * (1.5) 16163 * (1.4.3.2.2.2) "Particle Valid (Extension)" 16164 * 16165 * Returns 0 if the constraints are satisfied, a positive 16166 * error code if not and -1 if an internal error occurred. 16167 */ 16168 static int 16169 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, 16170 xmlSchemaTypePtr type) 16171 { 16172 xmlSchemaTypePtr base = type->baseType; 16173 /* 16174 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used 16175 * temporarily only. 16176 */ 16177 /* 16178 * SPEC (1) "If the {base type definition} is a complex type definition, 16179 * then all of the following must be true:" 16180 */ 16181 if (WXS_IS_COMPLEX(base)) { 16182 /* 16183 * SPEC (1.1) "The {final} of the {base type definition} must not 16184 * contain extension." 16185 */ 16186 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16187 xmlSchemaPCustomErr(ctxt, 16188 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16189 WXS_BASIC_CAST type, NULL, 16190 "The 'final' of the base type definition " 16191 "contains 'extension'", NULL); 16192 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16193 } 16194 16195 /* 16196 * ATTENTION: The constrains (1.2) and (1.3) are not applied, 16197 * since they are automatically satisfied through the 16198 * inheriting mechanism. 16199 * Note that even if redefining components, the inheriting mechanism 16200 * is used. 16201 */ 16202 #if 0 16203 /* 16204 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute 16205 * uses} 16206 * of the complex type definition itself, that is, for every attribute 16207 * use in the {attribute uses} of the {base type definition}, there 16208 * must be an attribute use in the {attribute uses} of the complex 16209 * type definition itself whose {attribute declaration} has the same 16210 * {name}, {target namespace} and {type definition} as its attribute 16211 * declaration" 16212 */ 16213 if (base->attrUses != NULL) { 16214 int i, j, found; 16215 xmlSchemaAttributeUsePtr use, buse; 16216 16217 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) { 16218 buse = (WXS_LIST_CAST base->attrUses)->items[i]; 16219 found = 0; 16220 if (type->attrUses != NULL) { 16221 use = (WXS_LIST_CAST type->attrUses)->items[j]; 16222 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++) 16223 { 16224 if ((WXS_ATTRUSE_DECL_NAME(use) == 16225 WXS_ATTRUSE_DECL_NAME(buse)) && 16226 (WXS_ATTRUSE_DECL_TNS(use) == 16227 WXS_ATTRUSE_DECL_TNS(buse)) && 16228 (WXS_ATTRUSE_TYPEDEF(use) == 16229 WXS_ATTRUSE_TYPEDEF(buse)) 16230 { 16231 found = 1; 16232 break; 16233 } 16234 } 16235 } 16236 if (! found) { 16237 xmlChar *str = NULL; 16238 16239 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16240 XML_SCHEMAP_COS_CT_EXTENDS_1_2, 16241 NULL, WXS_BASIC_CAST type, 16242 /* 16243 * TODO: The report does not indicate that also the 16244 * type needs to be the same. 16245 */ 16246 "This type is missing a matching correspondent " 16247 "for its {base type}'s %s in its {attribute uses}", 16248 xmlSchemaGetComponentDesignation(&str, 16249 buse->children), 16250 NULL); 16251 FREE_AND_NULL(str) 16252 } 16253 } 16254 } 16255 /* 16256 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type 16257 * definition must also have one, and the base type definition's 16258 * {attribute wildcard}'s {namespace constraint} must be a subset 16259 * of the complex type definition's {attribute wildcard}'s {namespace 16260 * constraint}, as defined by Wildcard Subset ($3.10.6)." 16261 */ 16262 16263 /* 16264 * MAYBE TODO: Enable if ever needed. But this will be needed only 16265 * if created the type via a schema construction API. 16266 */ 16267 if (base->attributeWildcard != NULL) { 16268 if (type->attributeWilcard == NULL) { 16269 xmlChar *str = NULL; 16270 16271 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16272 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16273 NULL, type, 16274 "The base %s has an attribute wildcard, " 16275 "but this type is missing an attribute wildcard", 16276 xmlSchemaGetComponentDesignation(&str, base)); 16277 FREE_AND_NULL(str) 16278 16279 } else if (xmlSchemaCheckCOSNSSubset( 16280 base->attributeWildcard, type->attributeWildcard)) 16281 { 16282 xmlChar *str = NULL; 16283 16284 xmlSchemaCustomErr(ACTXT_CAST pctxt, 16285 XML_SCHEMAP_COS_CT_EXTENDS_1_3, 16286 NULL, type, 16287 "The attribute wildcard is not a valid " 16288 "superset of the one in the base %s", 16289 xmlSchemaGetComponentDesignation(&str, base)); 16290 FREE_AND_NULL(str) 16291 } 16292 } 16293 #endif 16294 /* 16295 * SPEC (1.4) "One of the following must be true:" 16296 */ 16297 if ((type->contentTypeDef != NULL) && 16298 (type->contentTypeDef == base->contentTypeDef)) { 16299 /* 16300 * SPEC (1.4.1) "The {content type} of the {base type definition} 16301 * and the {content type} of the complex type definition itself 16302 * must be the same simple type definition" 16303 * PASS 16304 */ 16305 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) && 16306 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) { 16307 /* 16308 * SPEC (1.4.2) "The {content type} of both the {base type 16309 * definition} and the complex type definition itself must 16310 * be empty." 16311 * PASS 16312 */ 16313 } else { 16314 /* 16315 * SPEC (1.4.3) "All of the following must be true:" 16316 */ 16317 if (type->subtypes == NULL) { 16318 /* 16319 * SPEC 1.4.3.1 The {content type} of the complex type 16320 * definition itself must specify a particle. 16321 */ 16322 xmlSchemaPCustomErr(ctxt, 16323 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16324 WXS_BASIC_CAST type, NULL, 16325 "The content type must specify a particle", NULL); 16326 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16327 } 16328 /* 16329 * SPEC (1.4.3.2) "One of the following must be true:" 16330 */ 16331 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16332 /* 16333 * SPEC (1.4.3.2.1) "The {content type} of the {base type 16334 * definition} must be empty. 16335 * PASS 16336 */ 16337 } else { 16338 /* 16339 * SPEC (1.4.3.2.2) "All of the following must be true:" 16340 */ 16341 if ((type->contentType != base->contentType) || 16342 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) && 16343 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) { 16344 /* 16345 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed 16346 * or both must be element-only." 16347 */ 16348 xmlSchemaPCustomErr(ctxt, 16349 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16350 WXS_BASIC_CAST type, NULL, 16351 "The content type of both, the type and its base " 16352 "type, must either 'mixed' or 'element-only'", NULL); 16353 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16354 } 16355 /* 16356 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the 16357 * complex type definition must be a `valid extension` 16358 * of the {base type definition}'s particle, as defined 16359 * in Particle Valid (Extension) ($3.9.6)." 16360 * 16361 * NOTE that we won't check "Particle Valid (Extension)", 16362 * since it is ensured by the derivation process in 16363 * xmlSchemaTypeFixup(). We need to implement this when heading 16364 * for a construction API 16365 * TODO: !! This is needed to be checked if redefining a type !! 16366 */ 16367 } 16368 /* 16369 * URGENT TODO (1.5) 16370 */ 16371 } 16372 } else { 16373 /* 16374 * SPEC (2) "If the {base type definition} is a simple type definition, 16375 * then all of the following must be true:" 16376 */ 16377 if (type->contentTypeDef != base) { 16378 /* 16379 * SPEC (2.1) "The {content type} must be the same simple type 16380 * definition." 16381 */ 16382 xmlSchemaPCustomErr(ctxt, 16383 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16384 WXS_BASIC_CAST type, NULL, 16385 "The content type must be the simple base type", NULL); 16386 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16387 } 16388 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) { 16389 /* 16390 * SPEC (2.2) "The {final} of the {base type definition} must not 16391 * contain extension" 16392 * NOTE that this is the same as (1.1). 16393 */ 16394 xmlSchemaPCustomErr(ctxt, 16395 XML_SCHEMAP_COS_CT_EXTENDS_1_1, 16396 WXS_BASIC_CAST type, NULL, 16397 "The 'final' of the base type definition " 16398 "contains 'extension'", NULL); 16399 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1); 16400 } 16401 } 16402 return (0); 16403 } 16404 16405 /** 16406 * xmlSchemaCheckDerivationOKRestriction: 16407 * @ctxt: the schema parser context 16408 * @type: the complex type definition 16409 * 16410 * (3.4.6) Constraints on Complex Type Definition Schema Components 16411 * Schema Component Constraint: 16412 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction) 16413 * 16414 * STATUS: 16415 * missing: 16416 * (5.4.2) ??? 16417 * 16418 * ATTENTION: 16419 * In XML Schema 1.1 this will be: 16420 * Validation Rule: Checking complex type subsumption 16421 * 16422 * Returns 0 if the constraints are satisfied, a positive 16423 * error code if not and -1 if an internal error occurred. 16424 */ 16425 static int 16426 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, 16427 xmlSchemaTypePtr type) 16428 { 16429 xmlSchemaTypePtr base; 16430 16431 /* 16432 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used 16433 * temporarily only. 16434 */ 16435 base = type->baseType; 16436 if (! WXS_IS_COMPLEX(base)) { 16437 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16438 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16439 type->node, WXS_BASIC_CAST type, 16440 "The base type must be a complex type", NULL, NULL); 16441 return(ctxt->err); 16442 } 16443 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) { 16444 /* 16445 * SPEC (1) "The {base type definition} must be a complex type 16446 * definition whose {final} does not contain restriction." 16447 */ 16448 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16449 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16450 type->node, WXS_BASIC_CAST type, 16451 "The 'final' of the base type definition " 16452 "contains 'restriction'", NULL, NULL); 16453 return (ctxt->err); 16454 } 16455 /* 16456 * SPEC (2), (3) and (4) 16457 * Those are handled in a separate function, since the 16458 * same constraints are needed for redefinition of 16459 * attribute groups as well. 16460 */ 16461 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt, 16462 XML_SCHEMA_ACTION_DERIVE, 16463 WXS_BASIC_CAST type, WXS_BASIC_CAST base, 16464 type->attrUses, base->attrUses, 16465 type->attributeWildcard, 16466 base->attributeWildcard) == -1) 16467 { 16468 return(-1); 16469 } 16470 /* 16471 * SPEC (5) "One of the following must be true:" 16472 */ 16473 if (base->builtInType == XML_SCHEMAS_ANYTYPE) { 16474 /* 16475 * SPEC (5.1) "The {base type definition} must be the 16476 * `ur-type definition`." 16477 * PASS 16478 */ 16479 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16480 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16481 /* 16482 * SPEC (5.2.1) "The {content type} of the complex type definition 16483 * must be a simple type definition" 16484 * 16485 * SPEC (5.2.2) "One of the following must be true:" 16486 */ 16487 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16488 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) 16489 { 16490 int err; 16491 /* 16492 * SPEC (5.2.2.1) "The {content type} of the {base type 16493 * definition} must be a simple type definition from which 16494 * the {content type} is validly derived given the empty 16495 * set as defined in Type Derivation OK (Simple) ($3.14.6)." 16496 * 16497 * ATTENTION TODO: This seems not needed if the type implicitely 16498 * derived from the base type. 16499 * 16500 */ 16501 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt, 16502 type->contentTypeDef, base->contentTypeDef, 0); 16503 if (err != 0) { 16504 xmlChar *strA = NULL, *strB = NULL; 16505 16506 if (err == -1) 16507 return(-1); 16508 xmlSchemaCustomErr(ACTXT_CAST ctxt, 16509 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16510 NULL, WXS_BASIC_CAST type, 16511 "The {content type} %s is not validly derived from the " 16512 "base type's {content type} %s", 16513 xmlSchemaGetComponentDesignation(&strA, 16514 type->contentTypeDef), 16515 xmlSchemaGetComponentDesignation(&strB, 16516 base->contentTypeDef)); 16517 FREE_AND_NULL(strA); 16518 FREE_AND_NULL(strB); 16519 return(ctxt->err); 16520 } 16521 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16522 (xmlSchemaIsParticleEmptiable( 16523 (xmlSchemaParticlePtr) base->subtypes))) { 16524 /* 16525 * SPEC (5.2.2.2) "The {base type definition} must be mixed 16526 * and have a particle which is `emptiable` as defined in 16527 * Particle Emptiable ($3.9.6)." 16528 * PASS 16529 */ 16530 } else { 16531 xmlSchemaPCustomErr(ctxt, 16532 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16533 WXS_BASIC_CAST type, NULL, 16534 "The content type of the base type must be either " 16535 "a simple type or 'mixed' and an emptiable particle", NULL); 16536 return (ctxt->err); 16537 } 16538 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16539 /* 16540 * SPEC (5.3.1) "The {content type} of the complex type itself must 16541 * be empty" 16542 */ 16543 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) { 16544 /* 16545 * SPEC (5.3.2.1) "The {content type} of the {base type 16546 * definition} must also be empty." 16547 * PASS 16548 */ 16549 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16550 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) && 16551 xmlSchemaIsParticleEmptiable( 16552 (xmlSchemaParticlePtr) base->subtypes)) { 16553 /* 16554 * SPEC (5.3.2.2) "The {content type} of the {base type 16555 * definition} must be elementOnly or mixed and have a particle 16556 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)." 16557 * PASS 16558 */ 16559 } else { 16560 xmlSchemaPCustomErr(ctxt, 16561 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16562 WXS_BASIC_CAST type, NULL, 16563 "The content type of the base type must be either " 16564 "empty or 'mixed' (or 'elements-only') and an emptiable " 16565 "particle", NULL); 16566 return (ctxt->err); 16567 } 16568 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) || 16569 WXS_HAS_MIXED_CONTENT(type)) { 16570 /* 16571 * SPEC (5.4.1.1) "The {content type} of the complex type definition 16572 * itself must be element-only" 16573 */ 16574 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) { 16575 /* 16576 * SPEC (5.4.1.2) "The {content type} of the complex type 16577 * definition itself and of the {base type definition} must be 16578 * mixed" 16579 */ 16580 xmlSchemaPCustomErr(ctxt, 16581 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16582 WXS_BASIC_CAST type, NULL, 16583 "If the content type is 'mixed', then the content type of the " 16584 "base type must also be 'mixed'", NULL); 16585 return (ctxt->err); 16586 } 16587 /* 16588 * SPEC (5.4.2) "The particle of the complex type definition itself 16589 * must be a `valid restriction` of the particle of the {content 16590 * type} of the {base type definition} as defined in Particle Valid 16591 * (Restriction) ($3.9.6). 16592 * 16593 * URGENT TODO: (5.4.2) 16594 */ 16595 } else { 16596 xmlSchemaPCustomErr(ctxt, 16597 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, 16598 WXS_BASIC_CAST type, NULL, 16599 "The type is not a valid restriction of its base type", NULL); 16600 return (ctxt->err); 16601 } 16602 return (0); 16603 } 16604 16605 /** 16606 * xmlSchemaCheckCTComponent: 16607 * @ctxt: the schema parser context 16608 * @type: the complex type definition 16609 * 16610 * (3.4.6) Constraints on Complex Type Definition Schema Components 16611 * 16612 * Returns 0 if the constraints are satisfied, a positive 16613 * error code if not and -1 if an internal error occurred. 16614 */ 16615 static int 16616 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, 16617 xmlSchemaTypePtr type) 16618 { 16619 int ret; 16620 /* 16621 * Complex Type Definition Properties Correct 16622 */ 16623 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type); 16624 if (ret != 0) 16625 return (ret); 16626 if (WXS_IS_EXTENSION(type)) 16627 ret = xmlSchemaCheckCOSCTExtends(ctxt, type); 16628 else 16629 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type); 16630 return (ret); 16631 } 16632 16633 /** 16634 * xmlSchemaCheckSRCCT: 16635 * @ctxt: the schema parser context 16636 * @type: the complex type definition 16637 * 16638 * (3.4.3) Constraints on XML Representations of Complex Type Definitions: 16639 * Schema Representation Constraint: 16640 * Complex Type Definition Representation OK (src-ct) 16641 * 16642 * Returns 0 if the constraints are satisfied, a positive 16643 * error code if not and -1 if an internal error occurred. 16644 */ 16645 static int 16646 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, 16647 xmlSchemaTypePtr type) 16648 { 16649 xmlSchemaTypePtr base; 16650 int ret = 0; 16651 16652 /* 16653 * TODO: Adjust the error codes here, as I used 16654 * XML_SCHEMAP_SRC_CT_1 only yet. 16655 */ 16656 base = type->baseType; 16657 if (! WXS_HAS_SIMPLE_CONTENT(type)) { 16658 /* 16659 * 1 If the <complexContent> alternative is chosen, the type definition 16660 * `resolved` to by the `actual value` of the base [attribute] 16661 * must be a complex type definition; 16662 */ 16663 if (! WXS_IS_COMPLEX(base)) { 16664 xmlChar *str = NULL; 16665 xmlSchemaPCustomErr(ctxt, 16666 XML_SCHEMAP_SRC_CT_1, 16667 WXS_BASIC_CAST type, type->node, 16668 "If using <complexContent>, the base type is expected to be " 16669 "a complex type. The base type '%s' is a simple type", 16670 xmlSchemaFormatQName(&str, base->targetNamespace, 16671 base->name)); 16672 FREE_AND_NULL(str) 16673 return (XML_SCHEMAP_SRC_CT_1); 16674 } 16675 } else { 16676 /* 16677 * SPEC 16678 * 2 If the <simpleContent> alternative is chosen, all of the 16679 * following must be true: 16680 * 2.1 The type definition `resolved` to by the `actual value` of the 16681 * base [attribute] must be one of the following: 16682 */ 16683 if (WXS_IS_SIMPLE(base)) { 16684 if (WXS_IS_EXTENSION(type) == 0) { 16685 xmlChar *str = NULL; 16686 /* 16687 * 2.1.3 only if the <extension> alternative is also 16688 * chosen, a simple type definition. 16689 */ 16690 /* TODO: Change error code to ..._SRC_CT_2_1_3. */ 16691 xmlSchemaPCustomErr(ctxt, 16692 XML_SCHEMAP_SRC_CT_1, 16693 WXS_BASIC_CAST type, NULL, 16694 "If using <simpleContent> and <restriction>, the base " 16695 "type must be a complex type. The base type '%s' is " 16696 "a simple type", 16697 xmlSchemaFormatQName(&str, base->targetNamespace, 16698 base->name)); 16699 FREE_AND_NULL(str) 16700 return (XML_SCHEMAP_SRC_CT_1); 16701 } 16702 } else { 16703 /* Base type is a complex type. */ 16704 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) || 16705 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) { 16706 /* 16707 * 2.1.1 a complex type definition whose {content type} is a 16708 * simple type definition; 16709 * PASS 16710 */ 16711 if (base->contentTypeDef == NULL) { 16712 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL, 16713 WXS_BASIC_CAST type, NULL, 16714 "Internal error: xmlSchemaCheckSRCCT, " 16715 "'%s', base type has no content type", 16716 type->name); 16717 return (-1); 16718 } 16719 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) && 16720 (WXS_IS_RESTRICTION(type))) { 16721 16722 /* 16723 * 2.1.2 only if the <restriction> alternative is also 16724 * chosen, a complex type definition whose {content type} 16725 * is mixed and a particle emptiable. 16726 */ 16727 if (! xmlSchemaIsParticleEmptiable( 16728 (xmlSchemaParticlePtr) base->subtypes)) { 16729 ret = XML_SCHEMAP_SRC_CT_1; 16730 } else 16731 /* 16732 * Attention: at this point the <simpleType> child is in 16733 * ->contentTypeDef (put there during parsing). 16734 */ 16735 if (type->contentTypeDef == NULL) { 16736 xmlChar *str = NULL; 16737 /* 16738 * 2.2 If clause 2.1.2 above is satisfied, then there 16739 * must be a <simpleType> among the [children] of 16740 * <restriction>. 16741 */ 16742 /* TODO: Change error code to ..._SRC_CT_2_2. */ 16743 xmlSchemaPCustomErr(ctxt, 16744 XML_SCHEMAP_SRC_CT_1, 16745 WXS_BASIC_CAST type, NULL, 16746 "A <simpleType> is expected among the children " 16747 "of <restriction>, if <simpleContent> is used and " 16748 "the base type '%s' is a complex type", 16749 xmlSchemaFormatQName(&str, base->targetNamespace, 16750 base->name)); 16751 FREE_AND_NULL(str) 16752 return (XML_SCHEMAP_SRC_CT_1); 16753 } 16754 } else { 16755 ret = XML_SCHEMAP_SRC_CT_1; 16756 } 16757 } 16758 if (ret > 0) { 16759 xmlChar *str = NULL; 16760 if (WXS_IS_RESTRICTION(type)) { 16761 xmlSchemaPCustomErr(ctxt, 16762 XML_SCHEMAP_SRC_CT_1, 16763 WXS_BASIC_CAST type, NULL, 16764 "If <simpleContent> and <restriction> is used, the " 16765 "base type must be a simple type or a complex type with " 16766 "mixed content and particle emptiable. The base type " 16767 "'%s' is none of those", 16768 xmlSchemaFormatQName(&str, base->targetNamespace, 16769 base->name)); 16770 } else { 16771 xmlSchemaPCustomErr(ctxt, 16772 XML_SCHEMAP_SRC_CT_1, 16773 WXS_BASIC_CAST type, NULL, 16774 "If <simpleContent> and <extension> is used, the " 16775 "base type must be a simple type. The base type '%s' " 16776 "is a complex type", 16777 xmlSchemaFormatQName(&str, base->targetNamespace, 16778 base->name)); 16779 } 16780 FREE_AND_NULL(str) 16781 } 16782 } 16783 /* 16784 * SPEC (3) "The corresponding complex type definition component must 16785 * satisfy the conditions set out in Constraints on Complex Type 16786 * Definition Schema Components ($3.4.6);" 16787 * NOTE (3) will be done in xmlSchemaTypeFixup(). 16788 */ 16789 /* 16790 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification 16791 * above for {attribute wildcard} is satisfied, the intensional 16792 * intersection must be expressible, as defined in Attribute Wildcard 16793 * Intersection ($3.10.6). 16794 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses(). 16795 */ 16796 return (ret); 16797 } 16798 16799 #ifdef ENABLE_PARTICLE_RESTRICTION 16800 /** 16801 * xmlSchemaCheckParticleRangeOK: 16802 * @ctxt: the schema parser context 16803 * @type: the complex type definition 16804 * 16805 * (3.9.6) Constraints on Particle Schema Components 16806 * Schema Component Constraint: 16807 * Occurrence Range OK (range-ok) 16808 * 16809 * STATUS: complete 16810 * 16811 * Returns 0 if the constraints are satisfied, a positive 16812 * error code if not and -1 if an internal error occurred. 16813 */ 16814 static int 16815 xmlSchemaCheckParticleRangeOK(int rmin, int rmax, 16816 int bmin, int bmax) 16817 { 16818 if (rmin < bmin) 16819 return (1); 16820 if ((bmax != UNBOUNDED) && 16821 (rmax > bmax)) 16822 return (1); 16823 return (0); 16824 } 16825 16826 /** 16827 * xmlSchemaCheckRCaseNameAndTypeOK: 16828 * @ctxt: the schema parser context 16829 * @r: the restricting element declaration particle 16830 * @b: the base element declaration particle 16831 * 16832 * (3.9.6) Constraints on Particle Schema Components 16833 * Schema Component Constraint: 16834 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK) 16835 * (rcase-NameAndTypeOK) 16836 * 16837 * STATUS: 16838 * MISSING (3.2.3) 16839 * CLARIFY: (3.2.2) 16840 * 16841 * Returns 0 if the constraints are satisfied, a positive 16842 * error code if not and -1 if an internal error occurred. 16843 */ 16844 static int 16845 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, 16846 xmlSchemaParticlePtr r, 16847 xmlSchemaParticlePtr b) 16848 { 16849 xmlSchemaElementPtr elemR, elemB; 16850 16851 /* TODO: Error codes (rcase-NameAndTypeOK). */ 16852 elemR = (xmlSchemaElementPtr) r->children; 16853 elemB = (xmlSchemaElementPtr) b->children; 16854 /* 16855 * SPEC (1) "The declarations' {name}s and {target namespace}s are 16856 * the same." 16857 */ 16858 if ((elemR != elemB) && 16859 ((! xmlStrEqual(elemR->name, elemB->name)) || 16860 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace)))) 16861 return (1); 16862 /* 16863 * SPEC (2) "R's occurrence range is a valid restriction of B's 16864 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16865 */ 16866 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16867 b->minOccurs, b->maxOccurs) != 0) 16868 return (1); 16869 /* 16870 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's 16871 * {scope} are global." 16872 */ 16873 if (elemR == elemB) 16874 return (0); 16875 /* 16876 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false." 16877 */ 16878 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) && 16879 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE)) 16880 return (1); 16881 /* 16882 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent, 16883 * or is not fixed, or R's declaration's {value constraint} is fixed 16884 * with the same value." 16885 */ 16886 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) && 16887 ((elemR->value == NULL) || 16888 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) || 16889 /* TODO: Equality of the initial value or normalized or canonical? */ 16890 (! xmlStrEqual(elemR->value, elemB->value)))) 16891 return (1); 16892 /* 16893 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint 16894 * definitions} is a subset of B's declaration's {identity-constraint 16895 * definitions}, if any." 16896 */ 16897 if (elemB->idcs != NULL) { 16898 /* TODO */ 16899 } 16900 /* 16901 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a 16902 * superset of B's declaration's {disallowed substitutions}." 16903 */ 16904 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) && 16905 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) || 16906 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) && 16907 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) || 16908 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) && 16909 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0))) 16910 return (1); 16911 /* 16912 * SPEC (3.2.5) "R's {type definition} is validly derived given 16913 * {extension, list, union} from B's {type definition}" 16914 * 16915 * BADSPEC TODO: What's the point of adding "list" and "union" to the 16916 * set, if the corresponding constraints handle "restriction" and 16917 * "extension" only? 16918 * 16919 */ 16920 { 16921 int set = 0; 16922 16923 set |= SUBSET_EXTENSION; 16924 set |= SUBSET_LIST; 16925 set |= SUBSET_UNION; 16926 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes, 16927 elemB->subtypes, set) != 0) 16928 return (1); 16929 } 16930 return (0); 16931 } 16932 16933 /** 16934 * xmlSchemaCheckRCaseNSCompat: 16935 * @ctxt: the schema parser context 16936 * @r: the restricting element declaration particle 16937 * @b: the base wildcard particle 16938 * 16939 * (3.9.6) Constraints on Particle Schema Components 16940 * Schema Component Constraint: 16941 * Particle Derivation OK (Elt:Any -- NSCompat) 16942 * (rcase-NSCompat) 16943 * 16944 * STATUS: complete 16945 * 16946 * Returns 0 if the constraints are satisfied, a positive 16947 * error code if not and -1 if an internal error occurred. 16948 */ 16949 static int 16950 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, 16951 xmlSchemaParticlePtr r, 16952 xmlSchemaParticlePtr b) 16953 { 16954 /* TODO:Error codes (rcase-NSCompat). */ 16955 /* 16956 * SPEC "For an element declaration particle to be a `valid restriction` 16957 * of a wildcard particle all of the following must be true:" 16958 * 16959 * SPEC (1) "The element declaration's {target namespace} is `valid` 16960 * with respect to the wildcard's {namespace constraint} as defined by 16961 * Wildcard allows Namespace Name ($3.10.4)." 16962 */ 16963 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children, 16964 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0) 16965 return (1); 16966 /* 16967 * SPEC (2) "R's occurrence range is a valid restriction of B's 16968 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 16969 */ 16970 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 16971 b->minOccurs, b->maxOccurs) != 0) 16972 return (1); 16973 16974 return (0); 16975 } 16976 16977 /** 16978 * xmlSchemaCheckRCaseRecurseAsIfGroup: 16979 * @ctxt: the schema parser context 16980 * @r: the restricting element declaration particle 16981 * @b: the base model group particle 16982 * 16983 * (3.9.6) Constraints on Particle Schema Components 16984 * Schema Component Constraint: 16985 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup) 16986 * (rcase-RecurseAsIfGroup) 16987 * 16988 * STATUS: TODO 16989 * 16990 * Returns 0 if the constraints are satisfied, a positive 16991 * error code if not and -1 if an internal error occurred. 16992 */ 16993 static int 16994 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, 16995 xmlSchemaParticlePtr r, 16996 xmlSchemaParticlePtr b) 16997 { 16998 /* TODO: Error codes (rcase-RecurseAsIfGroup). */ 16999 TODO 17000 return (0); 17001 } 17002 17003 /** 17004 * xmlSchemaCheckRCaseNSSubset: 17005 * @ctxt: the schema parser context 17006 * @r: the restricting wildcard particle 17007 * @b: the base wildcard particle 17008 * 17009 * (3.9.6) Constraints on Particle Schema Components 17010 * Schema Component Constraint: 17011 * Particle Derivation OK (Any:Any -- NSSubset) 17012 * (rcase-NSSubset) 17013 * 17014 * STATUS: complete 17015 * 17016 * Returns 0 if the constraints are satisfied, a positive 17017 * error code if not and -1 if an internal error occurred. 17018 */ 17019 static int 17020 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, 17021 xmlSchemaParticlePtr r, 17022 xmlSchemaParticlePtr b, 17023 int isAnyTypeBase) 17024 { 17025 /* TODO: Error codes (rcase-NSSubset). */ 17026 /* 17027 * SPEC (1) "R's occurrence range is a valid restriction of B's 17028 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17029 */ 17030 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17031 b->minOccurs, b->maxOccurs)) 17032 return (1); 17033 /* 17034 * SPEC (2) "R's {namespace constraint} must be an intensional subset 17035 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)." 17036 */ 17037 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children, 17038 (xmlSchemaWildcardPtr) b->children)) 17039 return (1); 17040 /* 17041 * SPEC (3) "Unless B is the content model wildcard of the `ur-type 17042 * definition`, R's {process contents} must be identical to or stronger 17043 * than B's {process contents}, where strict is stronger than lax is 17044 * stronger than skip." 17045 */ 17046 if (! isAnyTypeBase) { 17047 if ( ((xmlSchemaWildcardPtr) r->children)->processContents < 17048 ((xmlSchemaWildcardPtr) b->children)->processContents) 17049 return (1); 17050 } 17051 17052 return (0); 17053 } 17054 17055 /** 17056 * xmlSchemaCheckCOSParticleRestrict: 17057 * @ctxt: the schema parser context 17058 * @type: the complex type definition 17059 * 17060 * (3.9.6) Constraints on Particle Schema Components 17061 * Schema Component Constraint: 17062 * Particle Valid (Restriction) (cos-particle-restrict) 17063 * 17064 * STATUS: TODO 17065 * 17066 * Returns 0 if the constraints are satisfied, a positive 17067 * error code if not and -1 if an internal error occurred. 17068 */ 17069 static int 17070 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, 17071 xmlSchemaParticlePtr r, 17072 xmlSchemaParticlePtr b) 17073 { 17074 int ret = 0; 17075 17076 /*part = WXS_TYPE_PARTICLE(type); 17077 basePart = WXS_TYPE_PARTICLE(base); 17078 */ 17079 17080 TODO 17081 17082 /* 17083 * SPEC (1) "They are the same particle." 17084 */ 17085 if (r == b) 17086 return (0); 17087 17088 17089 return (0); 17090 } 17091 17092 #if 0 17093 /** 17094 * xmlSchemaCheckRCaseNSRecurseCheckCardinality: 17095 * @ctxt: the schema parser context 17096 * @r: the model group particle 17097 * @b: the base wildcard particle 17098 * 17099 * (3.9.6) Constraints on Particle Schema Components 17100 * Schema Component Constraint: 17101 * Particle Derivation OK (All/Choice/Sequence:Any -- 17102 * NSRecurseCheckCardinality) 17103 * (rcase-NSRecurseCheckCardinality) 17104 * 17105 * STATUS: TODO: subst-groups 17106 * 17107 * Returns 0 if the constraints are satisfied, a positive 17108 * error code if not and -1 if an internal error occurred. 17109 */ 17110 static int 17111 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, 17112 xmlSchemaParticlePtr r, 17113 xmlSchemaParticlePtr b) 17114 { 17115 xmlSchemaParticlePtr part; 17116 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */ 17117 if ((r->children == NULL) || (r->children->children == NULL)) 17118 return (-1); 17119 /* 17120 * SPEC "For a group particle to be a `valid restriction` of a 17121 * wildcard particle..." 17122 * 17123 * SPEC (1) "Every member of the {particles} of the group is a `valid 17124 * restriction` of the wildcard as defined by 17125 * Particle Valid (Restriction) ($3.9.6)." 17126 */ 17127 part = (xmlSchemaParticlePtr) r->children->children; 17128 do { 17129 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b)) 17130 return (1); 17131 part = (xmlSchemaParticlePtr) part->next; 17132 } while (part != NULL); 17133 /* 17134 * SPEC (2) "The effective total range of the group [...] is a 17135 * valid restriction of B's occurrence range as defined by 17136 * Occurrence Range OK ($3.9.6)." 17137 */ 17138 if (xmlSchemaCheckParticleRangeOK( 17139 xmlSchemaGetParticleTotalRangeMin(r), 17140 xmlSchemaGetParticleTotalRangeMax(r), 17141 b->minOccurs, b->maxOccurs) != 0) 17142 return (1); 17143 return (0); 17144 } 17145 #endif 17146 17147 /** 17148 * xmlSchemaCheckRCaseRecurse: 17149 * @ctxt: the schema parser context 17150 * @r: the <all> or <sequence> model group particle 17151 * @b: the base <all> or <sequence> model group particle 17152 * 17153 * (3.9.6) Constraints on Particle Schema Components 17154 * Schema Component Constraint: 17155 * Particle Derivation OK (All:All,Sequence:Sequence -- 17156 Recurse) 17157 * (rcase-Recurse) 17158 * 17159 * STATUS: ? 17160 * TODO: subst-groups 17161 * 17162 * Returns 0 if the constraints are satisfied, a positive 17163 * error code if not and -1 if an internal error occurred. 17164 */ 17165 static int 17166 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, 17167 xmlSchemaParticlePtr r, 17168 xmlSchemaParticlePtr b) 17169 { 17170 /* xmlSchemaParticlePtr part; */ 17171 /* TODO: Error codes (rcase-Recurse). */ 17172 if ((r->children == NULL) || (b->children == NULL) || 17173 (r->children->type != b->children->type)) 17174 return (-1); 17175 /* 17176 * SPEC "For an all or sequence group particle to be a `valid 17177 * restriction` of another group particle with the same {compositor}..." 17178 * 17179 * SPEC (1) "R's occurrence range is a valid restriction of B's 17180 * occurrence range as defined by Occurrence Range OK ($3.9.6)." 17181 */ 17182 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs, 17183 b->minOccurs, b->maxOccurs)) 17184 return (1); 17185 17186 17187 return (0); 17188 } 17189 17190 #endif 17191 17192 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \ 17193 xmlSchemaPCustomErrExt(pctxt, \ 17194 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17195 WXS_BASIC_CAST fac1, fac1->node, \ 17196 "It is an error for both '%s' and '%s' to be specified on the "\ 17197 "same type definition", \ 17198 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \ 17199 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL); 17200 17201 #define FACET_RESTR_ERR(fac1, msg) \ 17202 xmlSchemaPCustomErr(pctxt, \ 17203 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17204 WXS_BASIC_CAST fac1, fac1->node, \ 17205 msg, NULL); 17206 17207 #define FACET_RESTR_FIXED_ERR(fac) \ 17208 xmlSchemaPCustomErr(pctxt, \ 17209 XML_SCHEMAP_INVALID_FACET_VALUE, \ 17210 WXS_BASIC_CAST fac, fac->node, \ 17211 "The base type's facet is 'fixed', thus the value must not " \ 17212 "differ", NULL); 17213 17214 static void 17215 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt, 17216 xmlSchemaFacetPtr facet1, 17217 xmlSchemaFacetPtr facet2, 17218 int lessGreater, 17219 int orEqual, 17220 int ofBase) 17221 { 17222 xmlChar *msg = NULL; 17223 17224 msg = xmlStrdup(BAD_CAST "'"); 17225 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type)); 17226 msg = xmlStrcat(msg, BAD_CAST "' has to be"); 17227 if (lessGreater == 0) 17228 msg = xmlStrcat(msg, BAD_CAST " equal to"); 17229 if (lessGreater == 1) 17230 msg = xmlStrcat(msg, BAD_CAST " greater than"); 17231 else 17232 msg = xmlStrcat(msg, BAD_CAST " less than"); 17233 17234 if (orEqual) 17235 msg = xmlStrcat(msg, BAD_CAST " or equal to"); 17236 msg = xmlStrcat(msg, BAD_CAST " '"); 17237 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type)); 17238 if (ofBase) 17239 msg = xmlStrcat(msg, BAD_CAST "' of the base type"); 17240 else 17241 msg = xmlStrcat(msg, BAD_CAST "'"); 17242 17243 xmlSchemaPCustomErr(pctxt, 17244 XML_SCHEMAP_INVALID_FACET_VALUE, 17245 WXS_BASIC_CAST facet1, NULL, 17246 (const char *) msg, NULL); 17247 17248 if (msg != NULL) 17249 xmlFree(msg); 17250 } 17251 17252 /* 17253 * xmlSchemaDeriveAndValidateFacets: 17254 * 17255 * Schema Component Constraint: Simple Type Restriction (Facets) 17256 * (st-restrict-facets) 17257 */ 17258 static int 17259 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, 17260 xmlSchemaTypePtr type) 17261 { 17262 xmlSchemaTypePtr base = type->baseType; 17263 xmlSchemaFacetLinkPtr link, cur, last = NULL; 17264 xmlSchemaFacetPtr facet, bfacet, 17265 flength = NULL, ftotdig = NULL, ffracdig = NULL, 17266 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */ 17267 fmininc = NULL, fmaxinc = NULL, 17268 fminexc = NULL, fmaxexc = NULL, 17269 bflength = NULL, bftotdig = NULL, bffracdig = NULL, 17270 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */ 17271 bfmininc = NULL, bfmaxinc = NULL, 17272 bfminexc = NULL, bfmaxexc = NULL; 17273 int res; /* err = 0, fixedErr; */ 17274 17275 /* 17276 * SPEC st-restrict-facets 1: 17277 * "The {variety} of R is the same as that of B." 17278 */ 17279 /* 17280 * SPEC st-restrict-facets 2: 17281 * "If {variety} is atomic, the {primitive type definition} 17282 * of R is the same as that of B." 17283 * 17284 * NOTE: we leave 1 & 2 out for now, since this will be 17285 * satisfied by the derivation process. 17286 * CONSTRUCTION TODO: Maybe needed if using a construction API. 17287 */ 17288 /* 17289 * SPEC st-restrict-facets 3: 17290 * "The {facets} of R are the union of S and the {facets} 17291 * of B, eliminating duplicates. To eliminate duplicates, 17292 * when a facet of the same kind occurs in both S and the 17293 * {facets} of B, the one in the {facets} of B is not 17294 * included, with the exception of enumeration and pattern 17295 * facets, for which multiple occurrences with distinct values 17296 * are allowed." 17297 */ 17298 17299 if ((type->facetSet == NULL) && (base->facetSet == NULL)) 17300 return (0); 17301 17302 last = type->facetSet; 17303 if (last != NULL) 17304 while (last->next != NULL) 17305 last = last->next; 17306 17307 for (cur = type->facetSet; cur != NULL; cur = cur->next) { 17308 facet = cur->facet; 17309 switch (facet->type) { 17310 case XML_SCHEMA_FACET_LENGTH: 17311 flength = facet; break; 17312 case XML_SCHEMA_FACET_MINLENGTH: 17313 fminlen = facet; break; 17314 case XML_SCHEMA_FACET_MININCLUSIVE: 17315 fmininc = facet; break; 17316 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17317 fminexc = facet; break; 17318 case XML_SCHEMA_FACET_MAXLENGTH: 17319 fmaxlen = facet; break; 17320 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17321 fmaxinc = facet; break; 17322 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17323 fmaxexc = facet; break; 17324 case XML_SCHEMA_FACET_TOTALDIGITS: 17325 ftotdig = facet; break; 17326 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17327 ffracdig = facet; break; 17328 default: 17329 break; 17330 } 17331 } 17332 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17333 facet = cur->facet; 17334 switch (facet->type) { 17335 case XML_SCHEMA_FACET_LENGTH: 17336 bflength = facet; break; 17337 case XML_SCHEMA_FACET_MINLENGTH: 17338 bfminlen = facet; break; 17339 case XML_SCHEMA_FACET_MININCLUSIVE: 17340 bfmininc = facet; break; 17341 case XML_SCHEMA_FACET_MINEXCLUSIVE: 17342 bfminexc = facet; break; 17343 case XML_SCHEMA_FACET_MAXLENGTH: 17344 bfmaxlen = facet; break; 17345 case XML_SCHEMA_FACET_MAXINCLUSIVE: 17346 bfmaxinc = facet; break; 17347 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 17348 bfmaxexc = facet; break; 17349 case XML_SCHEMA_FACET_TOTALDIGITS: 17350 bftotdig = facet; break; 17351 case XML_SCHEMA_FACET_FRACTIONDIGITS: 17352 bffracdig = facet; break; 17353 default: 17354 break; 17355 } 17356 } 17357 /* 17358 * length and minLength or maxLength (2.2) + (3.2) 17359 */ 17360 if (flength && (fminlen || fmaxlen)) { 17361 FACET_RESTR_ERR(flength, "It is an error for both 'length' and " 17362 "either of 'minLength' or 'maxLength' to be specified on " 17363 "the same type definition") 17364 } 17365 /* 17366 * Mutual exclusions in the same derivation step. 17367 */ 17368 if ((fmaxinc) && (fmaxexc)) { 17369 /* 17370 * SCC "maxInclusive and maxExclusive" 17371 */ 17372 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc) 17373 } 17374 if ((fmininc) && (fminexc)) { 17375 /* 17376 * SCC "minInclusive and minExclusive" 17377 */ 17378 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc) 17379 } 17380 17381 if (flength && bflength) { 17382 /* 17383 * SCC "length valid restriction" 17384 * The values have to be equal. 17385 */ 17386 res = xmlSchemaCompareValues(flength->val, bflength->val); 17387 if (res == -2) 17388 goto internal_error; 17389 if (res != 0) 17390 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1); 17391 if ((res != 0) && (bflength->fixed)) { 17392 FACET_RESTR_FIXED_ERR(flength) 17393 } 17394 17395 } 17396 if (fminlen && bfminlen) { 17397 /* 17398 * SCC "minLength valid restriction" 17399 * minLength >= BASE minLength 17400 */ 17401 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val); 17402 if (res == -2) 17403 goto internal_error; 17404 if (res == -1) 17405 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1); 17406 if ((res != 0) && (bfminlen->fixed)) { 17407 FACET_RESTR_FIXED_ERR(fminlen) 17408 } 17409 } 17410 if (fmaxlen && bfmaxlen) { 17411 /* 17412 * SCC "maxLength valid restriction" 17413 * maxLength <= BASE minLength 17414 */ 17415 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val); 17416 if (res == -2) 17417 goto internal_error; 17418 if (res == 1) 17419 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1); 17420 if ((res != 0) && (bfmaxlen->fixed)) { 17421 FACET_RESTR_FIXED_ERR(fmaxlen) 17422 } 17423 } 17424 /* 17425 * SCC "length and minLength or maxLength" 17426 */ 17427 if (! flength) 17428 flength = bflength; 17429 if (flength) { 17430 if (! fminlen) 17431 fminlen = bfminlen; 17432 if (fminlen) { 17433 /* (1.1) length >= minLength */ 17434 res = xmlSchemaCompareValues(flength->val, fminlen->val); 17435 if (res == -2) 17436 goto internal_error; 17437 if (res == -1) 17438 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0); 17439 } 17440 if (! fmaxlen) 17441 fmaxlen = bfmaxlen; 17442 if (fmaxlen) { 17443 /* (2.1) length <= maxLength */ 17444 res = xmlSchemaCompareValues(flength->val, fmaxlen->val); 17445 if (res == -2) 17446 goto internal_error; 17447 if (res == 1) 17448 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0); 17449 } 17450 } 17451 if (fmaxinc) { 17452 /* 17453 * "maxInclusive" 17454 */ 17455 if (fmininc) { 17456 /* SCC "maxInclusive >= minInclusive" */ 17457 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val); 17458 if (res == -2) 17459 goto internal_error; 17460 if (res == -1) { 17461 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0); 17462 } 17463 } 17464 /* 17465 * SCC "maxInclusive valid restriction" 17466 */ 17467 if (bfmaxinc) { 17468 /* maxInclusive <= BASE maxInclusive */ 17469 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val); 17470 if (res == -2) 17471 goto internal_error; 17472 if (res == 1) 17473 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1); 17474 if ((res != 0) && (bfmaxinc->fixed)) { 17475 FACET_RESTR_FIXED_ERR(fmaxinc) 17476 } 17477 } 17478 if (bfmaxexc) { 17479 /* maxInclusive < BASE maxExclusive */ 17480 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val); 17481 if (res == -2) 17482 goto internal_error; 17483 if (res != -1) { 17484 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1); 17485 } 17486 } 17487 if (bfmininc) { 17488 /* maxInclusive >= BASE minInclusive */ 17489 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val); 17490 if (res == -2) 17491 goto internal_error; 17492 if (res == -1) { 17493 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1); 17494 } 17495 } 17496 if (bfminexc) { 17497 /* maxInclusive > BASE minExclusive */ 17498 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val); 17499 if (res == -2) 17500 goto internal_error; 17501 if (res != 1) { 17502 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1); 17503 } 17504 } 17505 } 17506 if (fmaxexc) { 17507 /* 17508 * "maxExclusive >= minExclusive" 17509 */ 17510 if (fminexc) { 17511 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val); 17512 if (res == -2) 17513 goto internal_error; 17514 if (res == -1) { 17515 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0); 17516 } 17517 } 17518 /* 17519 * "maxExclusive valid restriction" 17520 */ 17521 if (bfmaxexc) { 17522 /* maxExclusive <= BASE maxExclusive */ 17523 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val); 17524 if (res == -2) 17525 goto internal_error; 17526 if (res == 1) { 17527 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1); 17528 } 17529 if ((res != 0) && (bfmaxexc->fixed)) { 17530 FACET_RESTR_FIXED_ERR(fmaxexc) 17531 } 17532 } 17533 if (bfmaxinc) { 17534 /* maxExclusive <= BASE maxInclusive */ 17535 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val); 17536 if (res == -2) 17537 goto internal_error; 17538 if (res == 1) { 17539 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1); 17540 } 17541 } 17542 if (bfmininc) { 17543 /* maxExclusive > BASE minInclusive */ 17544 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val); 17545 if (res == -2) 17546 goto internal_error; 17547 if (res != 1) { 17548 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1); 17549 } 17550 } 17551 if (bfminexc) { 17552 /* maxExclusive > BASE minExclusive */ 17553 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val); 17554 if (res == -2) 17555 goto internal_error; 17556 if (res != 1) { 17557 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1); 17558 } 17559 } 17560 } 17561 if (fminexc) { 17562 /* 17563 * "minExclusive < maxInclusive" 17564 */ 17565 if (fmaxinc) { 17566 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val); 17567 if (res == -2) 17568 goto internal_error; 17569 if (res != -1) { 17570 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0); 17571 } 17572 } 17573 /* 17574 * "minExclusive valid restriction" 17575 */ 17576 if (bfminexc) { 17577 /* minExclusive >= BASE minExclusive */ 17578 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val); 17579 if (res == -2) 17580 goto internal_error; 17581 if (res == -1) { 17582 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1); 17583 } 17584 if ((res != 0) && (bfminexc->fixed)) { 17585 FACET_RESTR_FIXED_ERR(fminexc) 17586 } 17587 } 17588 if (bfmaxinc) { 17589 /* minExclusive <= BASE maxInclusive */ 17590 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val); 17591 if (res == -2) 17592 goto internal_error; 17593 if (res == 1) { 17594 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1); 17595 } 17596 } 17597 if (bfmininc) { 17598 /* minExclusive >= BASE minInclusive */ 17599 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val); 17600 if (res == -2) 17601 goto internal_error; 17602 if (res == -1) { 17603 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1); 17604 } 17605 } 17606 if (bfmaxexc) { 17607 /* minExclusive < BASE maxExclusive */ 17608 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val); 17609 if (res == -2) 17610 goto internal_error; 17611 if (res != -1) { 17612 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1); 17613 } 17614 } 17615 } 17616 if (fmininc) { 17617 /* 17618 * "minInclusive < maxExclusive" 17619 */ 17620 if (fmaxexc) { 17621 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val); 17622 if (res == -2) 17623 goto internal_error; 17624 if (res != -1) { 17625 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0); 17626 } 17627 } 17628 /* 17629 * "minExclusive valid restriction" 17630 */ 17631 if (bfmininc) { 17632 /* minInclusive >= BASE minInclusive */ 17633 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val); 17634 if (res == -2) 17635 goto internal_error; 17636 if (res == -1) { 17637 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1); 17638 } 17639 if ((res != 0) && (bfmininc->fixed)) { 17640 FACET_RESTR_FIXED_ERR(fmininc) 17641 } 17642 } 17643 if (bfmaxinc) { 17644 /* minInclusive <= BASE maxInclusive */ 17645 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val); 17646 if (res == -2) 17647 goto internal_error; 17648 if (res == 1) { 17649 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1); 17650 } 17651 } 17652 if (bfminexc) { 17653 /* minInclusive > BASE minExclusive */ 17654 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val); 17655 if (res == -2) 17656 goto internal_error; 17657 if (res != 1) 17658 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1); 17659 } 17660 if (bfmaxexc) { 17661 /* minInclusive < BASE maxExclusive */ 17662 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val); 17663 if (res == -2) 17664 goto internal_error; 17665 if (res != -1) 17666 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1); 17667 } 17668 } 17669 if (ftotdig && bftotdig) { 17670 /* 17671 * SCC " totalDigits valid restriction" 17672 * totalDigits <= BASE totalDigits 17673 */ 17674 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val); 17675 if (res == -2) 17676 goto internal_error; 17677 if (res == 1) 17678 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig, 17679 -1, 1, 1); 17680 if ((res != 0) && (bftotdig->fixed)) { 17681 FACET_RESTR_FIXED_ERR(ftotdig) 17682 } 17683 } 17684 if (ffracdig && bffracdig) { 17685 /* 17686 * SCC "fractionDigits valid restriction" 17687 * fractionDigits <= BASE fractionDigits 17688 */ 17689 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val); 17690 if (res == -2) 17691 goto internal_error; 17692 if (res == 1) 17693 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig, 17694 -1, 1, 1); 17695 if ((res != 0) && (bffracdig->fixed)) { 17696 FACET_RESTR_FIXED_ERR(ffracdig) 17697 } 17698 } 17699 /* 17700 * SCC "fractionDigits less than or equal to totalDigits" 17701 */ 17702 if (! ftotdig) 17703 ftotdig = bftotdig; 17704 if (! ffracdig) 17705 ffracdig = bffracdig; 17706 if (ftotdig && ffracdig) { 17707 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val); 17708 if (res == -2) 17709 goto internal_error; 17710 if (res == 1) 17711 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig, 17712 -1, 1, 0); 17713 } 17714 /* 17715 * *Enumerations* won' be added here, since only the first set 17716 * of enumerations in the ancestor-or-self axis is used 17717 * for validation, plus we need to use the base type of those 17718 * enumerations for whitespace. 17719 * 17720 * *Patterns*: won't be add here, since they are ORed at 17721 * type level and ANDed at ancestor level. This will 17722 * happed during validation by walking the base axis 17723 * of the type. 17724 */ 17725 for (cur = base->facetSet; cur != NULL; cur = cur->next) { 17726 bfacet = cur->facet; 17727 /* 17728 * Special handling of enumerations and patterns. 17729 * TODO: hmm, they should not appear in the set, so remove this. 17730 */ 17731 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) || 17732 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION)) 17733 continue; 17734 /* 17735 * Search for a duplicate facet in the current type. 17736 */ 17737 link = type->facetSet; 17738 /* err = 0; */ 17739 /* fixedErr = 0; */ 17740 while (link != NULL) { 17741 facet = link->facet; 17742 if (facet->type == bfacet->type) { 17743 switch (facet->type) { 17744 case XML_SCHEMA_FACET_WHITESPACE: 17745 /* 17746 * The whitespace must be stronger. 17747 */ 17748 if (facet->whitespace < bfacet->whitespace) { 17749 FACET_RESTR_ERR(facet, 17750 "The 'whitespace' value has to be equal to " 17751 "or stronger than the 'whitespace' value of " 17752 "the base type") 17753 } 17754 if ((bfacet->fixed) && 17755 (facet->whitespace != bfacet->whitespace)) { 17756 FACET_RESTR_FIXED_ERR(facet) 17757 } 17758 break; 17759 default: 17760 break; 17761 } 17762 /* Duplicate found. */ 17763 break; 17764 } 17765 link = link->next; 17766 } 17767 /* 17768 * If no duplicate was found: add the base types's facet 17769 * to the set. 17770 */ 17771 if (link == NULL) { 17772 link = (xmlSchemaFacetLinkPtr) 17773 xmlMalloc(sizeof(xmlSchemaFacetLink)); 17774 if (link == NULL) { 17775 xmlSchemaPErrMemory(pctxt, 17776 "deriving facets, creating a facet link", NULL); 17777 return (-1); 17778 } 17779 link->facet = cur->facet; 17780 link->next = NULL; 17781 if (last == NULL) 17782 type->facetSet = link; 17783 else 17784 last->next = link; 17785 last = link; 17786 } 17787 17788 } 17789 17790 return (0); 17791 internal_error: 17792 PERROR_INT("xmlSchemaDeriveAndValidateFacets", 17793 "an error occurred"); 17794 return (-1); 17795 } 17796 17797 static int 17798 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt, 17799 xmlSchemaTypePtr type) 17800 { 17801 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink; 17802 /* 17803 * The actual value is then formed by replacing any union type 17804 * definition in the `explicit members` with the members of their 17805 * {member type definitions}, in order. 17806 * 17807 * TODO: There's a bug entry at 17808 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html" 17809 * which indicates that we'll keep the union types the future. 17810 */ 17811 link = type->memberTypes; 17812 while (link != NULL) { 17813 17814 if (WXS_IS_TYPE_NOT_FIXED(link->type)) 17815 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt); 17816 17817 if (WXS_IS_UNION(link->type)) { 17818 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type); 17819 if (subLink != NULL) { 17820 link->type = subLink->type; 17821 if (subLink->next != NULL) { 17822 lastLink = link->next; 17823 subLink = subLink->next; 17824 prevLink = link; 17825 while (subLink != NULL) { 17826 newLink = (xmlSchemaTypeLinkPtr) 17827 xmlMalloc(sizeof(xmlSchemaTypeLink)); 17828 if (newLink == NULL) { 17829 xmlSchemaPErrMemory(pctxt, "allocating a type link", 17830 NULL); 17831 return (-1); 17832 } 17833 newLink->type = subLink->type; 17834 prevLink->next = newLink; 17835 prevLink = newLink; 17836 newLink->next = lastLink; 17837 17838 subLink = subLink->next; 17839 } 17840 } 17841 } 17842 } 17843 link = link->next; 17844 } 17845 return (0); 17846 } 17847 17848 static void 17849 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type) 17850 { 17851 int has = 0, needVal = 0, normVal = 0; 17852 17853 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0; 17854 if (has) { 17855 needVal = (type->baseType->flags & 17856 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0; 17857 normVal = (type->baseType->flags & 17858 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0; 17859 } 17860 if (type->facets != NULL) { 17861 xmlSchemaFacetPtr fac; 17862 17863 for (fac = type->facets; fac != NULL; fac = fac->next) { 17864 switch (fac->type) { 17865 case XML_SCHEMA_FACET_WHITESPACE: 17866 break; 17867 case XML_SCHEMA_FACET_PATTERN: 17868 normVal = 1; 17869 has = 1; 17870 break; 17871 case XML_SCHEMA_FACET_ENUMERATION: 17872 needVal = 1; 17873 normVal = 1; 17874 has = 1; 17875 break; 17876 default: 17877 has = 1; 17878 break; 17879 } 17880 } 17881 } 17882 if (normVal) 17883 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED; 17884 if (needVal) 17885 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17886 if (has) 17887 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS; 17888 17889 if (has && (! needVal) && WXS_IS_ATOMIC(type)) { 17890 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type); 17891 /* 17892 * OPTIMIZE VAL TODO: Some facets need a computed value. 17893 */ 17894 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) && 17895 (prim->builtInType != XML_SCHEMAS_STRING)) { 17896 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE; 17897 } 17898 } 17899 } 17900 17901 static int 17902 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type) 17903 { 17904 17905 17906 /* 17907 * Evaluate the whitespace-facet value. 17908 */ 17909 if (WXS_IS_LIST(type)) { 17910 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17911 return (0); 17912 } else if (WXS_IS_UNION(type)) 17913 return (0); 17914 17915 if (type->facetSet != NULL) { 17916 xmlSchemaFacetLinkPtr lin; 17917 17918 for (lin = type->facetSet; lin != NULL; lin = lin->next) { 17919 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { 17920 switch (lin->facet->whitespace) { 17921 case XML_SCHEMAS_FACET_PRESERVE: 17922 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17923 break; 17924 case XML_SCHEMAS_FACET_REPLACE: 17925 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17926 break; 17927 case XML_SCHEMAS_FACET_COLLAPSE: 17928 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17929 break; 17930 default: 17931 return (-1); 17932 } 17933 return (0); 17934 } 17935 } 17936 } 17937 /* 17938 * For all `atomic` datatypes other than string (and types `derived` 17939 * by `restriction` from it) the value of whiteSpace is fixed to 17940 * collapse 17941 */ 17942 { 17943 xmlSchemaTypePtr anc; 17944 17945 for (anc = type->baseType; anc != NULL && 17946 anc->builtInType != XML_SCHEMAS_ANYTYPE; 17947 anc = anc->baseType) { 17948 17949 if (anc->type == XML_SCHEMA_TYPE_BASIC) { 17950 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) { 17951 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE; 17952 17953 } else if ((anc->builtInType == XML_SCHEMAS_STRING) || 17954 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) { 17955 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE; 17956 17957 } else 17958 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE; 17959 break; 17960 } 17961 } 17962 } 17963 return (0); 17964 } 17965 17966 static int 17967 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt, 17968 xmlSchemaTypePtr type) 17969 { 17970 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 17971 return(0); 17972 if (! WXS_IS_TYPE_NOT_FIXED_1(type)) 17973 return(0); 17974 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1; 17975 17976 if (WXS_IS_LIST(type)) { 17977 /* 17978 * Corresponds to <simpleType><list>... 17979 */ 17980 if (type->subtypes == NULL) { 17981 /* 17982 * This one is really needed, so get out. 17983 */ 17984 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17985 "list type has no item-type assigned"); 17986 return(-1); 17987 } 17988 } else if (WXS_IS_UNION(type)) { 17989 /* 17990 * Corresponds to <simpleType><union>... 17991 */ 17992 if (type->memberTypes == NULL) { 17993 /* 17994 * This one is really needed, so get out. 17995 */ 17996 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 17997 "union type has no member-types assigned"); 17998 return(-1); 17999 } 18000 } else { 18001 /* 18002 * Corresponds to <simpleType><restriction>... 18003 */ 18004 if (type->baseType == NULL) { 18005 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne", 18006 "type has no base-type assigned"); 18007 return(-1); 18008 } 18009 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType)) 18010 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1) 18011 return(-1); 18012 /* 18013 * Variety 18014 * If the <restriction> alternative is chosen, then the 18015 * {variety} of the {base type definition}. 18016 */ 18017 if (WXS_IS_ATOMIC(type->baseType)) 18018 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC; 18019 else if (WXS_IS_LIST(type->baseType)) { 18020 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST; 18021 /* 18022 * Inherit the itemType. 18023 */ 18024 type->subtypes = type->baseType->subtypes; 18025 } else if (WXS_IS_UNION(type->baseType)) { 18026 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION; 18027 /* 18028 * NOTE that we won't assign the memberTypes of the base, 18029 * since this will make trouble when freeing them; we will 18030 * use a lookup function to access them instead. 18031 */ 18032 } 18033 } 18034 return(0); 18035 } 18036 18037 #ifdef DEBUG_TYPE 18038 static void 18039 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt, 18040 xmlSchemaTypePtr type) 18041 { 18042 if (type->node != NULL) { 18043 xmlGenericError(xmlGenericErrorContext, 18044 "Type of %s : %s:%d :", name, 18045 type->node->doc->URL, 18046 xmlGetLineNo(type->node)); 18047 } else { 18048 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name); 18049 } 18050 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) { 18051 switch (type->contentType) { 18052 case XML_SCHEMA_CONTENT_SIMPLE: 18053 xmlGenericError(xmlGenericErrorContext, "simple\n"); 18054 break; 18055 case XML_SCHEMA_CONTENT_ELEMENTS: 18056 xmlGenericError(xmlGenericErrorContext, "elements\n"); 18057 break; 18058 case XML_SCHEMA_CONTENT_UNKNOWN: 18059 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n"); 18060 break; 18061 case XML_SCHEMA_CONTENT_EMPTY: 18062 xmlGenericError(xmlGenericErrorContext, "empty\n"); 18063 break; 18064 case XML_SCHEMA_CONTENT_MIXED: 18065 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr) 18066 type->subtypes)) 18067 xmlGenericError(xmlGenericErrorContext, 18068 "mixed as emptiable particle\n"); 18069 else 18070 xmlGenericError(xmlGenericErrorContext, "mixed\n"); 18071 break; 18072 /* Removed, since not used. */ 18073 /* 18074 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS: 18075 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n"); 18076 break; 18077 */ 18078 case XML_SCHEMA_CONTENT_BASIC: 18079 xmlGenericError(xmlGenericErrorContext, "basic\n"); 18080 break; 18081 default: 18082 xmlGenericError(xmlGenericErrorContext, 18083 "not registered !!!\n"); 18084 break; 18085 } 18086 } 18087 } 18088 #endif 18089 18090 /* 18091 * 3.14.6 Constraints on Simple Type Definition Schema Components 18092 */ 18093 static int 18094 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt, 18095 xmlSchemaTypePtr type) 18096 { 18097 int res, olderrs = pctxt->nberrors; 18098 18099 if (type->type != XML_SCHEMA_TYPE_SIMPLE) 18100 return(-1); 18101 18102 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18103 return(0); 18104 18105 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18106 type->contentType = XML_SCHEMA_CONTENT_SIMPLE; 18107 18108 if (type->baseType == NULL) { 18109 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo", 18110 "missing baseType"); 18111 goto exit_failure; 18112 } 18113 if (WXS_IS_TYPE_NOT_FIXED(type->baseType)) 18114 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt); 18115 /* 18116 * If a member type of a union is a union itself, we need to substitute 18117 * that member type for its member types. 18118 * NOTE that this might change in WXS 1.1; i.e. we will keep the union 18119 * types in WXS 1.1. 18120 */ 18121 if ((type->memberTypes != NULL) && 18122 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1)) 18123 return(-1); 18124 /* 18125 * SPEC src-simple-type 1 18126 * "The corresponding simple type definition, if any, must satisfy 18127 * the conditions set out in Constraints on Simple Type Definition 18128 * Schema Components ($3.14.6)." 18129 */ 18130 /* 18131 * Schema Component Constraint: Simple Type Definition Properties Correct 18132 * (st-props-correct) 18133 */ 18134 res = xmlSchemaCheckSTPropsCorrect(pctxt, type); 18135 HFAILURE HERROR 18136 /* 18137 * Schema Component Constraint: Derivation Valid (Restriction, Simple) 18138 * (cos-st-restricts) 18139 */ 18140 res = xmlSchemaCheckCOSSTRestricts(pctxt, type); 18141 HFAILURE HERROR 18142 /* 18143 * TODO: Removed the error report, since it got annoying to get an 18144 * extra error report, if anything failed until now. 18145 * Enable this if needed. 18146 * 18147 * xmlSchemaPErr(ctxt, type->node, 18148 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1, 18149 * "Simple type '%s' does not satisfy the constraints " 18150 * "on simple type definitions.\n", 18151 * type->name, NULL); 18152 */ 18153 /* 18154 * Schema Component Constraint: Simple Type Restriction (Facets) 18155 * (st-restrict-facets) 18156 */ 18157 res = xmlSchemaCheckFacetValues(type, pctxt); 18158 HFAILURE HERROR 18159 if ((type->facetSet != NULL) || 18160 (type->baseType->facetSet != NULL)) { 18161 res = xmlSchemaDeriveAndValidateFacets(pctxt, type); 18162 HFAILURE HERROR 18163 } 18164 /* 18165 * Whitespace value. 18166 */ 18167 res = xmlSchemaTypeFixupWhitespace(type); 18168 HFAILURE HERROR 18169 xmlSchemaTypeFixupOptimFacets(type); 18170 18171 exit_error: 18172 #ifdef DEBUG_TYPE 18173 xmlSchemaDebugFixedType(pctxt, type); 18174 #endif 18175 if (olderrs != pctxt->nberrors) 18176 return(pctxt->err); 18177 return(0); 18178 18179 exit_failure: 18180 #ifdef DEBUG_TYPE 18181 xmlSchemaDebugFixedType(pctxt, type); 18182 #endif 18183 return(-1); 18184 } 18185 18186 static int 18187 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt, 18188 xmlSchemaTypePtr type) 18189 { 18190 int res = 0, olderrs = pctxt->nberrors; 18191 xmlSchemaTypePtr baseType = type->baseType; 18192 18193 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18194 return(0); 18195 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED; 18196 if (baseType == NULL) { 18197 PERROR_INT("xmlSchemaFixupComplexType", 18198 "missing baseType"); 18199 goto exit_failure; 18200 } 18201 /* 18202 * Fixup the base type. 18203 */ 18204 if (WXS_IS_TYPE_NOT_FIXED(baseType)) 18205 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt); 18206 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) { 18207 /* 18208 * Skip fixup if the base type is invalid. 18209 * TODO: Generate a warning! 18210 */ 18211 return(0); 18212 } 18213 /* 18214 * This basically checks if the base type can be derived. 18215 */ 18216 res = xmlSchemaCheckSRCCT(pctxt, type); 18217 HFAILURE HERROR 18218 /* 18219 * Fixup the content type. 18220 */ 18221 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) { 18222 /* 18223 * Corresponds to <complexType><simpleContent>... 18224 */ 18225 if ((WXS_IS_COMPLEX(baseType)) && 18226 (baseType->contentTypeDef != NULL) && 18227 (WXS_IS_RESTRICTION(type))) { 18228 xmlSchemaTypePtr contentBase, content; 18229 #ifdef ENABLE_NAMED_LOCALS 18230 char buf[30]; 18231 const xmlChar *tmpname; 18232 #endif 18233 /* 18234 * SPEC (1) If <restriction> + base type is <complexType>, 18235 * "whose own {content type} is a simple type..." 18236 */ 18237 if (type->contentTypeDef != NULL) { 18238 /* 18239 * SPEC (1.1) "the simple type definition corresponding to the 18240 * <simpleType> among the [children] of <restriction> if there 18241 * is one;" 18242 * Note that this "<simpleType> among the [children]" was put 18243 * into ->contentTypeDef during parsing. 18244 */ 18245 contentBase = type->contentTypeDef; 18246 type->contentTypeDef = NULL; 18247 } else { 18248 /* 18249 * (1.2) "...otherwise (<restriction> has no <simpleType> 18250 * among its [children]), the simple type definition which 18251 * is the {content type} of the ... base type." 18252 */ 18253 contentBase = baseType->contentTypeDef; 18254 } 18255 /* 18256 * SPEC 18257 * "... a simple type definition which restricts the simple 18258 * type definition identified in clause 1.1 or clause 1.2 18259 * with a set of facet components" 18260 * 18261 * Create the anonymous simple type, which will be the content 18262 * type of the complex type. 18263 */ 18264 #ifdef ENABLE_NAMED_LOCALS 18265 snprintf(buf, 29, "#scST%d", ++(pctxt->counter)); 18266 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1); 18267 content = xmlSchemaAddType(pctxt, pctxt->schema, 18268 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace, 18269 type->node, 0); 18270 #else 18271 content = xmlSchemaAddType(pctxt, pctxt->schema, 18272 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace, 18273 type->node, 0); 18274 #endif 18275 if (content == NULL) 18276 goto exit_failure; 18277 /* 18278 * We will use the same node as for the <complexType> 18279 * to have it somehow anchored in the schema doc. 18280 */ 18281 content->type = XML_SCHEMA_TYPE_SIMPLE; 18282 content->baseType = contentBase; 18283 /* 18284 * Move the facets, previously anchored on the 18285 * complexType during parsing. 18286 */ 18287 content->facets = type->facets; 18288 type->facets = NULL; 18289 content->facetSet = type->facetSet; 18290 type->facetSet = NULL; 18291 18292 type->contentTypeDef = content; 18293 if (WXS_IS_TYPE_NOT_FIXED(contentBase)) 18294 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt); 18295 /* 18296 * Fixup the newly created type. We don't need to check 18297 * for circularity here. 18298 */ 18299 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content); 18300 HFAILURE HERROR 18301 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content); 18302 HFAILURE HERROR 18303 18304 } else if ((WXS_IS_COMPLEX(baseType)) && 18305 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) && 18306 (WXS_IS_RESTRICTION(type))) { 18307 /* 18308 * SPEC (2) If <restriction> + base is a mixed <complexType> with 18309 * an emptiable particle, then a simple type definition which 18310 * restricts the <restriction>'s <simpleType> child. 18311 */ 18312 if ((type->contentTypeDef == NULL) || 18313 (type->contentTypeDef->baseType == NULL)) { 18314 /* 18315 * TODO: Check if this ever happens. 18316 */ 18317 xmlSchemaPCustomErr(pctxt, 18318 XML_SCHEMAP_INTERNAL, 18319 WXS_BASIC_CAST type, NULL, 18320 "Internal error: xmlSchemaTypeFixup, " 18321 "complex type '%s': the <simpleContent><restriction> " 18322 "is missing a <simpleType> child, but was not catched " 18323 "by xmlSchemaCheckSRCCT()", type->name); 18324 goto exit_failure; 18325 } 18326 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) { 18327 /* 18328 * SPEC (3) If <extension> + base is <complexType> with 18329 * <simpleType> content, "...then the {content type} of that 18330 * complex type definition" 18331 */ 18332 if (baseType->contentTypeDef == NULL) { 18333 /* 18334 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT 18335 * should have catched this already. 18336 */ 18337 xmlSchemaPCustomErr(pctxt, 18338 XML_SCHEMAP_INTERNAL, 18339 WXS_BASIC_CAST type, NULL, 18340 "Internal error: xmlSchemaTypeFixup, " 18341 "complex type '%s': the <extension>ed base type is " 18342 "a complex type with no simple content type", 18343 type->name); 18344 goto exit_failure; 18345 } 18346 type->contentTypeDef = baseType->contentTypeDef; 18347 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) { 18348 /* 18349 * SPEC (4) <extension> + base is <simpleType> 18350 * "... then that simple type definition" 18351 */ 18352 type->contentTypeDef = baseType; 18353 } else { 18354 /* 18355 * TODO: Check if this ever happens. 18356 */ 18357 xmlSchemaPCustomErr(pctxt, 18358 XML_SCHEMAP_INTERNAL, 18359 WXS_BASIC_CAST type, NULL, 18360 "Internal error: xmlSchemaTypeFixup, " 18361 "complex type '%s' with <simpleContent>: unhandled " 18362 "derivation case", type->name); 18363 goto exit_failure; 18364 } 18365 } else { 18366 int dummySequence = 0; 18367 xmlSchemaParticlePtr particle = 18368 (xmlSchemaParticlePtr) type->subtypes; 18369 /* 18370 * Corresponds to <complexType><complexContent>... 18371 * 18372 * NOTE that the effective mixed was already set during parsing of 18373 * <complexType> and <complexContent>; its flag value is 18374 * XML_SCHEMAS_TYPE_MIXED. 18375 * 18376 * Compute the "effective content": 18377 * (2.1.1) + (2.1.2) + (2.1.3) 18378 */ 18379 if ((particle == NULL) || 18380 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) && 18381 ((particle->children->type == XML_SCHEMA_TYPE_ALL) || 18382 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) || 18383 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) && 18384 (particle->minOccurs == 0))) && 18385 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) { 18386 if (type->flags & XML_SCHEMAS_TYPE_MIXED) { 18387 /* 18388 * SPEC (2.1.4) "If the `effective mixed` is true, then 18389 * a particle whose properties are as follows:..." 18390 * 18391 * Empty sequence model group with 18392 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable"). 18393 * NOTE that we sill assign it the <complexType> node to 18394 * somehow anchor it in the doc. 18395 */ 18396 if ((particle == NULL) || 18397 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) { 18398 /* 18399 * Create the particle. 18400 */ 18401 particle = xmlSchemaAddParticle(pctxt, 18402 type->node, 1, 1); 18403 if (particle == NULL) 18404 goto exit_failure; 18405 /* 18406 * Create the model group. 18407 */ /* URGENT TODO: avoid adding to pending items. */ 18408 particle->children = (xmlSchemaTreeItemPtr) 18409 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18410 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18411 if (particle->children == NULL) 18412 goto exit_failure; 18413 18414 type->subtypes = (xmlSchemaTypePtr) particle; 18415 } 18416 dummySequence = 1; 18417 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18418 } else { 18419 /* 18420 * SPEC (2.1.5) "otherwise empty" 18421 */ 18422 type->contentType = XML_SCHEMA_CONTENT_EMPTY; 18423 } 18424 } else { 18425 /* 18426 * SPEC (2.2) "otherwise the particle corresponding to the 18427 * <all>, <choice>, <group> or <sequence> among the 18428 * [children]." 18429 */ 18430 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS; 18431 } 18432 /* 18433 * Compute the "content type". 18434 */ 18435 if (WXS_IS_RESTRICTION(type)) { 18436 /* 18437 * SPEC (3.1) "If <restriction>..." 18438 * (3.1.1) + (3.1.2) */ 18439 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) { 18440 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18441 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18442 } 18443 } else { 18444 /* 18445 * SPEC (3.2) "If <extension>..." 18446 */ 18447 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18448 /* 18449 * SPEC (3.2.1) 18450 * "If the `effective content` is empty, then the 18451 * {content type} of the [...] base ..." 18452 */ 18453 type->contentType = baseType->contentType; 18454 type->subtypes = baseType->subtypes; 18455 /* 18456 * Fixes bug #347316: 18457 * This is the case when the base type has a simple 18458 * type definition as content. 18459 */ 18460 type->contentTypeDef = baseType->contentTypeDef; 18461 /* 18462 * NOTE that the effective mixed is ignored here. 18463 */ 18464 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) { 18465 /* 18466 * SPEC (3.2.2) 18467 */ 18468 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18469 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18470 } else { 18471 /* 18472 * SPEC (3.2.3) 18473 */ 18474 if (type->flags & XML_SCHEMAS_TYPE_MIXED) 18475 type->contentType = XML_SCHEMA_CONTENT_MIXED; 18476 /* 18477 * "A model group whose {compositor} is sequence and whose 18478 * {particles} are..." 18479 */ 18480 if ((WXS_TYPE_PARTICLE(type) != NULL) && 18481 (WXS_TYPE_PARTICLE_TERM(type) != NULL) && 18482 ((WXS_TYPE_PARTICLE_TERM(type))->type == 18483 XML_SCHEMA_TYPE_ALL)) 18484 { 18485 /* 18486 * SPEC cos-all-limited (1) 18487 */ 18488 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18489 /* TODO: error code */ 18490 XML_SCHEMAP_COS_ALL_LIMITED, 18491 WXS_ITEM_NODE(type), NULL, 18492 "The type has an 'all' model group in its " 18493 "{content type} and thus cannot be derived from " 18494 "a non-empty type, since this would produce a " 18495 "'sequence' model group containing the 'all' " 18496 "model group; 'all' model groups are not " 18497 "allowed to appear inside other model groups", 18498 NULL, NULL); 18499 18500 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) && 18501 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) && 18502 ((WXS_TYPE_PARTICLE_TERM(baseType))->type == 18503 XML_SCHEMA_TYPE_ALL)) 18504 { 18505 /* 18506 * SPEC cos-all-limited (1) 18507 */ 18508 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18509 /* TODO: error code */ 18510 XML_SCHEMAP_COS_ALL_LIMITED, 18511 WXS_ITEM_NODE(type), NULL, 18512 "A type cannot be derived by extension from a type " 18513 "which has an 'all' model group in its " 18514 "{content type}, since this would produce a " 18515 "'sequence' model group containing the 'all' " 18516 "model group; 'all' model groups are not " 18517 "allowed to appear inside other model groups", 18518 NULL, NULL); 18519 18520 } else if (! dummySequence) { 18521 xmlSchemaTreeItemPtr effectiveContent = 18522 (xmlSchemaTreeItemPtr) type->subtypes; 18523 /* 18524 * Create the particle. 18525 */ 18526 particle = xmlSchemaAddParticle(pctxt, 18527 type->node, 1, 1); 18528 if (particle == NULL) 18529 goto exit_failure; 18530 /* 18531 * Create the "sequence" model group. 18532 */ 18533 particle->children = (xmlSchemaTreeItemPtr) 18534 xmlSchemaAddModelGroup(pctxt, pctxt->schema, 18535 XML_SCHEMA_TYPE_SEQUENCE, type->node); 18536 if (particle->children == NULL) 18537 goto exit_failure; 18538 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle; 18539 /* 18540 * SPEC "the particle of the {content type} of 18541 * the ... base ..." 18542 * Create a duplicate of the base type's particle 18543 * and assign its "term" to it. 18544 */ 18545 particle->children->children = 18546 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt, 18547 type->node, 18548 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs, 18549 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs); 18550 if (particle->children->children == NULL) 18551 goto exit_failure; 18552 particle = (xmlSchemaParticlePtr) 18553 particle->children->children; 18554 particle->children = 18555 ((xmlSchemaParticlePtr) baseType->subtypes)->children; 18556 /* 18557 * SPEC "followed by the `effective content`." 18558 */ 18559 particle->next = effectiveContent; 18560 /* 18561 * This all will result in: 18562 * new-particle 18563 * --> new-sequence( 18564 * new-particle 18565 * --> base-model, 18566 * this-particle 18567 * --> this-model 18568 * ) 18569 */ 18570 } else { 18571 /* 18572 * This is the case when there is already an empty 18573 * <sequence> with minOccurs==maxOccurs==1. 18574 * Just add the base types's content type. 18575 * NOTE that, although we miss to add an intermediate 18576 * <sequence>, this should produce no difference to 18577 * neither the regex compilation of the content model, 18578 * nor to the complex type contraints. 18579 */ 18580 particle->children->children = 18581 (xmlSchemaTreeItemPtr) baseType->subtypes; 18582 } 18583 } 18584 } 18585 } 18586 /* 18587 * Now fixup attribute uses: 18588 * - expand attr. group references 18589 * - intersect attribute wildcards 18590 * - inherit attribute uses of the base type 18591 * - inherit or union attr. wildcards if extending 18592 * - apply attr. use prohibitions if restricting 18593 */ 18594 res = xmlSchemaFixupTypeAttributeUses(pctxt, type); 18595 HFAILURE HERROR 18596 /* 18597 * Apply the complex type component constraints; this will not 18598 * check attributes, since this is done in 18599 * xmlSchemaFixupTypeAttributeUses(). 18600 */ 18601 res = xmlSchemaCheckCTComponent(pctxt, type); 18602 HFAILURE HERROR 18603 18604 #ifdef DEBUG_TYPE 18605 xmlSchemaDebugFixedType(pctxt, type); 18606 #endif 18607 if (olderrs != pctxt->nberrors) 18608 return(pctxt->err); 18609 else 18610 return(0); 18611 18612 exit_error: 18613 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18614 #ifdef DEBUG_TYPE 18615 xmlSchemaDebugFixedType(pctxt, type); 18616 #endif 18617 return(pctxt->err); 18618 18619 exit_failure: 18620 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID; 18621 #ifdef DEBUG_TYPE 18622 xmlSchemaDebugFixedType(pctxt, type); 18623 #endif 18624 return(-1); 18625 } 18626 18627 18628 /** 18629 * xmlSchemaTypeFixup: 18630 * @typeDecl: the schema type definition 18631 * @ctxt: the schema parser context 18632 * 18633 * Fixes the content model of the type. 18634 * URGENT TODO: We need an int result! 18635 */ 18636 static int 18637 xmlSchemaTypeFixup(xmlSchemaTypePtr type, 18638 xmlSchemaAbstractCtxtPtr actxt) 18639 { 18640 if (type == NULL) 18641 return(0); 18642 if (actxt->type != XML_SCHEMA_CTXT_PARSER) { 18643 AERROR_INT("xmlSchemaTypeFixup", 18644 "this function needs a parser context"); 18645 return(-1); 18646 } 18647 if (! WXS_IS_TYPE_NOT_FIXED(type)) 18648 return(0); 18649 if (type->type == XML_SCHEMA_TYPE_COMPLEX) 18650 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type)); 18651 else if (type->type == XML_SCHEMA_TYPE_SIMPLE) 18652 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type)); 18653 return(0); 18654 } 18655 18656 /** 18657 * xmlSchemaCheckFacet: 18658 * @facet: the facet 18659 * @typeDecl: the schema type definition 18660 * @pctxt: the schema parser context or NULL 18661 * @name: the optional name of the type 18662 * 18663 * Checks and computes the values of facets. 18664 * 18665 * Returns 0 if valid, a positive error code if not valid and 18666 * -1 in case of an internal or API error. 18667 */ 18668 int 18669 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, 18670 xmlSchemaTypePtr typeDecl, 18671 xmlSchemaParserCtxtPtr pctxt, 18672 const xmlChar * name ATTRIBUTE_UNUSED) 18673 { 18674 int ret = 0, ctxtGiven; 18675 18676 if ((facet == NULL) || (typeDecl == NULL)) 18677 return(-1); 18678 /* 18679 * TODO: will the parser context be given if used from 18680 * the relaxNG module? 18681 */ 18682 if (pctxt == NULL) 18683 ctxtGiven = 0; 18684 else 18685 ctxtGiven = 1; 18686 18687 switch (facet->type) { 18688 case XML_SCHEMA_FACET_MININCLUSIVE: 18689 case XML_SCHEMA_FACET_MINEXCLUSIVE: 18690 case XML_SCHEMA_FACET_MAXINCLUSIVE: 18691 case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18692 case XML_SCHEMA_FACET_ENUMERATION: { 18693 /* 18694 * Okay we need to validate the value 18695 * at that point. 18696 */ 18697 xmlSchemaTypePtr base; 18698 18699 /* 4.3.5.5 Constraints on enumeration Schema Components 18700 * Schema Component Constraint: enumeration valid restriction 18701 * It is an `error` if any member of {value} is not in the 18702 * `value space` of {base type definition}. 18703 * 18704 * minInclusive, maxInclusive, minExclusive, maxExclusive: 18705 * The value `must` be in the 18706 * `value space` of the `base type`. 18707 */ 18708 /* 18709 * This function is intended to deliver a compiled value 18710 * on the facet. In this implementation of XML Schemata the 18711 * type holding a facet, won't be a built-in type. 18712 * Thus to ensure that other API 18713 * calls (relaxng) do work, if the given type is a built-in 18714 * type, we will assume that the given built-in type *is 18715 * already* the base type. 18716 */ 18717 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) { 18718 base = typeDecl->baseType; 18719 if (base == NULL) { 18720 PERROR_INT("xmlSchemaCheckFacet", 18721 "a type user derived type has no base type"); 18722 return (-1); 18723 } 18724 } else 18725 base = typeDecl; 18726 18727 if (! ctxtGiven) { 18728 /* 18729 * A context is needed if called from RelaxNG. 18730 */ 18731 pctxt = xmlSchemaNewParserCtxt("*"); 18732 if (pctxt == NULL) 18733 return (-1); 18734 } 18735 /* 18736 * NOTE: This call does not check the content nodes, 18737 * since they are not available: 18738 * facet->node is just the node holding the facet 18739 * definition, *not* the attribute holding the *value* 18740 * of the facet. 18741 */ 18742 ret = xmlSchemaVCheckCVCSimpleType( 18743 ACTXT_CAST pctxt, facet->node, base, 18744 facet->value, &(facet->val), 1, 1, 0); 18745 if (ret != 0) { 18746 if (ret < 0) { 18747 /* No error message for RelaxNG. */ 18748 if (ctxtGiven) { 18749 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18750 XML_SCHEMAP_INTERNAL, facet->node, NULL, 18751 "Internal error: xmlSchemaCheckFacet, " 18752 "failed to validate the value '%s' of the " 18753 "facet '%s' against the base type", 18754 facet->value, xmlSchemaFacetTypeToString(facet->type)); 18755 } 18756 goto internal_error; 18757 } 18758 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18759 /* No error message for RelaxNG. */ 18760 if (ctxtGiven) { 18761 xmlChar *str = NULL; 18762 18763 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18764 ret, facet->node, WXS_BASIC_CAST facet, 18765 "The value '%s' of the facet does not validate " 18766 "against the base type '%s'", 18767 facet->value, 18768 xmlSchemaFormatQName(&str, 18769 base->targetNamespace, base->name)); 18770 FREE_AND_NULL(str); 18771 } 18772 goto exit; 18773 } else if (facet->val == NULL) { 18774 if (ctxtGiven) { 18775 PERROR_INT("xmlSchemaCheckFacet", 18776 "value was not computed"); 18777 } 18778 TODO 18779 } 18780 break; 18781 } 18782 case XML_SCHEMA_FACET_PATTERN: 18783 facet->regexp = xmlRegexpCompile(facet->value); 18784 if (facet->regexp == NULL) { 18785 ret = XML_SCHEMAP_REGEXP_INVALID; 18786 /* No error message for RelaxNG. */ 18787 if (ctxtGiven) { 18788 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18789 ret, facet->node, WXS_BASIC_CAST typeDecl, 18790 "The value '%s' of the facet 'pattern' is not a " 18791 "valid regular expression", 18792 facet->value, NULL); 18793 } 18794 } 18795 break; 18796 case XML_SCHEMA_FACET_TOTALDIGITS: 18797 case XML_SCHEMA_FACET_FRACTIONDIGITS: 18798 case XML_SCHEMA_FACET_LENGTH: 18799 case XML_SCHEMA_FACET_MAXLENGTH: 18800 case XML_SCHEMA_FACET_MINLENGTH: 18801 18802 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) { 18803 ret = xmlSchemaValidatePredefinedType( 18804 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER), 18805 facet->value, &(facet->val)); 18806 } else { 18807 ret = xmlSchemaValidatePredefinedType( 18808 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER), 18809 facet->value, &(facet->val)); 18810 } 18811 if (ret != 0) { 18812 if (ret < 0) { 18813 /* No error message for RelaxNG. */ 18814 if (ctxtGiven) { 18815 PERROR_INT("xmlSchemaCheckFacet", 18816 "validating facet value"); 18817 } 18818 goto internal_error; 18819 } 18820 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18821 /* No error message for RelaxNG. */ 18822 if (ctxtGiven) { 18823 /* error code */ 18824 xmlSchemaCustomErr4(ACTXT_CAST pctxt, 18825 ret, facet->node, WXS_BASIC_CAST typeDecl, 18826 "The value '%s' of the facet '%s' is not a valid '%s'", 18827 facet->value, 18828 xmlSchemaFacetTypeToString(facet->type), 18829 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ? 18830 BAD_CAST "nonNegativeInteger" : 18831 BAD_CAST "positiveInteger", 18832 NULL); 18833 } 18834 } 18835 break; 18836 18837 case XML_SCHEMA_FACET_WHITESPACE:{ 18838 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) { 18839 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; 18840 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) { 18841 facet->whitespace = XML_SCHEMAS_FACET_REPLACE; 18842 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) { 18843 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; 18844 } else { 18845 ret = XML_SCHEMAP_INVALID_FACET_VALUE; 18846 /* No error message for RelaxNG. */ 18847 if (ctxtGiven) { 18848 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */ 18849 xmlSchemaCustomErr(ACTXT_CAST pctxt, 18850 ret, facet->node, WXS_BASIC_CAST typeDecl, 18851 "The value '%s' of the facet 'whitespace' is not " 18852 "valid", facet->value, NULL); 18853 } 18854 } 18855 } 18856 default: 18857 break; 18858 } 18859 exit: 18860 if ((! ctxtGiven) && (pctxt != NULL)) 18861 xmlSchemaFreeParserCtxt(pctxt); 18862 return (ret); 18863 internal_error: 18864 if ((! ctxtGiven) && (pctxt != NULL)) 18865 xmlSchemaFreeParserCtxt(pctxt); 18866 return (-1); 18867 } 18868 18869 /** 18870 * xmlSchemaCheckFacetValues: 18871 * @typeDecl: the schema type definition 18872 * @ctxt: the schema parser context 18873 * 18874 * Checks the default values types, especially for facets 18875 */ 18876 static int 18877 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl, 18878 xmlSchemaParserCtxtPtr pctxt) 18879 { 18880 int res, olderrs = pctxt->nberrors; 18881 const xmlChar *name = typeDecl->name; 18882 /* 18883 * NOTE: It is intended to use the facets list, instead 18884 * of facetSet. 18885 */ 18886 if (typeDecl->facets != NULL) { 18887 xmlSchemaFacetPtr facet = typeDecl->facets; 18888 18889 /* 18890 * Temporarily assign the "schema" to the validation context 18891 * of the parser context. This is needed for NOTATION validation. 18892 */ 18893 if (pctxt->vctxt == NULL) { 18894 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1) 18895 return(-1); 18896 } 18897 pctxt->vctxt->schema = pctxt->schema; 18898 while (facet != NULL) { 18899 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name); 18900 HFAILURE 18901 facet = facet->next; 18902 } 18903 pctxt->vctxt->schema = NULL; 18904 } 18905 if (olderrs != pctxt->nberrors) 18906 return(pctxt->err); 18907 return(0); 18908 exit_failure: 18909 return(-1); 18910 } 18911 18912 /** 18913 * xmlSchemaGetCircModelGrDefRef: 18914 * @ctxtMGroup: the searched model group 18915 * @selfMGroup: the second searched model group 18916 * @particle: the first particle 18917 * 18918 * This one is intended to be used by 18919 * xmlSchemaCheckGroupDefCircular only. 18920 * 18921 * Returns the particle with the circular model group definition reference, 18922 * otherwise NULL. 18923 */ 18924 static xmlSchemaTreeItemPtr 18925 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef, 18926 xmlSchemaTreeItemPtr particle) 18927 { 18928 xmlSchemaTreeItemPtr circ = NULL; 18929 xmlSchemaTreeItemPtr term; 18930 xmlSchemaModelGroupDefPtr gdef; 18931 18932 for (; particle != NULL; particle = particle->next) { 18933 term = particle->children; 18934 if (term == NULL) 18935 continue; 18936 switch (term->type) { 18937 case XML_SCHEMA_TYPE_GROUP: 18938 gdef = (xmlSchemaModelGroupDefPtr) term; 18939 if (gdef == groupDef) 18940 return (particle); 18941 /* 18942 * Mark this model group definition to avoid infinite 18943 * recursion on circular references not yet examined. 18944 */ 18945 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED) 18946 continue; 18947 if (gdef->children != NULL) { 18948 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18949 circ = xmlSchemaGetCircModelGrDefRef(groupDef, 18950 gdef->children->children); 18951 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED; 18952 if (circ != NULL) 18953 return (circ); 18954 } 18955 break; 18956 case XML_SCHEMA_TYPE_SEQUENCE: 18957 case XML_SCHEMA_TYPE_CHOICE: 18958 case XML_SCHEMA_TYPE_ALL: 18959 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children); 18960 if (circ != NULL) 18961 return (circ); 18962 break; 18963 default: 18964 break; 18965 } 18966 } 18967 return (NULL); 18968 } 18969 18970 /** 18971 * xmlSchemaCheckGroupDefCircular: 18972 * @item: the model group definition 18973 * @ctxt: the parser context 18974 * @name: the name 18975 * 18976 * Checks for circular references to model group definitions. 18977 */ 18978 static void 18979 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item, 18980 xmlSchemaParserCtxtPtr ctxt) 18981 { 18982 /* 18983 * Schema Component Constraint: Model Group Correct 18984 * 2 Circular groups are disallowed. That is, within the {particles} 18985 * of a group there must not be at any depth a particle whose {term} 18986 * is the group itself. 18987 */ 18988 if ((item == NULL) || 18989 (item->type != XML_SCHEMA_TYPE_GROUP) || 18990 (item->children == NULL)) 18991 return; 18992 { 18993 xmlSchemaTreeItemPtr circ; 18994 18995 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children); 18996 if (circ != NULL) { 18997 xmlChar *str = NULL; 18998 /* 18999 * TODO: The error report is not adequate: this constraint 19000 * is defined for model groups but not definitions, but since 19001 * there cannot be any circular model groups without a model group 19002 * definition (if not using a construction API), we check those 19003 * defintions only. 19004 */ 19005 xmlSchemaPCustomErr(ctxt, 19006 XML_SCHEMAP_MG_PROPS_CORRECT_2, 19007 NULL, WXS_ITEM_NODE(circ), 19008 "Circular reference to the model group definition '%s' " 19009 "defined", xmlSchemaFormatQName(&str, 19010 item->targetNamespace, item->name)); 19011 FREE_AND_NULL(str) 19012 /* 19013 * NOTE: We will cut the reference to avoid further 19014 * confusion of the processor. This is a fatal error. 19015 */ 19016 circ->children = NULL; 19017 } 19018 } 19019 } 19020 19021 /** 19022 * xmlSchemaModelGroupToModelGroupDefFixup: 19023 * @ctxt: the parser context 19024 * @mg: the model group 19025 * 19026 * Assigns the model group of model group definitions to the "term" 19027 * of the referencing particle. 19028 * In xmlSchemaResolveModelGroupParticleReferences the model group 19029 * definitions were assigned to the "term", since needed for the 19030 * circularity check. 19031 * 19032 * Schema Component Constraint: 19033 * All Group Limited (cos-all-limited) (1.2) 19034 */ 19035 static void 19036 xmlSchemaModelGroupToModelGroupDefFixup( 19037 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED, 19038 xmlSchemaModelGroupPtr mg) 19039 { 19040 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg); 19041 19042 while (particle != NULL) { 19043 if ((WXS_PARTICLE_TERM(particle) == NULL) || 19044 ((WXS_PARTICLE_TERM(particle))->type != 19045 XML_SCHEMA_TYPE_GROUP)) 19046 { 19047 particle = WXS_PTC_CAST particle->next; 19048 continue; 19049 } 19050 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) { 19051 /* 19052 * TODO: Remove the particle. 19053 */ 19054 WXS_PARTICLE_TERM(particle) = NULL; 19055 particle = WXS_PTC_CAST particle->next; 19056 continue; 19057 } 19058 /* 19059 * Assign the model group to the {term} of the particle. 19060 */ 19061 WXS_PARTICLE_TERM(particle) = 19062 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)); 19063 19064 particle = WXS_PTC_CAST particle->next; 19065 } 19066 } 19067 19068 /** 19069 * xmlSchemaCheckAttrGroupCircularRecur: 19070 * @ctxtGr: the searched attribute group 19071 * @attr: the current attribute list to be processed 19072 * 19073 * This one is intended to be used by 19074 * xmlSchemaCheckAttrGroupCircular only. 19075 * 19076 * Returns the circular attribute grou reference, otherwise NULL. 19077 */ 19078 static xmlSchemaQNameRefPtr 19079 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr, 19080 xmlSchemaItemListPtr list) 19081 { 19082